使用 Delphi 和 FireDAC 从数据库中读取 DateTime



我使用Delphi 10.3和FireDAC从SQLite数据库中读取日期时间失败了。 作为最简单的示例,我使用 sqlite 创建一个示例数据库,如下所示:

.open Test.db
CREATE TABLE "TABLE1" ("Name"VarChar(16), "Time" datetime); 
INSERT INTO Table1 (Name,Time) VALUES("Fred",time('now'));

然后

select * from Table1

如预期的那样给出弗雷德|16:52:57。

如果我生成一个Delphi程序,其中FDConnection1和FDQuery1链接到数据源和DBgrid,它将读取"Fred",但不会读取时间。FDquery1 asstring 返回的值为 '',asfloat 为 0。 如果我尝试使用FireDAC资源管理器工具来查看数据库,它也无法读取时间值,但我注意到它确实从一些示例数据库中读取了日期时间,因此它显然可以工作。

谁能告诉我我错过了什么。 谢谢

尝试在Delphi 代码中将 SQL 语句构造为字符串可能有点容易出错。 但是,您应该会发现以下代码正确执行

procedure TForm2.btnInsertRowClick(Sender: TObject);
const
sInsertRow = ' INSERT INTO Table1 (Name,time) VALUES(''Fred'',datetime(''now''))';
begin
FDConnection1.ExecSql(sInsertRow);
end;

顺便说一句,一般来说,使用参数化的 INSERT 语句比使用上面的文字语句更好,但在这里并不实用,因为您插入的是 Sqlite 返回的now值,而不是 Delphinow功能。

**更新: **下面的代码来自一个创建示例表的最小项目, 在其中插入一行,然后将其显示在数据库感知控件(DBGrid、DBEdit(中进行编辑。 这一切都完全按照应有的方式进行。 特别是,对行数据所做的任何更改通过 下次运行 THA 应用时,将保留这些控件。 请注意,创建表的 SQL 在"名称"列/字段上指定主键:这是 FDQuery1 生成将更改保存回磁盘表所需的 UPDATE 语句所必需的。

btnSelectClick处理程序中的代码演示如何设置time字段的 DisplayFormat 和 EditMask 属性,以便它仅显示存储的 DateTime 数据的时间部分。

type
TForm2 = class(TForm)
FDConnection1: TFDConnection;
FDQuery1: TFDQuery;
DBGrid1: TDBGrid;
DBNavigator1: TDBNavigator;
DataSource1: TDataSource;
DBEdit1: TDBEdit;
btnCreateTable: TButton;
btnInsertRow: TButton;
btnSelect: TButton;
[...]
public
[...]
const
sCreateTable = 'CREATE TABLE ''TABLE1'' (''Name'' VarChar(16) primary key, ''Time'' datetime)';
sInsertRow = ' INSERT INTO Table1 (Name,time) VALUES(''Fred'',datetime(''now''))';
sSelect = 'select * from table1';
procedure TForm2.btnCreateTableClick(Sender: TObject);
begin
FDConnection1.Connected := True;
FDConnection1.ExecSql(sCreateTable);
end;
procedure TForm2.btnInsertRowClick(Sender: TObject);
const
begin
FDConnection1.ExecSql(sInsertRow);
end;
procedure TForm2.btnSelectClick(Sender: TObject);
var
AField : TDateTimeField;
begin
FDQuery1.SQL.Text := sSelect;
FDQuery1.Open;
//   The following shows how to  control how the time field is formatted for display
//   in gui controls using the field's DisplayFormat
//   and how to set up its EditMask for editing
AField := FDQuery1.FieldByName('time') as TDateTimeField;
AField.DisplayFormat := 'hh:nn:ss';
AField.EditMask := '!90:00:00;1;_';
end;
end.

.DFM 文件

object Form2: TForm2
[...]
object FDConnection1: TFDConnection
Params.Strings = (
'Database=D:DelphiCodeFireDACdb1.sqlite'
'DriverID=SQLite')
LoginPrompt = False
end
object FDQuery1: TFDQuery
Connection = FDConnection1
end
object DataSource1: TDataSource
DataSet = FDQuery1
end
object DBGrid1: TDBGrid
DataSource = DataSource1
end
object DBNavigator1: TDBNavigator
DataSource = DataSource1
end
object DBEdit1: TDBEdit
DataField = 'Time'
DataSource = DataSource1
end
end

最新更新