如何使用 FieldDefs 在运行时创建新的 SQLite 文件和 table?
How can I create a new SQLite file and table at runtime using FieldDefs?
我正在使用 Delphi Seattle 在全新的 SQLite 文件中创建一个全新的 table,并且仅使用 FieldDef 和非可视化代码。我可以使用 ExecSQL ('CREATE TABLE....' ) 语法创建一个 table 但不是如下所示(我得到 'No such table 'MyTable' 这是在我执行 CreateDataSet 调用时引发的).我想要一些允许我使用 FieldDefs 的解决方案。此代码以示例 here 为蓝本。不过我注意到,有关 CreateDataSet 的注释仅适用于 TFDMemTable。是否有一种运行时方法可以在不使用 ExecSQL 的情况下创建 SQLite table?
procedure Test;
const
MyDBFile = 'c:\scratch\hope.db';
var
Connection : TFDConnection;
DriverLink : TFDPhysSQLiteDriverLink;
Table : TFDTable;
begin
DeleteFile( MyDBFile );
DriverLink := TFDPhysSQLiteDriverLink.Create( nil );
Connection := TFDConnection.Create( nil );
try
Connection.Params.Values['DriverID'] := 'SQLite';
Connection.Params.Values['Database'] := MyDBFile;
Connection.Connected := True;
Table := TFDTable.Create( nil );
try
Table.TableName := 'MyTable';
Table.Connection := Connection;
Table.FieldDefs.Add( 'one', ftString, 20 );
Table.FieldDefs.Add( 'two', ftString, 20 );
Table.CreateDataSet;
// I would add records here....
finally
Table.Free;
end;
finally
Connection.Free;
DriverLink.Free;
end;
end;
CreateDataSet 通常是一个本地操作,用于将客户端数据集初始化为空状态。如果 TClientDataSet 是任何东西,afaik 它不能用于创建服务器端 table。
要创建一个实际的服务器 table,我希望必须构建 DDL SQL 来创建 table,然后使用 ExecSQL 执行它(客户端)数据集,正如您已经尝试过的那样。
更新
尽管使用了不显示 FieldDef 的 TFDTable 组件,以下内容似乎可以满足您在代码中完成所有操作的要求,因此我使用了代码创建的 TFields。在西雅图 D10 测试。
procedure TForm3.CreateDatabaseAndTable;
const
DBName = 'd:\delphi\code\sqlite\atest.sqlite';
var
AField : TField;
begin
if FileExists(DBName) then
DeleteFile(DBName);
AField := TLargeIntField.Create(Self);
AField.Name := 'IDField';
AField.FieldName := 'ID';
AField.DataSet := FDTable1;
AField := TWideStringField.Create(Self);
AField.Size := 80;
AField.Name := 'NameField';
AField.FieldName := 'Name';
AField.DataSet := FDTable1;
FDConnection1.Params.Values['database'] := DBName;
FDConnection1.Connected:= True;
FDTable1.TableName := 'MyTable';
FDTable1.CreateTable(False, [tpTable]);
FDTable1.Open();
FDTable1.InsertRecord([1, 'First']);
FDConnection1.Commit;
FDConnection1.Connected:= False;
end;
我希望比我更熟悉的人可以使用 TFDMemTable 的 FieldDefs 做类似的事情,如果它通过 FDTableAdaptor 正确连接到服务器端组件(FDCommand?)。
顺便说一句,我使用了 LargeInt ID 字段和 WideString Name 字段,因为前一段时间尝试将 Sqlite 与 D7 一起使用时,我在尝试使用整数和字符串字段时遇到了无穷无尽的麻烦。
顺便说一句,如果您在部署之前知道所需的结构,您可能会发现如果您只是将一个空数据库 + table 复制到位,您可能会获得更多 predictable/robust 结果,而不是而不是尝试在原位创建 table 。 Ymmv,当然。
我永远不会梦想使用 fielddef 创建数据库 table,因为您最终会得到 table,但没有适当的主键、索引和引用完整性。结果 table 完全是 "dumbed down".
只要您在查询中有 "where" 子句,数据库就会进行完整的 table 扫描以查找与查询匹配的记录。所以你的数据库随着大小的增加而变慢(并且 CPU 使用增加)。那只是糟糕的设计。
此致,
亚瑟
您可以使用应用程序 SQLite Expert Professional,创建 SQLite 数据库。
并使用 FDConnection 连接到数据库。并使用它。
数据库SQLite的方法,和MartynA说的一样。
Begin
FDConnection1.Connected:=false;
FDConnection1.Params.Clear;
FDConnection1.Params.Database:='D:\SQLiteDatabase.db';
FDConnection1.ConnectionDefName:='SQLite_Demo';
FDConnection1.DriverName:='SQLite';
FDConnection1.Connected:=true;
FDTable1.Open;
End;
我正在使用 Delphi Seattle 在全新的 SQLite 文件中创建一个全新的 table,并且仅使用 FieldDef 和非可视化代码。我可以使用 ExecSQL ('CREATE TABLE....' ) 语法创建一个 table 但不是如下所示(我得到 'No such table 'MyTable' 这是在我执行 CreateDataSet 调用时引发的).我想要一些允许我使用 FieldDefs 的解决方案。此代码以示例 here 为蓝本。不过我注意到,有关 CreateDataSet 的注释仅适用于 TFDMemTable。是否有一种运行时方法可以在不使用 ExecSQL 的情况下创建 SQLite table?
procedure Test;
const
MyDBFile = 'c:\scratch\hope.db';
var
Connection : TFDConnection;
DriverLink : TFDPhysSQLiteDriverLink;
Table : TFDTable;
begin
DeleteFile( MyDBFile );
DriverLink := TFDPhysSQLiteDriverLink.Create( nil );
Connection := TFDConnection.Create( nil );
try
Connection.Params.Values['DriverID'] := 'SQLite';
Connection.Params.Values['Database'] := MyDBFile;
Connection.Connected := True;
Table := TFDTable.Create( nil );
try
Table.TableName := 'MyTable';
Table.Connection := Connection;
Table.FieldDefs.Add( 'one', ftString, 20 );
Table.FieldDefs.Add( 'two', ftString, 20 );
Table.CreateDataSet;
// I would add records here....
finally
Table.Free;
end;
finally
Connection.Free;
DriverLink.Free;
end;
end;
CreateDataSet 通常是一个本地操作,用于将客户端数据集初始化为空状态。如果 TClientDataSet 是任何东西,afaik 它不能用于创建服务器端 table。
要创建一个实际的服务器 table,我希望必须构建 DDL SQL 来创建 table,然后使用 ExecSQL 执行它(客户端)数据集,正如您已经尝试过的那样。
更新
尽管使用了不显示 FieldDef 的 TFDTable 组件,以下内容似乎可以满足您在代码中完成所有操作的要求,因此我使用了代码创建的 TFields。在西雅图 D10 测试。
procedure TForm3.CreateDatabaseAndTable;
const
DBName = 'd:\delphi\code\sqlite\atest.sqlite';
var
AField : TField;
begin
if FileExists(DBName) then
DeleteFile(DBName);
AField := TLargeIntField.Create(Self);
AField.Name := 'IDField';
AField.FieldName := 'ID';
AField.DataSet := FDTable1;
AField := TWideStringField.Create(Self);
AField.Size := 80;
AField.Name := 'NameField';
AField.FieldName := 'Name';
AField.DataSet := FDTable1;
FDConnection1.Params.Values['database'] := DBName;
FDConnection1.Connected:= True;
FDTable1.TableName := 'MyTable';
FDTable1.CreateTable(False, [tpTable]);
FDTable1.Open();
FDTable1.InsertRecord([1, 'First']);
FDConnection1.Commit;
FDConnection1.Connected:= False;
end;
我希望比我更熟悉的人可以使用 TFDMemTable 的 FieldDefs 做类似的事情,如果它通过 FDTableAdaptor 正确连接到服务器端组件(FDCommand?)。
顺便说一句,我使用了 LargeInt ID 字段和 WideString Name 字段,因为前一段时间尝试将 Sqlite 与 D7 一起使用时,我在尝试使用整数和字符串字段时遇到了无穷无尽的麻烦。
顺便说一句,如果您在部署之前知道所需的结构,您可能会发现如果您只是将一个空数据库 + table 复制到位,您可能会获得更多 predictable/robust 结果,而不是而不是尝试在原位创建 table 。 Ymmv,当然。
我永远不会梦想使用 fielddef 创建数据库 table,因为您最终会得到 table,但没有适当的主键、索引和引用完整性。结果 table 完全是 "dumbed down".
只要您在查询中有 "where" 子句,数据库就会进行完整的 table 扫描以查找与查询匹配的记录。所以你的数据库随着大小的增加而变慢(并且 CPU 使用增加)。那只是糟糕的设计。
此致, 亚瑟
您可以使用应用程序 SQLite Expert Professional,创建 SQLite 数据库。
并使用 FDConnection 连接到数据库。并使用它。 数据库SQLite的方法,和MartynA说的一样。
Begin
FDConnection1.Connected:=false;
FDConnection1.Params.Clear;
FDConnection1.Params.Database:='D:\SQLiteDatabase.db';
FDConnection1.ConnectionDefName:='SQLite_Demo';
FDConnection1.DriverName:='SQLite';
FDConnection1.Connected:=true;
FDTable1.Open;
End;