Reputation: 21
I have a table("Product_Location
") with the following columns:
ProductID (PK), LocationID (PK), Quantity
i would like to update the table in the database from rows in a datatable. if row already exists then Update quantity otherwise Insert new row.
i have the following method which update the quantity in the table, if the combination of productID and LocationID exists, it just update otherwise insert new row for that combination. code:
public bool UpdateLocationQuantity(DataSet productLocationData,
SqlTransaction sqlTransaction)
{
try
{
bool result = true;
SqlCommand command = new SqlCommand();
//get the Transaction table which contains rows to update from dataset
DataTable table = productLocationData.Tables["Inventory_Transactions"];
//Create Command Text
string commandText = @" IF Exists (SELECT * FROM Product_Location PL
WHERE ProductID = @ProductID AND LocationID = @LocationID)
UPDATE Product_Location SET Quantity = Quantity + @Quantity
WHERE ProductID = @ProductID AND LocationID = @LocationID
ELSE
INSERT INTO Product_Location (ProductID,LocationID,Quantity)
VALUES(@ProductID,@LocationID,@quantity)";
command = new SqlCommand(commandText, this.CurrentConnection);
command.CommandType = CommandType.Text;
command.Transaction = sqlTransaction;
SqlParameterCollection paramCols = command.Parameters;
//this loop will do the update or insert for all rows in the table
// How can we optimize to only ONE CALL to database?
foreach (DataRow row in table.Rows)
{
paramCols.Clear();
paramCols.AddWithValue("@ProductID",row["ProductID"]);
paramCols.AddWithValue("@LocationID", row["LocationID"]);
paramCols.AddWithValue("@Quantity", row["Quantity"]);
result &= command.ExecuteNonQuery()>= 0;
}
return result;
}
catch
{
throw;
}
}
**My question is how we can optimize the code so only one call to ExecuteNonQuery to update the database instead of having it in a loop? Please note that we are not using StoredProcedure and all should be from C# and SQL Queries or Transactions.
if it was just Update the rows, we could call command.Update with providing the source table and it easily update all the rows without using rows. but since i am using 'IF Exists' then we are forced to use ExecuteNonQuery which is not accepting source table as parameter.
Thank You
Upvotes: 2
Views: 2865
Reputation: 1043
for multiple rows , add command in loop
foreach (DataRow row in table.Rows)
{
SqlCommand command = new SqlCommand();
.
.
.
}
Upvotes: 0
Reputation: 8659
Instead of using a ParameterCollection you could do:
command.Parameters.Add(new SqlParameter("@ProductID", ProductData.PRODUCTID_FIELD));
or
command.Parameters.AddWithValue("@ProductID", ProductData.PRODUCTID_FIELD);
and so on. You don't actually have to specify the type.
Then call:
int numOfRowsAffected = command.ExecuteNonQuery();
There is no dataset to be returned, only the number of rows affected, since this is a non-query.
The problem with making a ParameterCollection like you are doing is you then need to set command.Parameters = paramCols;
but command.Parameters is Read-Only, so you can't. That is, its read-only as far as assignment goes. You can only add parameters to it through the methods Add
and AddWithValue
.
Upvotes: 1