简体   繁体   中英

Using parameter in query results in BEGIN / COMMIT mismatch SQLException

The following code executing a bunch of SQL statements works well...

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

...unless I use a parameter:

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

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

Exception message:

Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0

Note: This would work, if I combined all the statements in a single command. But in my app, the original SQL script is a bunch of batches separated by GO which is automatically split into multiple commands (so I have no control over how or what transactions are used):

/* Original SQL */

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

I have read about this exception, but nothing really seems to apply to this special scenario.

I have not figured out yet what exact difference introducing a parameter makes here and why it breaks the code. Anyone got a solution for this?

Try this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM