sqlite - 如何使用 FieldDefs 在运行时创建新的 SQLite 文件和表?

标签 sqlite delphi firedac

我正在使用 Delphi Seattle 在全新的 SQLite 文件中创建一个全新的表,并且仅使用 FieldDefs 和非可视代码。我可以使用 ExecSQL ('CREATE TABLE....' ) 语法创建一个表,但不能如下所示(我得到“没有这样的表 'MyTable' ”,这是在执行 CreateDataSet 调用时引发的)。我想要一些允许我使用 FieldDefs 的解决方案。此代码以示例 here 为蓝本。 。但我注意到,关于 CreateDataSet 有一个注释,它仅适用于 TFDMemTable。是否有一种无需使用 ExecSQL 即可创建 SQLite 表的运行时方法?

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 是可以遵循的,那么它不能用于创建服务器端表。

要创建实际的服务器表,我希望必须构造 DDL SQL 来创建表,然后在(客户端)数据集上使用 ExecSQL 执行它,正如您已经尝试过的那样。

更新

以下内容似乎满足您在代码中执行所有操作的要求,但使用 TFDTable 组件,该组件不会显示 FieldDefs,因此我使用了代码创建的 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;

如果通过 FDTableAdaptor 正确连接到服务器端组件(FDCommand?),我希望比我更熟悉的人可以使用 TFDMemTable 的 FieldDef 执行类似的操作。

Fwiw,我使用了 LargeInt ID 字段和 WideString Name 字段,因为不久前尝试将 Sqlite 与 D7 一起使用,在尝试使用整数和字符串字段时遇到了无穷无尽的麻烦。

顺便说一句,如果您在部署之前知道所需的结构,您可能会发现,如果您只需将空数据库+表复制到位,而不是尝试在原位创建表,就会获得更可预测/稳健的结果。嗯,当然。

关于sqlite - 如何使用 FieldDefs 在运行时创建新的 SQLite 文件和表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35949230/

相关文章:

delphi - 在 Delphi 10.1 Berlin 中使用 VCL 样式时,TSaveDialog 的属性 "ofOverwritePrompt"不起作用

delphi - FireDac GetFieldNames 不带引号

sqlite - 在关闭应用程序之前,为什么我的SQLite数据库不添加数据?

objective-c - 从 SQLite 数据库填充 SplitViewController 中的 UITableView 和 DetailsView

string - 如何计算两个字符串之间的差异?

.net - 通过 COM 对象将 Delphi 生成的位图返回到 (ASP).Net

sql-server - Delphi Firedac MSSQL复制到不同的服务器

python - 正确选择由字典组成的数据库

database - 无论主键如何,如何检查两个关系数据库是否相同?

android - 在 Android 中打开预先存在的 sqlite 数据库的持续问题