从 sqlite 数据库读取日期时间的 Econverter 错误

问题描述

我有一个 sqlite 数据库,其中有一个表,其中一列是 DATETIME 类型。 DATETIME表中sqlite的格式为yyyy-mm-dd hh:nn:ss,pc中DATETIME的格式为mm/dd/yyyy hh:nn:ss ampm。当我将日期写入数据库时​​,它会自动转换为格式 yyyy-mm-dd hh:nn:ss。但是当我尝试从表中读取它时,我收到了 econverter 错误,表明 yyyy-mm-dd hh:nn:ss 不是正确的格式。我的 query 看起来像这样:

sqlQuery.sql.Text := 'SELECT MAX(Pradzia) FROM Pamainos';
sqlQuery.open();
ShiftPradzia := sqlQuery.Fields[0].AsDateTime; <-- I do get error here
sqlQuery.Close;

如果我像这样更改 Query,那么我不会收到任何错误

sqlQuery.sql.Text := 'SELECT Pradzia FROM Pamainos WHERE ID = :_ID';
sqlQuery.Params.ParamByName('_ID').Value := fShiftID;
sqlQuery.open();
ShiftPradzia := sqlQuery.Fields[0].AsDateTime;
sqlQuery.Close;

编辑: 确切的错误信息:

Project ProjectName.exe 引发异常类 EConverterError 消息“2020-12-19 13:34:24.743”不是有效的日期和时间。

编辑2: 也可以这样工作:

sqlQuery.sql.Text := 'SELECT Pradzia FROM Pamainos WHERE Pradzia = (SELECT MAX(Pradzia) FROM Pamainos)';

解决方法

来自Using SQLite with FireDAC

对于 SELECT 列表中的表达式,SQLite 避免使用类型名称 信息。当结果集不为空时,FireDAC 使用该值 来自第一条记录的数据类型。当为空时,FireDAC 描述那些 列作为 dtWideString。要显式指定列数据类型, 追加 :: 到列别名

因此:

sqlQuery.SQL.Text := 'SELECT MAX(Pradzia) as "MaxPradzia::datetime" FROM Pamainos';

您还必须确保 FDConnection.Params.Values['DateTimeFormat'] := 'string'; 这是默认设置。

,

SQLite 没有 DATETIME 数据类型 (Datatypes In SQLite Version 3)。
所有日期时间值都存储为 TEXT,对于 Unix 时间戳记为 INTEGER,对于儒略日存储为 REAL

我在另一个有类似问题的论坛中发现了这个:sqlite .AsDateTime error cannot access field as type DateTime,答案是:

如果您使用串联、聚合函数(MAX、AVG、...), 等,SQLite 返回此类字段的 Unknown 类型。对于正确 数据显示,应该使用DataTypeMapping。

不幸的是,答案提供的链接已损坏。

也许您可以尝试将查询返回的值显式转换为 TEXT

SELECT CAST(MAX(Pradzia) AS TEXT) FROM Pamainos