TFDQuery 和 SQLite:字段类型不匹配,期望:LargeInt 实际:WideString

TFDQuery and SQLite: Type mismatch for field, expecting: LargeInt actual: WideString

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

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

我使用名为 qryGrpahRuntimeTFDQuery 访问 table,其中 SQL:

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 中的字段编辑器,我可以添加两个持久字段,将 TheDate 作为 TDateTimeField 并将 DeviceTotal 作为TLargeIntField.

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

qryGrpahRuntime: Type mismatch for field 'DeviceTotal', expecting: LargeInt actual: Widestring

我已经在网上搜索了很多关于如何防止空查询出现此错误的解决方案,但我没有找到任何运气。据我所知,当没有数据被 returned 时,SQLite 默认为宽字符串字段。我试过在查询中使用 CAST,它似乎没有任何区别。

如果我删除持久字段,查询将在空 return 集上打开而不会出现问题。但是,为了在 IDE 中使用 TeeChart 编辑器,我似乎需要持久字段。

有什么方法可以让我使用持久字段进行这项工作,还是我必须丢弃持久字段然后在 运行 时间添加 TeeChart 系列?

此行为在 FireDAC 的 SQLite 手册的 Adjusting FireDAC Mapping 章节中有所描述:

For an expression in a SELECT list, SQLite avoids type name information. When the result set is not empty, FireDAC uses the value data types from the first record. When empty, FireDAC describes those columns as dtWideString. To explicitly specify the column data type, append ::<type name> to the column alias:

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

所以修改你的命令,例如这样(我使用 BIGINT,但你可以使用任何 pseudo data type that maps to a 64-bit signed integer data type and is not auto incrementing, which corresponds to your persistent 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)

P.S。我通过对日期常量使用 BETWEEN operator (which evaluates the column value only once), and used an escape sequence 做了一个小的优化(我猜实际上你用参数替换了它;所以只是出于好奇)。


此数据类型提示由 FDSQLiteTypeName2ADDataType 过程解析,该过程在其 AColName 参数.