我有一个SP,使用CURSOR和FETCH NEXT更新表中的价格。
游标的查询是一个简单的“选择”,而不是WHERE - 我正在加入一个带来所有相关用户ID的函数。
现在,由于我的SP更新了很多不同的表(附加只是其中的一部分),并且在每次更新中我都使用了用户函数的JOIN - 我想节省一些时间,并带来用户仅在SP的开头列出一次。
如果我加入临时表(@t,其中包含用户ID),我会得到一个无限循环。 最终价格将是无限的。
但是 - 如果我加入函数本身,而不是应该具有完全相同值的临时表,一切都很好。
我评论了有问题的JOIN。
-- This is my main object, who "holds" a lot of users
DECLARE @DistID INT = 123
DECLARE @t TABLE
(MainDistID int,
DistID int,
UserID int)
INSERT INTO @t
SELECT MainDistID,
DistID,
UserID
FROM [MyScheme].[FnGetAllDistAndUsers] (@DistID)
DECLARE @Bid INT -- Will contain the ID we need to update
DECLARE c CURSOR LOCAL FOR
SELECT ID
FROM BillingDetails AS bd
-- BOTH JOINS SHOULD BE THE SAME:
--JOIN @t AS GUsers -- Infinite loop...
-- ON bd.UserID = GUsers.UserID
JOIN [MyScheme].[FnGetAllDistAndUsers] (@DistID) AS GUsers -- NO infinite loop
ON bd.UserID = GUsers.UserID
OPEN c
FETCH NEXT FROM c
INTO @Bid
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE MyTable
SET Price = Price * 2
WHERE MyTableID = @Bid
FETCH NEXT FROM c
INTO @Bid
END
谢谢!
答案 0 :(得分:0)
我认为米奇是对的,你不应该使用光标。在进行更新时,如果您加入主键,则速度最快,因此您可以执行此类操作。
DECLARE @t TABLE (Bid int)
INSERT INTO @t
SELECT bd.ID
FROM [MyScheme].[FnGetAllDistAndUsers] u (@DistID)
INNER JOIN BillingDetails bd
ON u.UserID = bd.UserID
UPDATE mt
SET Price = Price * 2
FROM MyTable mt
INNER JOIN @t t
ON mt.MyTableID = t.Bid