2

我正在使用 delphi 2010 和 Tim Anderson 的 SQLite3 包装器 - http://www.itwriting.com/blog/?page_id=659 - 但我无法插入日期

这是我的数据库创建

DB.ExecSql('CREATE TABLE Tags (No Integer NOT NULL, Title VarChar(25) NOT NULL, Creator VarChar(25) NULL, Born Date NULL, Charter Boolean Default False NULL, Owned Boolean Default False NULL, Image Blob NULL, CONSTRAINT PK_No PRIMARY KEY (No));');

哪个构建和工作正常。我用 SQLite 管理员测试了它 - http://sqliteadmin.orbmu2k.de/ 我什至可以使用管理员手动输入日期

这是我的插入

DB.ExecSql('Insert into Tags (No, Title, Creator, Born, Charter, Owned) ' +
             'values (' + quotedStr(frmTag.edtTagNo.Text) + ',' + quotedStr(frmTag.edtTitle.Text) + ',' +
                          quotedStr(frmTag.edtCreator.Text) + ',' + quotedStr(frmTag.edtBorn.Text) + ',' +
                          quotedStr(BoolToStr(frmTag.cbxCharter.Checked)) + ',' + quotedStr(BoolToStr(frmTag.cbxOwned.Checked)) + ');');

日期字段由 edtBorn 控件 (TRzDateEdit) 提供

我在插入之前检查了 edtBorn.Text 和 edtBorn.date 的值,并且日期始终正确。

我尝试插入以下方式:

frmTag.edtBorn.Text 
FormatDateTime('mm/dd/yyyy',frmTag.edtBorn.Text)
quotedStr(frmTag.edtBorn.Text)
quotedStr(FormatDateTime('mm/dd/yyyy',frmTag.edtBorn.Text))

我什至尝试过使用参数

 DB.AddParamText('@ABorn', frmTag.edtBorn.Text);
 DB.AddParamFloat('@ABorn', frmTag.edtBorn.Date);

似乎没有任何效果!我没有例外,但我的字段从未获得 dat 值!

4

3 回答 3

3

日期和时间数据类型

SQLite 能够将日期和时间存储为 TEXT、REAL 或 INTEGER 值:

  • TEXT 作为 ISO8601 字符串(“YYYY-MM-DD HH:MM:SS.SSS”)。
  • REAL 作为儒略日数字,根据预测的公历,自公元前 4714 年 11 月 24 日格林威治中午以来的天数。
  • INTEGER 作为 Unix 时间,自 1970-01-01 00:00:00 UTC 以来的秒数。

例如此处显示 REAL 和 INTEGER 部分。

修改后的 SQLite3 包装器测试文件:uTestSqlite

sSQL := 'CREATE TABLE testtable ([ID] INTEGER PRIMARY KEY,[OtherID] INTEGER NULL,';
sSQL := sSQL + '[Name] VARCHAR (255),[Number] FLOAT,[Date] INTEGER, [notes] BLOB,
       [picture] BLOB COLLATE NOCASE);';
sldb.execsql(sSQL);
sldb.execsql('CREATE INDEX TestTableName ON [testtable]([Name]);');

//begin a transaction
sldb.BeginTransaction;

sSQL := 'INSERT INTO testtable(Name,OtherID,Number,Date) VALUES ("Some Name", 4,
         julianday("now"), strftime("%s","now"));';
sldb.ExecSQL(sSQL);

sSQL := 'INSERT INTO testtable(Name,OtherID,Number,Date,Notes) VALUES ("Another Name",12,
         julianday("2013-03-01"),strftime("%s","2013-03-01"), "More notes");';
sldb.ExecSQL(sSQL);

//end the transaction
sldb.Commit;

[...]

//query the data
sltb := slDb.GetTable('SELECT * FROM testtable');
if sltb.Count > 0 then
begin
//display first row
updateFields;
end;

显示值:

procedure TForm1.updateFields;
var
Notes: string;
myDate :TDateTime;

begin
ebName.Text := sltb.FieldAsString(sltb.FieldIndex['Name']);
ebID.Text := inttostr(sltb.FieldAsInteger(sltb.FieldIndex['ID']));

if TryJulianDateToDateTime(sltb.FieldAsDouble(sltb.FieldIndex['Number']),myDate)
   then
   ebNumber.Text := DateTimeToStr(myDate)
   else
   ShowMessage('Not a valid Julian date');

myDate:=UnixToDateTime(sltb.FieldAsInteger(sltb.FieldIndex['Date']));
ebDate.Text := DateTimeToStr(myDate);

[...]
end;

输出:

在此处输入图像描述

在你的问题中DB.ExecSql('CREATE TABLE Tags (..., Born Date NULL,...);');

替换DB.ExecSql('Insert into Tags (....) VALUES (...

+ quotedStr(frmTag.edtBorn.Text) 

'strftime("%Y-%m-%d","'+frmTag.edtBorn.Text+'")'

的值frmTag.edtBorn.Text必须像1975-10-21

您可以通过以下方式获得它:

ebDate.Text := sltb.FieldAsString(sltb.FieldIndex['Born']);
于 2013-03-02T01:08:10.783 回答
1

我已经制作了自己的“非常轻巧”的 SQLite3 包装器,但使用 Variants 来决定是否使用哪种 sqlite3 内部类型:https ://github.com/stijnsanders/TSQLite

在那里,我发现“松散类型”sqlite3 在内部工作得非常好,我发现存储在 Variant 中的 Delphi 日期变成了 SQLite3 中的浮点值(顺便说一下,TDateTime 实际上是)。一个可能的缺点是从 SQL 操作日期值有点笨拙。我很遗憾看到您已经尝试过 AddParamFloat(和 FieldAsFloat),但这似乎不起作用。

所以我建议你将日期存储为一个字符串,如果是 sqlite 日期格式,则使用一个字符串,例如使用FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz',d). 在这里查看更多信息:http ://www.sqlite.org/lang_datefunc.html

于 2013-03-01T19:12:09.077 回答
0

我使用 Delphi 2010 和 Tim Anderson 的 SQLite3 包装器。
这是我用来创建和使用日期时间字段的内容。它相当直截了当,一直在为我工作。我相信您可以通过我为您编写一个演示程序来弄清楚下面说明的概念。

创建字段的 SQL:

  sSQL :=  'CREATE TABLE [someTable] (' +
            '  [somefield1] VARCHAR(12),' +
            '  [somefield2] VARCHAR(12),' +
            '  [myDateTime] DATETIME );';

填充字段的 SQL:

 sSQL := 'INSERT INTO someTable(somefield1, somefield2, myDateTime)' + 
         '  VALUES ( "baloney1", "baloney2","' + FloatToStr(Now) + '");';

从字段中检索数据的示例:

var
sDBFilePathString: string;
sl3tbl: TSqliteTable;
fsldb : TSQLiteDatabase;
FromdbDTField : TDateTime;

begin
   ...
   ... 
    fsldb := TSQLiteDatabase.Create(sDBFilePathString); 
    sl3tbl := fsldb.GetTable('SELECT * FROM someTable');
    FromdbDateTime := StrToFloat(sl3tbl.FieldAsString(sl3tbl.FieldIndex['myDateTime']));
    Showmessage('DT: ' + DateTimeToStr(FromdbDTField));
end;

结果:

 **DT: 10/10/2013 1:09:53 AM**

我把它留给你,让事情变得更漂亮或更优雅。

于 2013-10-10T08:23:01.337 回答