Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   SQLLite mit INTEGER für DATETIME (https://www.delphipraxis.net/181792-sqllite-mit-integer-fuer-datetime.html)

wschrabi 9. Sep 2014 12:06

Datenbank: SQLLite • Version: letzte • Zugriff über: FireMonkey

SQLLite mit INTEGER für DATETIME
 
Hallo,
ich knoble jetzt schon den ganzen Tag.
Ich möchte ineinem SQLite Feld das Messdatum als INTEGER (= UNIX TIME STAMP) speichern.
Doch in dem ListView soll es HUMAN READABLE Sein. Also hab ich mir gedacht, mit OnCalcFields arbeiten.
Doch es klappt einfach nicht.
Was mache ich da falsch? Es soll unter XE6 auf Android laufen.
Delphi-Quellcode:
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf,
  FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async,
  FireDAC.Phys, FireDAC.Phys.SQLite, FireDAC.Stan.ExprFuncs,
  FireDAC.FMXUI.Login, FireDAC.Comp.UI, Data.DB, FireDAC.Comp.Client,
  FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt,
  FMX.ListView.Types, Data.Bind.EngExt, Fmx.Bind.DBEngExt, Data.Bind.Controls,
  System.Rtti, System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.Components,
  FMX.Layouts, Fmx.Bind.Navigator, Data.Bind.DBScope, FMX.ListView,
  FireDAC.Comp.DataSet, FMX.StdCtrls, FireDAC.FMXUI.Wait, System.IOUtils, DateUtils;

const
  cnFormat    = 'yyyy-mm-dd';
   
type
  TForm1 = class(TForm)
    FDConnection1: TFDConnection;
    FDGUIxLoginDialog1: TFDGUIxLoginDialog;
    FDQueryCreateTable: TFDQuery;
    ListView1: TListView;
    BindSourceDB1: TBindSourceDB;
    BindingsList1: TBindingsList;
    FDQuery1: TFDQuery;
    BindSourceDB2: TBindSourceDB;
    FDQuery2: TFDQuery;
    NavigatorBindSourceDB2: TBindNavigator;
    ButtonDelete: TButton;
    FDQueryIns: TFDQuery;
    ButtonAdd: TButton;
    FDGUIxWaitCursor1: TFDGUIxWaitCursor;
    FDQueryDel: TFDQuery;
    Label1: TLabel;
    LinkFillControlToFieldMessdatum: TLinkFillControlToField;
    FDQueryDrop: TFDQuery;
    Label2: TLabel;
    procedure ListView1ItemClick(const Sender: TObject;
      const AItem: TListViewItem);
    procedure ButtonAddClick(Sender: TObject);
    procedure FDConnection1BeforeConnect(Sender: TObject);
    procedure ButtonDeleteClick(Sender: TObject);
    procedure ButtonDropClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FDQuery2CalcFields(DataSet: TDataSet);
   
  private
    { Private-Deklarationen }
    FmtStngs: TFormatSettings;
   
   
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}


procedure TForm1.ButtonAddClick(Sender: TObject);
var
  TaskName: String;
begin
  try
    TaskName:=DateToStr(now()(*, FmtStngs*));
    if InputQuery('Bitte neues Meßdatum eingeben', 'Messdatum', TaskName) and (TaskName.Trim <> '') then
    begin
      ShowMessage('UNIX Timestamp:'+Inttostr(  DateTimeToUnix(StrToDateTime(TaskName))));
      //FDQueryIns.ParamByName('MessDatum').AsDate := StrToDate(TaskName(*, FmtStngs*));
      FDQueryIns.ParamByName('MessDatum').AsInteger := DateTimeToUnix(StrToDateTime(TaskName));
      FDQueryIns.ExecSQL();
      FDQuery2.Close;
      FDQuery2.Open;
      Label2.Text:= 'Total:' + IntTOStr(FDQuery2.RowsAffected);
     
      ButtonDelete.Visible := ListView1.Selected <> nil;
    end;
  except
    on e: Exception do
    begin
      ShowMessage(e.Message);
    end;
  end;
end;

