使用嵌入式 Firebird 时删除表失败并'unsuccessful metadata update'



我的代码执行以下操作:

  1. 设置设计时目标TFDConnection
  2. 创建运行时源TFDConnection
  3. 删除目标中的所有索引和表
  4. 重新创建那些
  5. 将所有数据从源复制到目标
  6. 删除其中一个名为TT_SYS_WEEKS的表(和索引
  7. )
  8. 重新创建并填充它

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
  • 德尔福东京 10.2.3 Win32 应用程序, 火鸟 2.5.3.25778 Win32
  • 此用户在删除后创建时遇到问题。在答案中,Mark 写道,使用 execute 语句添加了额外的锁 iirc,这些锁与相同表名的后续 DDL 冲突。那是Firebird 2.1下的PSQL,没有提到嵌入式,我没有死锁错误。

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

最新更新