在SQL中使用params时从字符串转换错误

时间:2012-10-25 14:38:19

标签: delphi delphi-2010 firebird

使用Delphi 2010(Firebird [测试],MS Sql Server,Oracle [生产])

以下是我的SQL

SELECT p.script_no, MIN(p.start_Time) as startTime, MAX(p.end_Time) as endTime, 
SUM(p.duration) as TotalDuration
FROM phase_times p
WHERE (p.script_no=:scriptNo) AND (Trunc(p.start_time) >= :beginDateRange) AND (Trunc(p.start_time) <= :endDateRange) 
GROUP BY p.script_no



ParamByName('beginDateRange').AsDate:= Date - 30;
ParamByName('endDateRange').AsDate:= Date;

我收到了“字符串转换错误 - 2012年10月25日”,我不知道为什么,因为我的datetime字段在数据库中的“10/25/2012 9:20:49 AM”格式

如果我将其更改为以下内容:ParamByName('beginDateRange')。AsString:= formatDateTime('mm / dd / yyyy',Date - 30).....我收到错误“来自字符串的转换错误 - 10/25/2012“

重新发现这个错误并没有为我提供新的途径,你有什么想法吗?

4 个答案:

答案 0 :(得分:5)

根据Interbase 6.0手册,嵌入式SQL指南,第7章,Firebird支持从YYYY-MM-DD和YYYY-MM-DD HH:MM:SS.qqq进行转换。我也相信它支持美国风格的速记日期(例如1-JAN-2012)进行转换。

可能存在一些支持区域设置的转换,但一般情况下:使用实际的日期/时间戳类型而不是字符串。

<强>更新 我最初没有在您的查询中发现TRUNC:它是转换错误的原因,因为此函数仅适用于数字,请参阅manual entry for TRUNC

鉴于你的评论(以及 ain 的回应),我假设你只对日期部分感兴趣,并且想要忽略时间。如果是这样,请将TRUNC的使用重写为:

CAST(<your-timestamp-field> AS DATE)

条件(Trunc(p.start_time) >= :beginDateRange) AND (Trunc(p.start_time) <= :endDateRange)为:

CAST(p.start_time AS DATE) BETWEEN :beginDateRange AND :endDateRange

答案 1 :(得分:2)

如果字符串是12小时格式,Firebird不支持从字符串到日期和时间值的转换。使用'dd.mm.yyyy hh:mm:ss'或'mm / dd / yyyy hh:mm:ss'格式。

答案 2 :(得分:0)

日期/时间转换的字符串通常使用用户的语言环境。 因此,如果您使用与您的语言环境的日期部分不匹配的字符串提供日期/时间转换功能,您将收到类似的错误。

同样指定日期/时间值,例如“10/25/2012”是依赖于区域设置的。因此,如果您在不同于US Locale(如Mine)的计算机上执行程序,则使用“10/25/2012”时可能会失败。

要独立于区域设置,我建议两个选项:

  • 使用StrToDateTime,指定TFormatSettings
  • 使用ISO 8601指定日期/时间字符串(但我不认为Delphi支持...)

像MS Sql,Excel等BTW程序接受ISO 8601中的日期。但你必须检查这个FB。

关于这个:

  

...因为我的日期时间字段位于数据库中的“10/25/2012 9:20:49 AM”格式...

日期/时间字段的内部存储因不同的数据库引擎而异。您在数据库管理软件中看到的内容(在您的情况下为“10/25/2012 9:20:49 AM”)是数据字段的字符串表示形式,通常根据您的用户区域设置(再次)格式化

答案 3 :(得分:0)

如果您从服务器Firebird 2.1下的Firebird 1.0连接数据库(例如),则需要在Firebird 2.1下进行备份和还原。