问题描述
我有一个 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)';
解决方法
对于 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