我有一个Delphi XE应用程序,它使用TClientDataSet
和TDataSetProvider
加上TADOQuery
来访问Oracle XE数据库。
我想写的表有一个NUMBER(19)
字段。
我正在写一个像这样的值:
myDataModule.myClientDataSet.FieldByName('ID').AsLargeInt := ID;
假设我有1234567890123456789
这样的ID,它会四舍五入为1234567890123460000
。
我该如何避免?
答案 0 :(得分:3)
确保将TClientDataSet
字段明确创建为ftLargeint
,否则您可能会遇到此类舍入问题。
忘记使用ADO访问Oracle。请注意,ADO连接的所有OleDB提供程序都有处理BLOB的错误:Microsoft的版本只是不处理它们,Oracle的版本将randomly return null for 1/4 of rows ...如果您的情况出现类似问题,我将不会感到惊讶字段。
您可以查看访问Oracle的其他方法,例如DBExpresss驱动程序甚至BDE。某些第三方组件也可用。
我们的免费direct access classes to Oracle原生处理此类数字字段,并将直接处理Int64值,而不进行TDataSet
转换(这也可能是问题的原因)。例如,我认为它是唯一一个实现最新11g功能的Delphi单元,名为“ 64位整数主机数据类型,用于OCI绑定和定义调用”。它不需要客户端驱动程序(也不需要BDE,也不需要Provider,也不需要本地配置):只需通过Delphi exe复制Oracle Instance Client dll即可直接连接到Oracle。结果speed is amazing。
答案 1 :(得分:1)
您是否在Delphi项目选项中设置了use debug .dcus
并从初始变量分配中逐步完成了将数据交给Oracle传输驱动程序的所有代码?您是否验证了何时将值四舍五入为15位?
以下是其他论坛中的一些帖子,其中非Delphi用户遇到了同样的问题,这是由使用to_char()
函数引起的。我想知道number(19)
(或BigInt
)值是否在您设置值和发布到数据库之间的某个位置转换为字符串。
答案 2 :(得分:0)
我决定抛弃TClientDataSet
和TDataSetProvider
并直接使用TADOQuery
插入值。
即。我现在有这样的事情:
myDataModule.myQuery.SQL.Clear;
myDataModule.myQuery.SQL.Add('INSERT INTO mytable (ID) VALUES(:ID)');
myDataModule.myQuery.Prepared := True;
myDataModule.myQuery.Parameters.ParamByName('ID').Value := 1234567890123456789;
myDataModule.myQuery.ExecSQL;
不是一个完美的解决方案,但它有效。