我在c#中使用针对Firebird的dot net提供程序运行了许多SQL命令。具体来说,我改变数据库架构,进行数据更新等。
作为我处理的一部分,我创建了一个新表,运行查询以从旧表中复制数据,然后删除旧表。
当我这样做时,firebird会生成错误:
不成功的元数据更新对象正在使用
我已经完成了一些工作,并且似乎就像复制数据的查询一样,并没有被清除"我们还是别的什么。我的意思是当我在我的c#执行暂停时检查Firebird中的监控表时,我看到MON$STATEMENTS
表中的查询为非活动状态。这是在我运行提交声明之后。
我的问题:
在我尝试运行下一个命令之前,有没有办法暂停,等待或强制查询完全完成?
当我在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;
答案 0 :(得分:2)
我遇到了同样的问题并验证了Beau的(原始)修补程序。然而,我找到了一个简单的解决方案:在事务提交后处理命令!然后不再需要重新连接。
mtransaction = Connection.BeginTransaction(IsolationLevel.Serializable);
FbCommand command = new FbCommand(commandString, Connection, mtransaction);
command.ExecuteNonQuery();
transaction.Commit();
command.Dispose(); // Thus!
transaction.Dispose();
此致 航标
答案 1 :(得分:0)
好的,问题的可怕解决方案:
我实际上能够通过关闭和处理连接,然后重新连接来实现这一点。这导致以某种方式删除“卡住”查询,然后我可以执行表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;
注意:我对此解决方案非常满意。它有效,但我不知道为什么。对于我来说,放弃一张桌子似乎过分和不经常。我非常赞赏任何人可能在这件事上提供的任何见解!!!
答案 2 :(得分:0)
我相信我遇到了类似的事情。我的猜测是根本原因似乎是一个特征:MVCC。当我乱用模式,或者只删除表来重新创建时,Visual Studio通常会将其保持打开状态。我只是重启服务,一切都很好。