在查询中使用参数导致BEGIN / COMMIT不匹配SQLException

时间:2016-10-25 14:12:47

标签: c# sql sql-server transactions sqlparameters

执行一堆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

我已经阅读过有关此异常的内容,但似乎并没有真正适用于此特殊情况。

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

1 个答案:

答案 0 :(得分:0)

试试这个:

// 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();
    }
}