9

I'm coding a transaction manually in ADO.NET. The example I'm working from reuses the SqlCommand which seem like a fine idea.

However, I have added parameters to my command.

My question is: in the following code, is command.Parameters.Clear() correct? Or am I doing it wrong?

using (var connection = new SqlConnection(EomAppCommon.EomAppSettings.ConnStr))
{
    connection.Open();
    SqlTransaction transaction = connection.BeginTransaction();
    SqlCommand command = connection.CreateCommand();
    command.Transaction = transaction;
    try
    {
        foreach (var itemIDs in this.SelectedItemIds)
        {
            command.CommandText = "UPDATE Item SET payment_method_id = @batchID WHERE id in (@itemIDs)";
            // IS THE FOLLOWING CORRECT?
            command.Parameters.Clear();

            command.Parameters.Add(new SqlParameter("@batchID", batchID));
            command.Parameters.Add(new SqlParameter("@itemIDs", itemIDs));
            command.ExecuteNonQuery();
        }
        transaction.Commit();
    }
    catch (Exception ex)
    {
        MessageBox.Show("Failed to update payment batches, rolling back." + ex.Message);
        try
        {
            transaction.Rollback();
        }
        catch (Exception exRollback)
        {
            if (!(exRollback is InvalidOperationException)) // connection closed or transaction already rolled back on the server.
            {
                MessageBox.Show("Failed to roll back. " + exRollback.Message);
            }
        }
    }
}
Aaron Anodide
  • 16,906
  • 15
  • 62
  • 121

2 Answers2

13

Since you're repeatedly executing the same query, it's unnecessary to clear them - you can add the parameters outside the loop and just fill them inside.

try
{
    command.CommandText = "UPDATE Item SET payment_method_id = @batchID WHERE id in (@itemIDs)";
    command.Parameters.Add(new SqlParameter("@batchID", 0));
    command.Parameters.Add(new SqlParameter("@itemIDs", ""));

    foreach (var itemIDs in this.SelectedItemIds)
    {
        command.Parameters["@batchID"].Value = batchID;
        command.Parameters["@itemIDs"].Value = itemIDs;
        command.ExecuteNonQuery();
    }
    transaction.Commit();
}

Note - you can't use parameters with IN as you've got here - it won't work.

Community
  • 1
  • 1
Richard
  • 29,854
  • 11
  • 77
  • 120
  • yeah I just discovered that about the IN clause, thanks for the link – Aaron Anodide Jan 17 '13 at 08:16
  • Besides the additional processing, is there any other downside to clearing and re-adding them? Not clearing them also makes the code less DRY. – Lukas Oct 22 '20 at 15:35
1

In this condition you need it as you need set new parameters values, so its correct.

By the way, move

command.CommandText = ".."

outside of the loop too, as it's never changed.

Tigran
  • 61,654
  • 8
  • 86
  • 123