简体   繁体   中英

Reading DateTime from Database using Delphi and FireDAC

I'm failing dismally to read a datetime from an SQLite database using Delphi 10.3 and FireDAC. As the simplest example, I create a sample database using sqlite as follows:

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

Then

select * from Table1

gives Fred|16:52:57 as expected.

If I generate a Delphi program with an FDConnection1 and FDQuery1 linked to a datasource and DBgrid it will read "Fred" but not the time. The value returned by FDquery1 asstring is '' and asfloat is 0. If I try the FireDAC explorer tool to look at the database it also fails to read the time value but I notice it does read datetimes from some of the example databases so it clearly can work.

Can anyone tell me what I'm missing. Thanks

Trying to construct a SQL statement as a string in Delphi code can be a bit error prone. However, you should find that the following code executes correctly

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

Btw, in general it would be better to use a parameterised INSERT statement than a literal one like the above, but it's not really practical here as you are inserting the now value returned by Sqlite rather than the Delphi now function.

**Update: ** The code below is from a minimal project which creates your example table, inserts a row into it and then presents it in db-aware controls (DBGrid, DBEdit) for editing. It all works exactly as it ought to. In particular, any changes to the row data made through those controls are retained when tha app is next run. Note that the SQL which creates the table specifies a primary key on the Name column/field: this is necessary for the FDQuery1 to generate the UPDATE statements needed to save changes back to the on-disk table.

The code in the btnSelectClick handler shows how to set the time field's DisplayFormat and EditMask properties so that it only displays the time part of the stored DateTime data.

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 file

object Form2: TForm2
[...]
  object FDConnection1: TFDConnection
    Params.Strings = (
      'Database=D:\Delphi\Code\FireDAC\db1.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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM