我有一个表(“Product_Location
”),其中包含以下列:
ProductID (PK), LocationID (PK), Quantity
我想从数据表中的行更新数据库中的表。如果行已存在,则更新数量,否则插入新行。
我有以下方法更新表中的数量,如果productID和LocationID的组合存在,则只需更新,否则为该组合插入新行。代码:
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;
}
}
**我的问题是我们如何优化代码,所以只有一次调用ExecuteNonQuery来更新数据库而不是在循环中?请注意,我们没有使用StoredProcedure,所有应该来自C#和SQL查询或事务。
如果它只是更新行,我们可以通过提供源表来调用command.Update,并且它可以轻松地更新所有行而不使用行。但由于我使用'IF存在',我们被迫使用不接受源表作为参数的ExecuteNonQuery。
谢谢
答案 0 :(得分:1)
您可以执行以下操作,而不是使用ParameterCollection:
command.Parameters.Add(new SqlParameter("@ProductID", ProductData.PRODUCTID_FIELD));
或
command.Parameters.AddWithValue("@ProductID", ProductData.PRODUCTID_FIELD);
等等。您实际上不必指定类型。
然后致电:
int numOfRowsAffected = command.ExecuteNonQuery();
没有要返回的数据集,只有受影响的行数,因为这是非查询。
像你正在做的那样创建一个ParameterCollection的问题是你需要设置command.Parameters = paramCols;
但是command.Parameters是只读的,所以你不能。也就是说,就任务而言,它是只读的。您只能通过方法Add
和AddWithValue
添加参数。