oracle数据类型15,我应该将哪种数据类型绑定为查询参数以与Oracle ODBC中的NUMBER(15)列一起使用?...

我正在使用ODBC 2从SQL Server移植到Oracle的C/C++应用程序.对于超过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

我注意到SQL_NUMERIC_STRUCT添加了ODBC 3.0并决定尝试一下.我很失望.

在我的情况下,这已经足够了,因为应用程序并不真正使用小数.但作为一般解决方案……简单地说,我不明白.我的意思是,我终于理解了应该如何使用它.我没有得到的是:为什么有人会引入这种新的结构然后让它以这种方式工作.

SQL_NUMERIC_STRUCT具有表示任何NUMERIC(或NUMBER或DECIMAL)值及其精度和比例所需的所有字段.只有它们不被使用.

在读取时,ODBC设置数字的精度(基于列的精度;除了Oracle返回更高的精度,例如对于NUMBER(15)为20).但是,如果您的列具有小数部分(比例> 0),则默认情况下将其截断.要以适当的比例读取数字,您需要在获取数据之前使用SQLSetDescField调用设置精度并自行调整.

在编写时,感谢Oracle尊重SQL_NUMERIC_STRUCT中包含的扩展.但ODBC规范并未强制要求它,MS SQL Server会忽略此值.所以,再次回到SQLSetDescField.

为什么ODBC没有完全使用自己的SQL_NUMERIC_STRUCT?我不知道.看起来它有效,但我认为这只是太多的工作.

我想我会使用SQL_C_CHAR.

最佳答案 我个人的偏好是使绑定变量字符串(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')

并提供字符串作为绑定变量.

这种方法有几个优点.

一个是解决与绑定其他数据类型遇到的问题和错误.

另一个优点是绑定值更容易在Oracle事件10046跟踪上进行解密.

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

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

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

根据过去的经验,这只是个人偏好.我使用与Perl DBD相同的方法.

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值