2016-03-29 1 views
1

Ich benutze Delphi 10 Seattle und unten ist Beispielcodes.Warum numerische Feld TWideStringField nach Union zwei Datensätze in SQLite mit TFDQuery

unit Unit1; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Data.DB, Datasnap.DBClient, 
    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.Phys.SQLiteDef, 
    FireDAC.Stan.ExprFuncs, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, 
    FireDAC.DApt, FireDAC.VCLUI.Wait, FireDAC.Comp.UI, FireDAC.Comp.Client, 
    FireDAC.Phys.SQLiteVDataSet, FireDAC.Comp.DataSet, Vcl.StdCtrls; 

type 
    TForm1 = class(TForm) 
    ClientDataSet1: TClientDataSet; 
    ClientDataSet2: TClientDataSet; 
    FDConnection1: TFDConnection; 
    FDQuery1: TFDQuery; 
    FDLocalSQL1: TFDLocalSQL; 
    FDPhysSQLiteDriverLink1: TFDPhysSQLiteDriverLink; 
    FDGUIxWaitCursor1: TFDGUIxWaitCursor; 
    Button1: TButton; 
    procedure Button1Click(Sender: TObject); 
    public 
    procedure AfterConstruction; override; 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.AfterConstruction; 
var o: TFDLocalSQLDataSet; 
begin 
    inherited; 
    ClientDataSet1.FieldDefs.Add('Code', ftString, 20); 
    ClientDataSet1.FieldDefs.Add('Amount', ftFMTBcd, 2); 
    ClientDataSet1.FieldDefs.Find('Amount').Precision := 18; 
    ClientDataSet1.CreateDataSet; 
    ClientDataSet1.AppendRecord(['A', 10]); 
    ClientDataSet1.AppendRecord(['B', 20]); 
    ClientDataSet1.AppendRecord(['C', 30]); 

    ClientDataSet2.FieldDefs.Add('Code', ftString, 20); 
    ClientDataSet2.FieldDefs.Add('Amount', ftFMTBcd, 2); 
    ClientDataSet2.FieldDefs.Find('Amount').Precision := 18; 
    ClientDataSet2.CreateDataSet; 
    ClientDataSet2.AppendRecord(['X', 10]); 
    ClientDataSet2.AppendRecord(['B', 20]); 
    ClientDataSet2.AppendRecord(['Y', 30]); 

    o := FDLocalSQL1.DataSets.Add; 
    o.DataSet := ClientDataSet1; 
    o := FDLocalSQL1.DataSets.Add; 
    o.DataSet := ClientDataSet2; 
    FDLocalSQL1.Active := True; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    if FDQuery1.Active then 
    FDQuery1.Close; 

    FDQuery1.Open(
    'SELECT * FROM ClientDataSet1 ' + 
    'UNION ' + 
    'SELECT * FROM ClientDataSet2' 
); 
    ShowMessage(FDQuery1.FindField('Amount').ClassName); 
end; 

end. 

Beide Instanz von TClientDataSet haben gleiche Felder Struktur (Code-String-Feld ist, Betrag ist FMTBcd Feld).

Warum gibt FDQuery1.FindField ('Amount') TWideStringField zurück?

Antwort

1

Ihr q setzt voraus, dass Ihr Betragsfeld an erster Stelle numerisch war, aber ich glaube nicht, dass Sqlite so funktioniert.

Sqlite-Spalten sind nicht streng typisiert, und FireDAC sagt Ihnen, was alle Sqlite-Spalten wirklich sind, nämlich WideStrings, selbst wenn Sie Spalten für einen anderen Typ deklarieren. In Sqlite ist das Definieren einer Spalte eines bestimmten Typs (z. B. automatisch inkrementierende ganze Zahl) eher eine Frage davon, wie sich Daten in dieser Spalte verhalten und nicht wie sie gespeichert werden.

Fwiw, FireDAC im Allgemeinen scheint einen besseren Job zu machen, um Sqlite-Spalten und ihre Metadaten sinnvoller zu machen als DBExpress, aber Sie bekommen immer noch "Funnies" wie die, nach denen Sie fragen.

Offensichtlich (siehe Kommentar unten von einer autoritativen Quelle), wenn SqlLite FireDAC einen Spaltentypnamen liefert, wird FireDAC versuchen, den tatsächlichen Datentyp des ersten Werts zu verwenden, der in der Spalte vorkommt. Wenn es Null ist, wird FireDAC ftWideString als Spaltentyp verwenden.

+0

Meistens korrekt, aber eine Addition. Wenn SQLite FireDAC wie im Fall von UNION einen Namen für den Spaltentyp zur Verfügung stellt, versucht FireDAC, den tatsächlichen Datentyp des ersten Wertes der Spalte zu verwenden. Wenn es NULL ist, definiert FireDAC die Spalte als ftWideString. –

Verwandte Themen