【问题标题】:Using parameter in query results in BEGIN / COMMIT mismatch SQLException在查询中使用参数导致 BEGIN / COMMIT 不匹配 SQLException
【发布时间】:2016-10-25 14:12:47
【问题描述】:

以下代码执行一堆 SQL 语句运行良好...

// SQL Server 2008 R2
SqlConnection connection = null;
var runBatch = false;
try
{
    connection = new SqlConnection(connectionString);
    connection.Open();
    var command = connection.CreateCommand();

    // 1st batch
    command.CommandText = "BEGIN TRANSACTION";
    command.ExecuteNonQuery;

    // 2nd batch
    command.CommandText = "UPDATE MyTable SET MyColumn = 'foo' WHERE Name = 'bar'";
    command.ExecuteNonQuery;

    // 3rd batch
    command.CommandText = "COMMIT TRANSACTION";
    command.ExecuteNonQuery;
}
finally
{
    if (connection != null)
    {
        connection.Close();
    }
}

...除非我使用参数:

// [...]
command.Parameters.AddWithValue("name", "bar");

// 1st batch
command.CommandText = "BEGIN TRANSACTION";
command.ExecuteNonQuery; // <= throws Exception

异常信息:

EXECUTE 之后的事务计数表明 BEGIN 和 COMMIT 语句的数量不匹配。先前计数 = 1,当前计数 = 0

注意:如果我将所有语句组合在一个命令中,这将起作用。但在我的应用程序中,原始 SQL 脚本是由GO 分隔的一堆批次,这些批次会自动拆分为多个命令(因此我无法控制如何使用事务或使用哪些事务):

/* Original SQL */

BEGIN TRANSACTION
GO
UPDATE MyTable
SET MyColumn = 'foo'
WHERE NAME = @name
GO
COMMIT TRANSACTION
GO

我已阅读有关此异常的信息,但似乎没有任何东西真正适用于这种特殊情况。

我还没有弄清楚在这里引入参数有什么确切的区别以及为什么它会破坏代码。有人对此有解决方案吗?

【问题讨论】:

标签: c# sql sql-server transactions sqlparameter


【解决方案1】:

试试这个:

// SQL Server 2008 R2

SqlConnection connection = null;

var runBatch = false;

try
{
    connection = new SqlConnection(connectionString);
    connection.Open();
    var command = connection.CreateCommand();

    // 1st batch
    command.CommandText = "BEGIN TRANSACTION";
    command.ExecuteNonQuery();

    // 2nd batch
    command.CommandText = "UPDATE MyTable SET MyColumn = 'foo' WHERE Name = @name";
    command.Parameters.AddWithValue("name", "bar");
    command.ExecuteNonQuery();

    // 3rd batch
    command.CommandText = "COMMIT TRANSACTION";
    command.Parameters.Clear();
    command.ExecuteNonQuery();
}
finally
{
    if (connection != null)
    {
        connection.Close();
    }
}

【讨论】:

  • 这可能有效,但它实际上只是一种解决方法,而不是对此行为的解释。另外,实际上我不知道哪个批次需要参数,如果我添加任何参数,哪个批次会中断。
  • 我猜是因为 command.ExecuteNonQuery() 。如果你声明一个没有参数的参数,你会得到那个错误。
猜你喜欢
  • 2019-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-10
  • 2014-03-21
  • 2016-06-21
  • 1970-01-01
  • 2011-05-12
相关资源
最近更新 更多