Search code examples
sql-serverpowershelltransactionsazure-powershellazure-runbook

Exception calling "ExecuteNonQuery" with "0" argument(s): "The transaction count is not 0


I am trying to run an Azure Runbook that executes a database maintenance stored procedure. However, $command.ExecuteNonQuery() gives me the error Exception calling "ExecuteNonQuery" with "0" argument(s): "The transaction count is not 0 in the following PowerShell script:

$credential = Get-AutomationPSCredential -Name 'Credential'

$userName = $credential.UserName

$password = $credential.GetNetworkCredential().Password

$connectionString = "Data Source=server.database.windows.net;Initial Catalog=database;Integrated Security=False;User ID=$userName;Password=$password"

$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)

$connection.Open()

$transaction = $connection.BeginTransaction()

try {
    $command = New-Object System.Data.SqlClient.SqlCommand

    $command.Connection = $connection

    $command.Transaction = $transaction
    
    $command.CommandType = [System.Data.CommandType]::StoredProcedure
    
    $command.CommandText = "dbo.IndexOptimize"
    
    $command.Parameters.AddWithValue("@Databases", "USER_DATABASES")
    
    $command.Parameters.AddWithValue("@MinNumberOfPages", "500")
    
    $command.Parameters.AddWithValue("@FragmentationMedium", "INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE")
    
    $command.Parameters.AddWithValue("@FragmentationHigh", "INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE")
    
    $command.Parameters.AddWithValue("@FragmentationLevel1", "5")
    
    $command.Parameters.AddWithValue("@FragmentationLevel2", "30")
    
    $command.Parameters.AddWithValue("@UpdateStatistics", "COLUMNS")
    
    $command.Parameters.AddWithValue("@LogToTable", "Y")
    
    $command.ExecuteNonQuery()
    
    $transaction.Commit()
}
catch {
    try {       
        $transaction.Rollback()
    }       
    catch {
        # Microsoft recommends to catch and log and/or ignore rollback exceptions
    }
    throw
}
finally {
    $command.Dispose()
    
    $transaction.Dispose()
    
    $connection.Close()
}

Solution

  • Ola's maintenance scripts do their own transaction handling. So you don't need your own transaction.

    Remove the following lines as well as the catch:

    $transaction = $connection.BeginTransaction()
    ...
    $command.Transaction = $transaction
    ...
    $transaction.Dispose()
    

    Also the whole catch... $transaction.Rollback was not necessary anyway even if you wanted a transaction. Since you have a finally with $transaction.Dispose this will get handled for you anyway.