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

时间:2016-03-11 20:22:03

标签: 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;

3 个答案:

答案 0 :(得分:3)

CreateDataSet通常是用于将客户端数据集初始化为空状态的本地操作。如果TClientDataSet是任何东西,afaik它不能用于创建服务器端表。

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

<强>更新

以下似乎满足了您在代码中执行所有操作的要求,尽管使用的TFDTable组件并没有表现出FieldDef,所以我使用了代码创建的TField代替。在西雅图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,我尝试使用整数和字符串字段时没有遇到任何麻烦。

顺便说一句,如果您在部署之前了解所需的结构,那么如果您只是将空数据库+表复制到位,您可能会发现可以获得更可预测/更强大的结果,而不是尝试在原位创建表。 Ymmv,当然。

答案 1 :(得分:1)

我绝对不会梦想使用fielddef创建数据库表,因为你最终得到的表没有正确的主键,索引和参照完整性。由此产生的表格完全“愚蠢”。

每当查询中有“where”子句时,数据库都会执行全表扫描以查找与查询匹配的记录。因此,您的数据库随着大小而减慢(并且CPU使用量增加)。那只是糟糕的设计。

此致 亚瑟

答案 2 :(得分:0)

您可以使用应用程序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;