2

使用 Delphi 10.2、SQLite 和 Teecharts。我的 SQLite 数据库有两个字段,使用以下命令创建:

CREATE TABLE HistoryRuntime ('DayTime' DateTime, Device1 INTEGER DEFAULT (0));

我使用带有以下 SQL的TFDQuery调用来访问表:qryGrpahRuntime

SELECT DayTime AS TheDate, Sum(Device1) As DeviceTotal
FROM HistoryRuntime 
WHERE  (DayTime >= "2017-06-01") and (DayTime <= "2017-06-26") 
Group by Date(DayTime)

使用 Delphi IDE 中的字段编辑器,我可以添加两个持久字段,分别为TheDateaTDateTimeField和.DeviceTotalTLargeIntField

我在程序中运行此查询以创建我在设计时创建的 TeeChart。只要查询返回一些记录,这一切都有效。但是,如果没有请求日期的记录,我会收到一条EDatabaseError异常消息:

qryGrpahRuntime:字段“DeviceTotal”的类型不匹配,预期:LargeInt 实际:Widestring

我已经在网上搜索了大量关于如何防止在空查询中出现此错误的解决方案,但我发现的任何东西都没有运气。据我所知,当没有数据返回时,SQLite 默认为宽字符串字段。我曾尝试在查询中使用 CAST,但似乎没有任何区别。

如果我删除持久字段,则查询将在空返回集上毫无问题地打开。但是,为了在 IDE 中使用 TeeChart 编辑器,看来我需要持久字段。

有没有办法可以使用持久字段进行这项工作,或者我是否必须丢弃持久字段,然后在运行时添加 TeeChart 系列?

4

1 回答 1

7

FireDAC 的 SQLite 手册的调整 FireDAC 映射章节中描述了这种行为:

对于 SELECT 列表中的表达式,SQLite 避免了类型名称信息。当结果集不为空时,FireDAC 使用第一条记录中的值数据类型。当为空时,FireDAC 将这些列描述为 dtWideString。要显式指定列数据类型,请附加::<type name>到列别名:

SELECT count(*) as "cnt::INT" FROM mytab

因此,以这种方式修改您的命令(我使用BIGINT,但您可以使用映射到 64 位有符号整数数据类型且不是自动递增的任何伪数据类型,这对应于您的持久TLargeIntField字段):

SELECT
   DayTime AS "TheDate",
   Sum(Device1) AS "DeviceTotal::BIGINT"
FROM
   HistoryRuntime 
WHERE
   DayTime BETWEEN {d 2017-06-01} AND {d 2017-06-26}
GROUP BY
   Date(DayTime)

PS 我通过使用BETWEEN运算符(它只评估一次列值)做了一个小的优化,并使用了日期常量的转义序列(实际上你用参数替换,我猜;所以只是为了好奇)。


此数据类型提示由FDSQLiteTypeName2ADDataType过程解析,该过程在其AColName参数中采用并解析格式为<column name>::<type name>的列名。

于 2017-07-17T00:09:20.333 回答