2016-03-29 30 views
1

kullanarak iki veri kümesinden sonra TWideStringField neden olur Delphi 10 Seattle kullanıyorum ve aşağıdaki örnek kodlar.Sayısal alan, SQLite'de 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. 

TClientDataSet Her iki örneği aynı alanlar yapıya sahip (Kod dize bir alandır, Tutar FMTBcd alandır).

Neden FDQuery1.FindField ('Amount') TWideStringField döndürür?

cevap

1

Sizin q, tutar alanınızın ilk sırada olduğunu varsayar, ancak Sqlite'in aslında nasıl çalıştığını sanmıyorum.

Sqlite sütunları kesinlikle yazılmamıştır ve FireDAC, diğer Sqlite sütunlarının gerçekten ne olduğunu söyler; diğer bir türden olması için sütunlar bildirseniz bile, WideStrings. Sqlite'de, belirli bir türdeki bir sütunun tanımlanması (f.i. otomatik artışlı tamsayı), o sütundaki verilerin nasıl depolandığından ziyade nasıl davrandığına dair bir sorudur.

Fwiw, FireDAC genel olarak Sqlite sütunlarının ve DBExpress'in yaptıklarının meta verilerinin anlamlandırılması konusunda daha iyi bir iş çıkarmış gibi görünmektedir, ancak yine de sorduğunuz gibi "eğlenceler" elde edersiniz.

SqlLite, FireDAC'a bir sütun türü adı verdiği takdirde, görünüşe göre (aşağıdaki yetkili bir sorktan aşağıya bakınız), FireDAC, sütunda oluşan ilk değerin gerçek veri türünü kullanmayı deneyecektir. Null ise, FireDAC, ftWideString sütun türü olarak kullanacaktır.

+0

Çoğunlukla doğru ama bir ekleme. SQLite, FireDAC'a UNION örneğinde olduğu gibi bir sütun tipi adı sağlıyorsa, FireDAC, gerçek veri türü sütun ilk değerini kullanmaya çalışacaktır. NULL ise, FireDAC sütunu ftWideString olarak tanımlar. –