Firebird点网提供商没有完全执行查询?

我正在使用c#中的Firebird点网提供程序运行一些SQL命令。 具体来说,我正在更改数据库架构,并进行数据更新等。

作为我处理的一部分,我创建了一个新表,运行查询以从旧表中复制数据,然后删除旧表。

当我这样做时,firebird生成并出错:

不成功的元数据更新对象正在使用中

我做了一些寻找, 似乎复制数据的查询尚未“清除”我们或其他东西。 我的意思是当我在我的c#执行暂停时检查Firebird中的监控表时,我看到MON$STATEMENTS表中的查询为非活动状态。 这是在我运行commit语句之后。

我的问题:

在我尝试运行下一个命令之前,有没有办法暂停,等待或强制查询完全完成?

当我在ISQL中运行相同的查询序列时,它完美地运行。 有没有什么不同的ISQL,我可以强制点网Firebird提供商这样做,它不会保持这个查询打开或什么?

所以为了参考,代码看起来像这样(显然这是一个非常简化的):

  // create the table string commandString = "CREATE TABLE ..."; // run the command in a transaction and commit it mtransaction = Connection.BeginTransaction( IsolationLevel.Serializable ); FbCommand command = new FbCommand(commandString, Connection, mtransaction); command.ExecuteNonQuery(); transaction.Commit(); transaction.Dispose(); transaction = null; // copy the data to the new table from the old commandString = "INSERT INTO ..."; mtransaction = Connection.BeginTransaction(IsolationLevel.Serializable); FbCommand command = new FbCommand(commandString, Connection, mtransaction); command.ExecuteNonQuery(); transaction.Commit(); transaction.Dispose(); transaction = null; // drop the old table commandString = "DROP TABLE ..."; mtransaction = Connection.BeginTransaction(IsolationLevel.Serializable); FbCommand command = new FbCommand(commandString, Connection, mtransaction); command.ExecuteNonQuery(); // this command fails with the exception // if I pause execution in c# before running this command, and // use isql to look at the db I see the new table, and the data fully populated // and I also see the inactive insert command in MON$STATEMENTS transaction.Commit(); transaction.Dispose(); transaction = null; 

我遇到了同样的问题并validation了Beau的(原始)修补程序。 然而,我找到了一个简单的解决方案:在事务提交后处理命令! 然后不再需要重新连接。

 mtransaction = Connection.BeginTransaction(IsolationLevel.Serializable); FbCommand command = new FbCommand(commandString, Connection, mtransaction); command.ExecuteNonQuery(); transaction.Commit(); command.Dispose(); // Thus! transaction.Dispose(); 

此致,AtoN

好的,问题的可怕解决方案:

我实际上能够通过关闭和处理连接,然后重新连接来实现这一点。 这导致以某种方式删除“卡住”查询,然后我可以执行表drop命令。 所以顺序看起来像这样:

 // create the table string commandString = "CREATE TABLE ..."; // run the command in a transaction and commit it mtransaction = Connection.BeginTransaction( IsolationLevel.Serializable ); FbCommand command = new FbCommand(commandString, Connection, mtransaction); command.ExecuteNonQuery(); transaction.Commit(); transaction.Dispose(); transaction = null; // copy the data to the new table from the old commandString = "INSERT INTO ..."; mtransaction = Connection.BeginTransaction(IsolationLevel.Serializable); FbCommand command = new FbCommand(commandString, Connection, mtransaction); command.ExecuteNonQuery(); transaction.Commit(); transaction.Dispose(); transaction = null; // ------------------ // Drop the connection entirely and start a new one // so the table can be dropped Connection.Close(); Connection.Dispose(); // build connection string FbConnectionStringBuilder csb = new FbConnectionStringBuilder(); csb.DataSource ... etc... // connect Connection = new FbConnection(connectionString); Connection.Open(); // Now have new connection that does not have weird // lingering query, and table can now be dropped // ----------------- // drop the old table commandString = "DROP TABLE ..."; mtransaction = Connection.BeginTransaction(IsolationLevel.Serializable); FbCommand command = new FbCommand(commandString, Connection, mtransaction); command.ExecuteNonQuery(); // this no longer fails because the connection was complete closed // and re-opened transaction.Commit(); transaction.Dispose(); transaction = null; 

注意:我对此解决方案非常满意。 它有效,但我不知道为什么。 对我来说,放下一张桌子似乎过分和不经常。 我非常想要任何人在这件事上提供的任何见解!

我相信我遇到了类似的事情。 我的猜测是根本原因似乎是一个特征:MVCC。 当我混乱使用模式,或者只删除表来重新创建时,Visual Studio通常会将其保持打开状态。 我只是重启服务,一切都很好。