在相关操作中使用Insert和Update语句

时间:2014-07-09 19:20:13

标签: sql sql-server database

我想在一个名为Payment的表中插入一条记录,其中列ID为主键(自动增量),然后我希望将ID用于另一个更新语句的WHERE子句。

var insertSatement = @"BEGIN INSERT INTO Payment (payment_type, reference, payment_date, total_records, total_amount) VALUES(@type, @reference, @date, @totalRecords, @totalAmount ) ";

var updateStatement = @"UPDATE SalaryTrans SET payment_id = (SELECT TOP 1 id FROM Payment ORDER BY Payment.id) WHERE SalaryTrans.id = @paramID ";

由于更新将更新多行,因此无法合并这两个语句。它将更新SalaryTrans表的所有匹配行。所以我使用foreach循环。

//open connection, add parameters 

sqlCommand.CommandText = insertStatement;
sqlCommand.ExecuteNonQuery(); // This inserts...

foreach(PaymentInfo p in paymentList)
{
    paramID.value = p.id;
    sqlCommand.CommandText = updateStatement;
    sqlCommand.ExecuteNonQuery();

}

每次"SELECT TOP 1 id..."执行时,在循环中。为了避免这种情况,有没有办法使用SCOPE_IDENTITY()从Payment表中获取最后更新的ID并在循环中使用它?

如果我在此上下文中更改update语句(性能明智)会有区别吗?

DECLARE @ID INT = (SELECT TOP 1 id FROM Payment ORDER BY Payment.id) 
UPDATE SalaryTrans SET payment_id = @ID WHERE SalaryTrans.id = 1

或者我应该将此SELECT与UPDATE分开以使其保持在循环之外吗?

注意:我的主要集中在于性能因素。

2 个答案:

答案 0 :(得分:2)

您还可以尝试更改您的声明,如下所示

var insertSatement = @"BEGIN INSERT INTO Payment (payment_type, reference, payment_date, total_records, total_amount) VALUES(@type, @reference, @date, @totalRecords, @totalAmount );  SELECT CAST(scope_identity() AS int) ";

然后在你的例外非查询中获取返回值

sqlCommand.CommandText = insertStatement;
int id = (int) sqlCommand.ExecuteScalar(); // This inserts...

您可以在循环中使用id

答案 1 :(得分:1)

您可以使用SCOPE_IDENTITY

它将包含新插入的行

中标识列的最新值

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