gpt4 book ai didi

sqlite - 为什么在 SQLite 中使用 TFDQuery 合并两个数据集后数字字段变成 TWideStringField

转载 作者:行者123 更新时间:2023-12-02 04:27:27 27 4
gpt4 key购买 nike

我使用的是 Delphi 10 Seattle,下面是示例代码。

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 的两个实例具有相同的字段结构(代码是字符串字段,金额是 FMTBcd 字段)。

为什么 FDQuery1.FindField('Amount') 返回 TWideStringField?

最佳答案

你的 q 预设你的 Amount 字段首先是数字,但我不认为这就是 Sqlite 的实际工作方式。

Sqlite 列不是严格类型化的,FireDAC 会告诉您所有 Sqlite 列的真正含义,即 WideString,即使您将列声明为其他类型也是如此。在 Sqlite 中,将列定义为特定类型(即自动递增整数)更多的是该列中的数据如何表现的问题,而不是如何存储的问题。

Fwiw,总的来说,FireDAC 在理解 Sqlite 列及其元数据方面似乎比 DBExpress 做得更好,但您仍然会得到像您所询问的那样的“有趣的东西”。

显然(请参阅下面权威来源的评论)如果 SqlLite 向 FireDAC 提供列类型名称,那么 FireDAC 将尝试使用列中出现的第一个值的实际数据类型。如果为 Null,FireDAC 将使用 ftWideString 作为列类型。

关于sqlite - 为什么在 SQLite 中使用 TFDQuery 合并两个数据集后数字字段变成 TWideStringField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36279979/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com