将变体转换为双精度时出错 [ Delphi XE + IBObjects 4.9.12 ]
Posted
技术标签:
【中文标题】将变体转换为双精度时出错 [ Delphi XE + IBObjects 4.9.12 ]【英文标题】:Error converting variant into double [ Delphi XE + IBObjects 4.9.12 ] 【发布时间】:2011-06-14 11:13:32 【问题描述】:我的配置:
德尔福 XE 火鸟 2.1 IBObjects 4.9.12 Windows 7 64 位
当我尝试为 IBOQuery 参数设置值时出现异常(“无法将类型的变体 (UnicodeString) 转换为类型 (Double)”)。
异常是从 IB_Components.pas 中的 TIB_Column.SetAsVariant 过程引发的(第 42795 行)。要创建这种情况,只需尝试将字符串传递给日期参数:
myQuery.paramByName('mydate').AsString := DateToStr(IncDay(Now,5));
在过去的 25 天内,我试图解决这种情况,但在 IBO 支持列表中我没有得到任何答案。 有人有想法吗?
【问题讨论】:
您在数据库中的日期字段是什么类型的?假设,例如,它是一个Delphi TDateTime,那么转换为字符串是错误的。您应该只使用类似的内容:myQuery.paramByName('mydate').AsDateTime := IncDay(Now,5);
正确答案取决于数据库字段中使用的数据类型。
这是 VarCastError 在尝试进行错误转换时从 Variants 单元引发的消息;尝试使用“使用调试 DCU”构建应用程序,您会看到它是从 Variants.pas 提出的;我的猜测:如果 IBObjects 有一种为参数分配“数据类型”的方法,那么您的参数被定义为 DATE(TDateTime = Delphi 中的 Double,而 Double 是一种 Float)。在给定行号处向我们展示 IB_Components.pas 中的代码;
数据库字段为 DATE。正如我所说,在 Delphi 2007 中它运行良好......我没有在 Delphi 2009/2010 中尝试过,但我猜是 Unicode 问题。
那么,IBO 可能变得更聪明了。 Firebird 本身完全有能力将 STRING 转换为 DATE,而以前版本的 IBO 可能会原封不动地传递字符串。尽管如此,该错误实际上是一件好事,因为将 DATE 值作为 STRING 传递是一个非常糟糕的主意:Firebird 假定您的日期是两种可接受的格式之一,既固定又与 Windows 语言环境无关。 DateToStr() 会根据您的语言环境进行转换,因此如果您遇到日期格式设置为“DD.MM.YYYY”的用户,则双重转换将失败。
@Cosmin 感谢您的提示。从现在开始我会更加关注这一点。
【参考方案1】:
IBObjects 的架构正在(在执行时)将所有参数、字段等转换为字符串或变体。如果您的 'mydate' 参数是 'DateTime'(numeric) 类型,那么您必须使用 corespondent 类型值填充它。用字符串填充“数字”类型参数不是逻辑...
试试这个
myQuery.paramByName('mydate').AsDateTime:= Now+5; //和大卫的回答一样。
或
myQuery.paramByName('mydate').AsFloat:=Now+5; //或 IncDay(Now,5)
最好的问候, 拉度
【讨论】:
我猜这背后的数据库可能使用 Delphi 的TDateTime
以外的东西来保存日期。
从“STRING”转换为“STRING or VARIANT”应该永远不会失败。从 STRING 转换为 DateTime 可能会失败,尤其是当字符串是 DateToStr() 的结果时
Radu,谢谢您的回答。我试过这个并且工作正常,但问题是找到所有“ParamByName”并修复。在以前的 Delphi 版本中,它可以正常工作。
尝试使用 GExpert 的 Grep 搜索实用程序。或者使用 IDE 中的 Delphi 搜索功能(在文件中搜索)。
当然,Grep Search 是一个很棒的实用程序。但是,令人沮丧的是,一个多年来可以正常工作的功能突然不再工作了。以上是关于将变体转换为双精度时出错 [ Delphi XE + IBObjects 4.9.12 ]的主要内容,如果未能解决你的问题,请参考以下文章