Popokoko
Popokoko

Reputation: 6543

C# , SQL update multiple rows

i have a question regarding an efficient way to update multiple rows via SQL.

Basiclly i have a query i need to run on different RowIDs:

UPDATE TableName SET Column = (some number) WHERE RowID = (some number)

if to be more specific this is a better example:

UPDATE TableName SET Column = 5 WHERE RowID = 1000
UPDATE TableName SET Column = 10 WHERE RowID = 1001
UPDATE TableName SET Column = 30 WHERE RowID = 1002
..

I'd like to know how should i build the update query command on C# (or just give me an example of the resulted query i should get to) so once i use ExecuteQuery it will run all of these commands at one piece and not by executing each command.

edited: I have another problem, can you also explain what about dynamic situation in which not necessarly the row i want to update exist already, in that case i need to insert instead of update. to explain better, back to my example lets say i want to do

UPDATE TableName SET Column = 5 WHERE RowID = 1000
INSERT INTO TableName [RowID, Column] VALUES (1001, 20)
UPDATE TableName SET Column = 30 WHERE RowID = 1002
..

The meaning of this is that i need to check if the row exist, if so i'd use update otherwise i'll have to insert it.

Thank you!

Upvotes: 13

Views: 22349

Answers (2)

onedaywhen
onedaywhen

Reputation: 57023

Use MERGE:

MERGE INTO TableName
   USING (
          VALUES (1000, 5), 
                 (1001, 10), 
                 (1002, 30)
         ) AS source (RowID, Column_name)
      ON TableName.RowID = source.RowID
WHEN MATCHED THEN
   UPDATE 
      SET Column_name = source.Column_name
WHEN NOT MATCHED THEN
   INSERT (RowID, Column_name) 
      VALUES (RowID, Column_name);

Rather than hard-coding/dynamic SQL, the MERGE statement could be encapsulated into a stored proc that takes a table-valued parameter.

Upvotes: 1

Tim Schmelter
Tim Schmelter

Reputation: 460138

You could use a DataTable to store your records, insert, delete or change rows and update all changes in one batch by using SqlDataAdapter's UpdateBatchSize(0 means no limit):

public static void BatchUpdate(DataTable dataTable,Int32 batchSize)
{
    // Assumes GetConnectionString() returns a valid connection string.
    string connectionString = GetConnectionString();

    // Connect to the AdventureWorks database.
    using (SqlConnection connection = new 
      SqlConnection(connectionString))
    {

        // Create a SqlDataAdapter.
        SqlDataAdapter adapter = new SqlDataAdapter();

        // Set the UPDATE command and parameters.
        adapter.UpdateCommand = new SqlCommand(
            "UPDATE Production.ProductCategory SET "
            + "Name=@Name WHERE ProductCategoryID=@ProdCatID;", 
            connection);
        adapter.UpdateCommand.Parameters.Add("@Name", 
           SqlDbType.NVarChar, 50, "Name");
        adapter.UpdateCommand.Parameters.Add("@ProdCatID", 
           SqlDbType.Int, 4, "ProductCategoryID");
         adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;

        // Set the INSERT command and parameter.
        adapter.InsertCommand = new SqlCommand(
            "INSERT INTO Production.ProductCategory (Name) VALUES (@Name);", 
            connection);
        adapter.InsertCommand.Parameters.Add("@Name", 
          SqlDbType.NVarChar, 50, "Name");
        adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None;

        // Set the DELETE command and parameter.
        adapter.DeleteCommand = new SqlCommand(
            "DELETE FROM Production.ProductCategory "
            + "WHERE ProductCategoryID=@ProdCatID;", connection);
        adapter.DeleteCommand.Parameters.Add("@ProdCatID", 
          SqlDbType.Int, 4, "ProductCategoryID");
        adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None;

        // Set the batch size.
        adapter.UpdateBatchSize = batchSize;

        // Execute the update.
        adapter.Update(dataTable);
    }
}

http://msdn.microsoft.com/en-us/library/aadf8fk2.aspx

I assume you're misunderstanding how the dbms works internally. This

UPDATE TableName SET Column = 5 WHERE RowID = 1000;
UPDATE TableName SET Column = 5 WHERE RowID = 1002;

is the same as

UPDATE TableName SET Column = 5 WHERE RowID IN(1000,2002);

The dbms will update all affected records one by one anyway even if you would write a statement like UPDATE table SET value=1 which would affect every record in the table. By updating in one batch you ensure that all updates(deletes,inserts)are submitted to the database instead of one roundtrip for every statement.

Upvotes: 9

Related Questions