Меня только что укусила проблема, описанная в SO вопросе Привязка int64 (SQL_BIGINT), так как параметр запроса вызывает ошибку при выполнении в Oracle 10g ODBC .
Я портирую C /Приложение C ++, использующее ODBC 2 из SQL Server в Oracle.Для числовых полей, превышающих NUMBER (9), он использует тип данных __int64, который связан с запросами как SQL_C_SBIGINT.Очевидно, такое связывание не поддерживается Oracle ODBC.Теперь я должен преобразовать приложение в другой метод.Поскольку у меня не так много времени - это неожиданная проблема - я бы предпочел использовать проверенное решение, а не метод проб и ошибок.
Какой тип данных следует использовать для привязки, например, NUMBER (15) в Oracle? Есть ли документированное рекомендуемое решение?Что вы используете?Любые предложения?
Меня особенно интересуют решения, которые не требуют каких-либо дополнительных преобразований.Я могу легко предоставлять и потреблять числа в форме __int64 или char * (обычная неэкспоненциальная форма без разделителя тысяч или десятичной точки).Любой другой формат требует дополнительного преобразования с моей стороны.
То, что я пробовал до сих пор:
SQL_C_CHAR
Похоже, что это собираетсяработать на меня.Я был обеспокоен изменчивостью числового формата.Но в моем случае это не имеет значения.Видимо, только символ дробной части изменяется с настройками языка системы.
И я не понимаю, почему я должен использовать явное приведение (например, TO_NUMERIC) в команде SQL INSERT или UPDATE.Все работает нормально, когда я связываю параметр с SQL_C_CHAR как тип C и SQL_NUMERIC (с правильной точностью и масштабированием) как тип SQL.Я не смог воспроизвести эффект повреждения данных.
SQL_NUMERIC_STRUCT
Я заметил, что SQL_NUMERIC_STRUCT добавлен в ODBC 3.0, и решил попробовать.Я разочарован.
В моей ситуации этого достаточно, поскольку приложение на самом деле не использует дробные числа.Но как общее решение ... Просто я не понимаю.Я имею в виду, я наконец понял, как это должно быть использовано.Чего я не понимаю: , почему кто-то вводит новую структуру такого рода и затем заставляет ее работать таким образом .
SQL_NUMERIC_STRUCT имеет все необходимые поля для представления любого NUMERIC (или NUMBERили DECIMAL) значение с его точностью и масштабом.Только они не используются.
При чтении ODBC устанавливает точность числа (в зависимости от точности столбца; за исключением того, что Oracle возвращает большую точность, например, 20 для NUMBER (15)).Но если ваш столбец имеет дробную часть (масштаб> 0), он по умолчанию усекается.Чтобы прочитать число с правильным масштабом, вам нужно установить точность и масштабировать себя с помощью вызова SQLSetDescField перед извлечением данных.
При записи Oracle, к счастью, учитывает масштаб, содержащийся в SQL_NUMERIC_STRUCT.Но спецификация ODBC не требует этого, и MS SQL Server игнорирует это значение.Итак, снова вернемся к SQLSetDescField.
См. HOWTO: получение числовых данных с помощью SQL_NUMERIC_STRUCT и INF: как использовать тип данных SQL_C_NUMERIC с числовыми данными для получения дополнительной информации.
Почему ODBC не полностью использует свой собственный SQL_NUMERIC_STRUCT?Я не знаю.Похоже, что это работает, но я думаю, что это слишком много работы.
Я думаю, я буду использовать SQL_C_CHAR.