使用“A Simple Delphi Wrapper for SQLite3”插入日期

时间:2013-03-01 18:22:20

标签: delphi sqlite delphi-2010

我正在使用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和eddBorn.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);

似乎什么都行不通!我没有例外,但我的领域永远不会得到一个数据值!

3 个答案:

答案 0 :(得分:3)

日期和时间数据类型

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

  • TEXT as ISO8601 strings(“YYYY-MM-DD HH:MM:SS.SSS”)。
  • 真实的朱利安日数,即公元前4714年11月24日格林威治中午以来的天数。根据预感格里高利历。
  • INTEGER as Unix Time,自1970-01-01 00:00:00 UTC以来的秒数。

在此处显示REAL和INTEGER部分。

修改过的SQLite3包装器Testfile: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;

输出:

enter image description here

问题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']);

答案 1 :(得分: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

答案 2 :(得分: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**

我留给你的是让事情变得更漂亮或更优雅。