procedure TForm1.ButtonDeleteClick(Sender: TObject);
var
  TaskName: String;
begin
  TaskName := ListView1.Selected.Text;

  try
    FDQueryDel.ParamByName('MessDatum').AsInteger := DateTimeToUnix(StrToDateTime(TaskName));
    FDQueryDel.ExecSQL();
    FDQuery2.Close;
    FDQuery2.Open;
    Label2.Text:= 'Total:' + IntTOStr(FDQuery2.RowsAffected);
    ButtonDelete.Visible := ListView1.Selected <> nil;
  except
    on e: Exception do
    begin
      SHowMessage(e.Message);
    end;
  end;
end;

procedure TForm1.ButtonDropClick(Sender: TObject);
begin
   FDQueryDrop.ExecSQL();
end;

procedure TForm1.FDConnection1BeforeConnect(Sender: TObject);
begin
  {$IF DEFINED(iOS) or DEFINED(ANDROID)}
  FDConnection1.Params.Values['Database'] :=
      TPath.Combine(TPath.GetDocumentsPath, 'lipoapp.s3db');
  {$ENDIF}
end;

procedure TForm1.FDQuery2CalcFields(DataSet: TDataSet);
begin
   DataSet.FieldByName('Messdatum').AsDateTime := UnixToDateTime(DataSet.FieldByName('Messdatum').AsInteger);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    FmtStngs:=TFormatsettings.Create;
    FmtStngs.DateSeparator := '.';
    FmtStngs.ShortDateFormat := 'yyyy.mm.dd';
    FmtStngs.TimeSeparator := ':';
    FmtStngs.LongTimeFormat := 'hh:mm:ss';
  //fSetting := GetCustomDateFormatSettings;
end;

procedure TForm1.ListView1ItemClick(const Sender: TObject;
  const AItem: TListViewItem);
begin
   ButtonDelete.Visible:=ListView1.Selected <> nil;
end;

end.

Der schöne Günther 9. Sep 2014 12:15

AW: SQLLite mit INTEGER für DATETIME
 
Ich kenne mich mit Datenbanken nicht aus, aber muss man das Feld dann nicht auch explizit als "berechnetes Feld" kennzeichnen?

Ansonsten warum als Integer-Feld? Nimm doch direkt ein Datumsfeldtyp. Was einen zur nächsten Frage bringt: Zugriff über was? FireMonkey oder VCL ist in dem Fall (glaube ich) völlig egal, gemeint ist eher "dbExpress", "FireDAC" oder anderes.

Klaus01 9. Sep 2014 12:17

AW: SQLLite mit INTEGER für DATETIME
 
Hallo,

was spricht dagegen den Unix-Timestamp erst beim befüllen des ListViews in
ein TDateTime Wert zu wandeln?

Grüße
Klaus

Sherlock 9. Sep 2014 12:23

AW: SQLLite mit INTEGER für DATETIME
 
@Günther: Hab ich auch erst gedacht, aber SQLite kennt sowas nicht www.sqlite.org/datatype3.html. Irrsinnig.
Augrund der Gegebenheiten würde ich dann aber eigentlich ein Text als Datentyp nehmen.

Sherlock

Der schöne Günther 9. Sep 2014 12:37

AW: SQLLite mit INTEGER für DATETIME
 
Das ist der Punkt den ich auch nicht ganz verstehe-

Ich habe eine sqLite-Datenbank mit "SQLite Expert" angelegt. Ein Feld habe ich als Typ "TIMESTAMP" deklariert. dbExpress erkennt da nur ein WIDEMEMO-Feld. FireDAC ist so schlau und macht da ein TSQLTimestampField draus. Der Theorie nach dürfte das ja gar nicht gehen.

jobo 9. Sep 2014 16:25

AW: SQLLite mit INTEGER für DATETIME
 
Reicht es nicht, bei der Abfrage eine Formatfunktion zu verwenden?
Code:
SELECT datetime(1092941466, 'unixepoch');
oder
Code:
SELECT datetime(1092941466, 'unixepoch', 'localtime');


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:51 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz