我想创建一个新的 mdb 文件,其中包含基于以前存在的表的结构的表。我知道我可以用newTable.FieldDefs.Add()
它在循环中一个一个地重新创建字段。但是由于已经有一个 oldTable 完全存放了正确的FieldDefs
,这似乎非常不雅。我一直在寻找单语句解决方案!
我发现它newTable.FieldDefs.Assign(oldTable.FieldDefs)
可以编译(并运行)而没有错误,但它留下newTable
了零定义的字段。这使我错误地得出结论,即我不理解该语句的功能。(后来我发现它只有在oldTable.open
没有发生时才会失败,当数据库不可用时不会发生这种情况,即使FieldDefs
已经将其设置为 Persistent 并且在 Object Inspector 中清晰可见)
这是我经过一番调查后的原始代码:
procedure TForm2.Button1Click(Sender: TObject);
var
fname: string;
Table: TFDTable;
FDConn: TFDConnection;
begin
fname := 'C:\ProgramData\mymdb.mdb';
if FileExists(fname) then DeleteFile(fname);
{ Make new file for Table }
FDMSAccessService1.Database := fname;
FDMSAccessService1.DBVersion := avAccess2000;
FDMSAccessService1.CreateDB;
{ Connect to new file }
FDConn := TFDConnection.Create(nil);
FDConn.Params.Database := fname;
FDConn.Params.DriverID := 'MSAcc';
FDConn.Connected := true;
{ Set up new Table using old table's structure }
Table := TFDTable.Create(nil);
try
{ ADOTable1 has been linked to an existing table in a prior
database with Field Defs made Persistent using the Fields
Editor in the Object Inspector. That database will not be
available in my actual use scenario }
try
ADOTable1.open; // Throws exception when database file not found
except
end;
Table.Connection := FDConn;
{ specify table name }
Table.TableName := ADOTable1.TableName;
Table.FieldDefs.Assign(ADOTable1.FieldDefs); // No errors reported
ShowMessageFmt('New Table %s has %d fields',[Table.TableName,
Table.FieldDefs.Count]);
{ Reports correct TableName but "0 fields" with table not open
(i.e. file not found). Reports "23 fields" with table open }
{ Set Table definition into new mdb file }
Table.CreateTable(False); // Throws exception when 0 fields found
finally
Table.Free;
end;
end;
事实证明,解决方案是使用最初链接到同一个旧数据库的 ClientDataSet 而不是 ADOTable。请参阅我的回答中的以下工作解决方案。
编辑:最后一点。我曾希望使用这种 FireDAC 方法,如此处所示,来解决缺少TADOTable.CreateTable
方法的问题。唉,尽管上面和下面的“解决方案”确实可以创建一个新TADOTable
的 ,但该表的字段定义并不是原始表的忠实副本。可能有无数TFDTable
选项的组合可以解决这个问题,但我无法发现它,所以我恢复使用 SQL 创建我的 ADO 表。