0

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?

marsze
  • 15,079
  • 5
  • 45
  • 61

1 Answers1

0

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();
    }
}
CesarKM
  • 1
  • 1
  • This could work, but it's really just a workaround and not an explanation for this behavior. Also, in reality I will not know which batch will need parameters and which will break if I add any. – marsze Oct 27 '16 at 09:17
  • I guess it's cause command.ExecuteNonQuery() . If you declare a Parameters where dont have parameters you will get that error. – CesarKM Oct 27 '16 at 19:14