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!
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With