我的代码执行以下操作:


设置设计时间目标TFDConnection
创建运行时源TFDConnection
将所有索引和表放在目标中
重新创建那些
将所有数据从源复制到目标
删除其中一个名为TT_SYS_WEEKS的表(和索引)
重新创建并填充它


TFDConnections可以嵌入或不嵌入Firebird。在所有组合中都可以正常工作,除非同时嵌入了两者。

在步骤6中,执行后

DROP INDEX <OWNER>TT_I1_SYS_WEEKS
ALTER TABLE <OWNER>TT_SYS_WEEKS DROP CONSTRAINT TT_I0_SYS_WEEKS


该声明

DROP TABLE TT_SYS_WEEKS


[FireDAC][FB][Phys]unsuccesful metadata update Table TT_SYS_WEEKS already exists失败。

在步骤3、4、5中已经执行了完全相同的删除和创建表/索引的操作。 TT_SYS_WEEKS不是最后复制的表。

设计时间目标连接及其TFDPhysFBDriverLink设置如下:

AConnection.TxOptions.AutoCommit := true;
AFDPhysDriverLink.DriverID := 'FBEmbeddedBase';  // JD 28-3-2018
AFDPhysDriverLink.VendorLib := 'fbembed.dll';  // 32-bits only
AConnection.Params.DriverID := 'FBEmbeddedBase'; // AConnection
AConnection.Params.Database := 'full GDB file';
SetFireBirdMapRules(AConnection); // Some mapping rules
AConnection.UpdateOptions.LockWait := False;
AConnection.UpdateOptions.LockMode := lmNone;


运行时源连接和TFDPhysFBDriverLink设置如下:

// Create 'own' TFDPhysFBDriverLink for embedded connection
// https://stackoverflow.com/questions/46691699/setting-up-a-second-tfdphysfbdriverlink-possible-and-necessary
lDriverLink := TFDPhysFBDriverLink.Create(Application);
lDriverLink.DriverID := 'FBEmbedded';
lDriverLink.VendorLib := 'fbembed.dll';  // 32-bits embedded
LRestoreDB := TFDConnection.Create(Application);
LRestoreDB.UpdateOptions.RequestLive     := false;
LRestoreDB.ResourceOptions.AutoReconnect := true;
LRestoreDB.Params.DriverID := lDriverLink.DriverID;
with LRestoreDB do
begin
   Params.Database := AFBFileName;
   Params.UserName := '***';
   Params.Password := '***';
   LoginPrompt := False;
   // ResourceOptions.KeepConnection is default true
   FetchOptions.Mode := fmAll;
end;
SetFireBirdMapRules(LRestoreDB); // Some mapping rules


怎么回事?
我还有什么可以调查的吗?

其他背景信息:


对于许多表,使用参数化的INSERT查询将数据复制到目标数据库。每个表传输都围绕着具有显式提交的事务。
在表复制操作中,TxOptions.AutoCommit对于目标数据库为true
Delphi Tokyo 10.2.3 Win32应用程序,Firebird 2.5.3.25778 Win32
This user在DROP之后发生CREATE问题。在answer中,Mark使用execute语句写入,添加了与同一表名的后续DDL冲突的附加锁iirc。那是Firebird 2.1下的PSQL,没有提到嵌入式,并且我没有死锁错误。

最佳答案

您需要在步骤4、5和6(当然还有7)之后执行一次提交。 Firebird中的某些DDL仅在提交时才真正执行,因此,如果您在一个事务中运行所有内容,则实际上并不会在步骤3和4中删除并重新创建索引,步骤6中的表删除可能会被阻止当您尝试在步骤7中重新创建它时,步骤5中的早期DML和步骤6中的表删除将尚未执行。

关于delphi - 使用嵌入式Firebird时,删除表失败并显示“元数据更新失败”,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49531871/

10-14 18:37
查看更多