gpt4 book ai didi

c - 我应该将哪种数据类型绑定(bind)为查询参数以用于 Oracle ODBC 中的 NUMBER(15) 列?

转载 作者:太空狗 更新时间:2023-10-29 15:39:40 25 4
gpt4 key购买 nike

我刚刚被 SO 问题 Binding int64 (SQL_BIGINT) as query parameter causes error during execution in Oracle 10g ODBC 中描述的问题困扰.

我正在将使用 ODBC 2 的 C/C++ 应用程序从 SQL Server 移植到 Oracle。对于超过 NUMBER(9) 的数字字段,它使用绑定(bind)到查询的 __int64 数据类型作为 SQL_C_SBIGINT。显然,Oracle ODBC 不支持这种绑定(bind)。我现在必须在应用程序范围内转换为另一种方法。由于我没有太多时间---这是一个意外问题---我宁愿使用经过验证的解决方案,而不是反复试验。

应该使用什么数据类型来绑定(bind),例如Oracle 中的 NUMBER(15)? 是否有记录的推荐解决方案?你在用什么?有什么建议吗?

我对不需要任何额外转换的解决方案特别感兴趣。我可以轻松地提供和使用 __int64 或 char* 形式的数字(没有千位分隔符或小数点的正常 非指数 形式)。任何其他格式都需要我进行额外的转换。


到目前为止我尝试了什么:

SQL_C_CHAR

看起来它对我有用。我担心数字格式的可变性。但在我的用例中,这似乎并不重要。显然只有小数点字符随系统语言设置而改变。

而且我不明白为什么我应该在 SQL INSERT 或 UPDATE 命令中使用显式转换(例如 TO_NUMERIC)。当我将参数与 SQL_C_CHAR 绑定(bind)为 C 类型并将 SQL_NUMERIC(具有适当的精度和比例)作为 SQL 类型绑定(bind)时,一切正常。我无法重现任何数据损坏效果。

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。

参见 HOWTO: Retrieving Numeric Data with SQL_NUMERIC_STRUCTINF: How to Use SQL_C_NUMERIC Data Type with Numeric Data获取更多信息。

为什么 ODBC 没有完全使用它自己的 SQL_NUMERIC_STRUCT?我不知道。看起来可行,但我认为工作量太大。


我想我会使用 SQL_C_CHAR。

最佳答案

我个人的偏好是制作绑定(bind)变量字符串 (VARCHAR2),并让 Oracle 将字符转换为它自己的内部存储格式。很容易(在 C 中)以可接受的格式获取表示为空终止字符串的数据值。

因此,与其像这样编写 SQL:

SET MY_NUMBER_COL = :b1
, MY_DATE_COL = :b2

我这样写SQL:

SET MY_NUMBER_COL = TO_NUMBER( :b1 )
, MY_DATE_COL = TO_DATE( :b2 , 'YYYY-MM-DD HH24:MI:SS')

并提供字符串作为绑定(bind)变量。

这种方法有几个优点。

一个是解决绑定(bind)其他数据类型时遇到的问题和错误。

另一个优点是绑定(bind)值在 Oracle 事件 10046 跟踪上更容易破译。

此外,EXPLAIN PLAN(我相信)期望所有绑定(bind)变量都是 VARCHAR2,因此这意味着正在解释的语句与正在执行的实际语句略有不同(由于绑定(bind)参数的数据类型时的隐式数据转换在实际语句中不是 VARCHAR2。)

而且(不太重要)当我在 TOAD 中测试语句时,只需在输入框中键入字符串就更容易,而不必在下拉列表框中更改数据类型。

我还让 buitin TO_NUMBER 和 TO_DATE 函数验证数据。 (至少在 Oracle 的早期版本中,我遇到了直接绑定(bind) DATE 值的问题,它绕过了(至少部分)有效性检查,并允许将无效的日期值存储在数据库中。

这只是个人喜好,根据过去的经验。我对 Perl DBD 使用相同的方法。

我想知道 Tom Kyte (asktom.oracle.com) 对这个话题有什么看法?

关于c - 我应该将哪种数据类型绑定(bind)为查询参数以用于 Oracle ODBC 中的 NUMBER(15) 列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3258457/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com