我刚刚被SO问题中描述的问题所困扰绑定 int64 (SQL_BIGINT) 作为查询参数会导致在 Oracle 10g ODBC 中执行期间出错.
我正在使用 ODBC 2 将 C/C++ 应用程序从 SQL Server 移植到 Oracle。对于超过 NUMBER(9) 的数字字段,它使用 __int64 数据类型,该数据类型作为 SQL_C_SBIGINT 绑定到查询。显然 Oracle ODBC 不支持这种绑定。我现在必须在应用程序范围内转换为另一种方法。由于我没有太多时间——这是一个意想不到的问题——我宁愿使用经过验证的解决方案,而不是反复试验。
应该使用什么数据类型来绑定,例如Oracle 中的 NUMBER(15)?有记录的推荐解决方案吗?你用什么?有什么建议么?
我对不需要任何额外转换的解决方案特别感兴趣。我可以轻松地提供和使用 __int64 或 char* 形式的数字(正常非指数没有千位分隔符或小数点的形式)。任何其他格式都需要我进行额外的转换。
到目前为止我已经尝试过:
SQL_C_CHAR
看起来这对我有用。我担心数字格式的可变性。但在我的用例中,这似乎并不重要。显然只有小数点字符随系统语言设置而变化。
我不明白为什么应该在 SQL INSERT 或 UPDATE 命令中使用显式转换(例如 TO_NUMERIC)。当我将参数与 SQL_C_CHAR 作为 C 类型和 SQL_NUMERIC (具有适当的精度和小数位数)作为 SQL 类型绑定时,一切正常。我无法重现任何数据损坏效果。
SQL_NUMERIC_STRUCT
我注意到 ODBC 3.0 添加了 SQL_NUMERIC_STRUCT,并决定尝试一下。我很失望。
在我的情况下这就足够了,因为应用程序并不真正使用小数。但作为一个通用的解决方案......简单地说,我不明白。我的意思是,我终于明白了它应该如何使用。我不明白的是:为什么有人会引入这种新的结构,然后让它以这种方式工作.
SQL_NUMERIC_STRUCT 具有表示任何 NUMERIC(或 NUMBER 或 DECIMAL)值及其精度和小数位数所需的所有字段。只是它们没有被使用。
读取时,ODBC 设置数字的精度(基于列的精度;除了 Oracle 返回更大的精度,例如 NUMBER(15) 为 20)。但是,如果您的列有小数部分(比例> 0),则默认情况下它会被截断。要以适当的比例读取数字,您需要在获取数据之前使用 SQLSetDescField 调用设置精度并自行调整比例。
值得庆幸的是,在编写时,Oracle 尊重 SQL_NUMERIC_STRUCT 中包含的比例。但 ODBC 规范并未强制要求它,并且 MS SQL Server 会忽略该值。那么,再次回到 SQLSetDescField。
See 如何:使用 SQL_NUMERIC_STRUCT 检索数字数据 and INF:如何将 SQL_C_NUMERIC 数据类型与数字数据一起使用了解更多信息。
为什么 ODBC 不完全使用自己的 SQL_NUMERIC_STRUCT?我不知道。看起来确实有效,但我认为这工作量太大了。
我想我会使用 SQL_C_CHAR。