我正在尝试优化一个长事务,并且我发现以下操作已经完成了很多次:
Declare @myCursor CURSOR FAST_FORWARD FOR
SELECT field1, MIN(COALESCE(field2, -2)) FROM MyTable tempfact
LEFT JOIN MyTable sd
ON tempfact.ID = sd.ID AND sd.TransactionId = @transactionId
WHERE tempfact.SomeField IS NULL
AND tempfact.TransactionId = @transactionId
GROUP BY tempfact.field1
OPEN @myCursor
FETCH NEXT FROM @myCursor INTO @field1Variable, @field2Variable
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC USP_SOME_PROC @field1Variable, @field2Variable
FETCH NEXT FROM @myCursor INTO @field1Variable, @field2Variable
END
CLOSE @myCursor
DEALLOCATE @myCursor
USP_SOME_PROC 存储过程的代码如下:
IF NOT EXISTS (SELECT * FROM SomeTable WHERE Field1 = @field1)
BEGIN
INSERT INTO SomeTable (Field1, Field2)
VALUES (@field1, @field2)
END
就像我提到的,这是在很多地方完成的,涉及的表和字段不同,但想法保持不变,并且我确信如果游标不存在,可能有一种方法可以提高这些存储过程的性能使用并且可能通过使此事务更快,我们遇到的死锁问题(另一篇文章的主题)可能会得到解决。
最佳答案
您可以使用MERGE
来实现此目的
;WITH Source AS
(
SELECT field1,
MIN(COALESCE(field2, -2)) as field2
FROM MyTable tempfact
LEFT JOIN MyTable sd
ON tempfact.ID = sd.ID
AND sd.TransactionId = @transactionId
WHERE tempfact.SomeField IS NULL
AND tempfact.TransactionId = @transactionId
GROUP BY tempfact.field1
)
MERGE SomeTable AS T
USING Source S
ON (T.Field1 = S.Field1)
WHEN NOT MATCHED BY TARGET THEN
INSERT (Field1, Field2)
VALUES (field1, field2)
;
关于sql-server - 游标是执行此类操作的唯一选择吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7502360/