使用Delphi 10.2,SQLite和Teecharts。我的SQLite数据库有两个字段,用:
创建CREATE TABLE HistoryRuntime ('DayTime' DateTime, Device1 INTEGER DEFAULT (0));
我使用名为TFDQuery
的{{1}}访问该表,其中包含以下SQL:
qryGrpahRuntime
使用Delphi IDE中的Field Editor,我可以添加两个持久字段,将SELECT DayTime AS TheDate, Sum(Device1) As DeviceTotal
FROM HistoryRuntime
WHERE (DayTime >= "2017-06-01") and (DayTime <= "2017-06-26")
Group by Date(DayTime)
作为TheDate
,将TDateTimeField
作为DeviceTotal
。
我在程序中运行此查询以创建我在设计时创建的TeeChart。只要查询返回一些记录,所有这些都有效。但是,如果请求的日期没有记录,我会收到TLargeIntField
个例外,其中包含以下消息:
qryGrpahRuntime:字段'DeviceTotal'的类型不匹配,期望:LargeInt actual:Widestring
我已经在网上搜索了大量关于如何在空查询中防止此错误的解决方案,但是我找不到任何好运。据我所知,当没有返回数据时,SQLite默认为宽字符串字段。我已经尝试在查询中使用CAST,它似乎没有任何区别。
如果删除持久字段,查询将在空返回集上打开而不会出现问题。但是,为了在IDE中使用TeeChart编辑器,我看来需要持久字段。
有没有办法让我可以使用持久字段,或者我是否必须抛弃持久字段然后在运行时添加TeeChart系列?
答案 0 :(得分:7)
在FireDAC的SQLite手册的Adjusting FireDAC Mapping章节中描述了这种行为:
对于SELECT列表中的表达式,SQLite避免使用类型名称 信息。当结果集不为空时,FireDAC将使用该值 来自第一条记录的数据类型。当为空时,FireDAC会描述这些内容 列为dtWideString。要显式指定列数据类型, 将
::<type name>
附加到列别名:
SELECT count(*) as "cnt::INT" FROM mytab
所以修改你的命令,例如这种方式(我使用 BIGINT ,但您可以使用映射到64位有符号整数数据类型的任何pseudo data type并且不会自动递增,这与您的持久性{{3}相对应} field):
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。我使用TLargeIntField运算符(仅对列值进行一次计算)进行了一次小优化,并使用BETWEEN作为日期常量(实际上,我用参数替换,我猜;所以只是为了好奇心)。
此数据类型提示由escape sequence过程解析,该过程在 AColName中以&lt; column name&gt; ::&lt; type name&gt; 格式获取和解析列名称参数。