2011-10-06 130 views
0

我有一個帶有表輸入的存儲過程。我想以某種方式遍歷該表的各行。我不確定你在SQL中如何做這種事情。循環遍歷SQL表中的行

這裏就是我試圖做的,在僞SQL:

CREATE PROCEDURE RearrangePuzzles 
    ChangedPuzzles table(
     OldDifficulty nvarchar(50), 
     OldIndex int, 
     NewDifficulty nvarchar(50), 
     NewIndex int 
    ) 
AS 
FOREACH Row IN ChangedPuzzles 
BEGIN 
    UPDATE Puzzles 
    SET Index = Row.NewIndex, 
     Difficulty = Row.NewDifficulty 
    WHERE Index = Row.OldIndex AND 
      Difficulty = Row.OldDifficulty 
END 

這,當然,是不是有效的SQL。我如何在SQL中編寫具有所需功能的查詢?

回答

4

我認爲在SQL內部採用基於集合的方法通常更好,而不是逐行的解決方案。我相信一個JOIN會在你的情況下工作:

UPDATE p 
SET 
    Index = cp.NewIndex, 
    Difficulty = cp.NewDifficulty 
FROM 
    Puzzles p JOIN 
    ChangedPuzzles cp ON cp.OldIndex = p.Index AND cp.OldDifficulty = p.Difficulty 
0

你就不能這樣做:

UPDATE Puzzles 
SET 
    Index = cp.NewIndex, 
    Difficulty = cp.NewDifficulty 
FROM ChangedPuzzles cp 
WHERE Index = cp.OldIndex 
AND Difficulty = cp.OldDifficulty 

(這是一個幾個月,因爲我得到了到SQL,所以道歉,如果語法是關閉的)

0

我可能失去了一些東西,但不這樣完成這個?:

UPDATE Puzzles 
SET  Puzzles.[Index] = ChangesPuzzles.NewIndex, 
     Puzzles.Difficulty = ChangedPuzzles.NewDifficulty 
FROM ChangedPuzzles 
WHERE Puzzles.[Index] = ChangedPuzzles.OldIndex AND Puzzles.Difficulty = ChangesPuzzles.OldDifficulty 
1

你可以做到這一點通過「更新 - 從」查詢:

UPDATE a 
SET a.Index = b.NewIndex, 
    a.Difficulty = b.NewDifficulty 
FROM Puzzles a 
JOIN ChangedPuzzles b ON a.Index = b.OldIndex AND a.Difficulty = b.OldDifficulty 
0

你可以使用table-valued parameters(新的SQL Server 2008):

CREATE TYPE dbo.ChangedPuzzles AS TABLE 
(
     OldDifficulty NVARCHAR(50) NOT NULL, 
     OldIndex INT NOT NULL, 
     NewDifficulty NVARCHAR(50) NOT NULL, 
     NewIndex INT NOT NULL, 
     PRIMARY KEY(OldIndex, OldDifficulty) 
); 
GO 

CREATE PROCEDURE dbo.RearrangePuzzles 
@Source dbo.ChangedPuzzles READONLY 
AS 

UPDATE Puzzles 
SET  Index = src.NewIndex, 
    Difficulty = src.NewDifficulty 
FROM Puzzles p 
INNER JOIN @Source src ON p.Index = src.OldIndex 
AND p.Difficulty = src.OldDifficulty; 
GO 

--Test 
DECLARE @p dbo.ChangedPuzzles; 
INSERT @p VALUES (10,1,11,11), (20,2,22,12); 

EXECUTE dbo.RearrangePuzzles @p;