丢弃表格失败,导致元数据更新失败'使用嵌入式Firebird时

时间:2018-03-28 10:17:03

标签: delphi firebird firedac delphi-10.2-tokyo

我的代码执行以下操作:

  1. 设置设计时间目标TFDConnection
  2. 创建运行时来源TFDConnection
  3. 删除目标
  4. 中的所有索引和表格
  5. 重新创建
  6. 将所有数据从源复制到目标
  7. 删除其中一个名为TT_SYS_WEEKS
  8. 的表(和索引)
  9. 重新创建并填写
  10. 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 app,Firebird 2.5.3.25778 Win32
    • This user在DROP之后出现了CREATE问题。在answer中,Mark写入,使用execute语句会添加额外的锁定iirc,这与相同的表名的后续DDL冲突。那是Firebird 2.1下的PSQL,没有提到嵌入式,而且我没有死锁错误。

1 个答案:

答案 0 :(得分:0)

您需要在第4步,第5步和第6步(当然是 - 7)之后执行提交。 Firebird中的一些DDL只是在提交时才真正执行,所以如果你在一个事务中运行所有东西,你仍然没有在步骤3和4中实际删除并重新创建索引,步骤6中的表格丢弃可能是在步骤5中被先前的DML阻止,并且当您尝试在步骤7中重新创建它时,步骤6中的表删除仍未执行。