2013-03-11 60 views
0

我有一個塞納里奧其中i具有從不是Temptable傳遞參數給存儲過程從一個臨時表

#student(table) 
StudentID Class 
10008  A 
10009  A 
10010  C 

的存儲過程接受2個參數StudentID和Class將參數傳遞給存儲過程。

Student_Fail @StudentID,@Class 

我想爲所有的studentID執行這個存儲過程(3次)。

這怎麼辦?使用while循環?

回答

1

理想情況下,您應該重新編寫存儲過程,以便它可以直接使用#temp表,或者創建不同的存儲過程,或者只是在此代碼中複製存儲過程試圖對單個行執行的操作。 (基於集合的操作幾乎總是優於一次處理一行。)

簡言之,您必須使用遊標或while循環(and no they aren't really different)。

DECLARE @StudentID INT, @Class CHAR(1); 

DECLARE c CURSOR LOCAL FAST_FORWARD 
    FOR SELECT StudentID, Class FROM #student; 

OPEN c; 

FETCH c INTO @StudentID, @Class; 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    EXEC dbo.Student_Fail @StudentID, Class; 
    FETCH c INTO @StudentID, @Class; 
END 

CLOSE c; 
DEALLOCATE c; 
1

正如您所指出的,while循環會做:

declare @StudentID int 
declare @Class char(1) 

while exists (select 1 from #student) 
begin 

    select top 1 @StudentID = StudentID 
    , @Class = Class 
    from #student 

    exec Student_Fail @StudentID, @Class 

    delete from #student where @StudentID = StudentID 

end 
1

是的,這可以被實現爲WHILE循環,或作爲CURSOR,因爲在這種情況下,他們將主要做同樣的事情,逐行操作。

但是,理想的解決方案是重新實現Student_Fail失敗存儲過程,使其基於set-based而不是procedure。

例如,您可以更改存儲過程以接受table-valued parameter

首先,創建表的類型:

CREATE TYPE dbo.StudentClassTableType AS TABLE 
(StudentID int, Class varchar(50)) 

接着,改變存儲的過程(或創建一個新的存儲過程)接受表型:

CREATE PROCEDURE dbo.usp_FailStudents 
(@tvpStudentsToFail dbo.StudentClassTableType READONLY) 
-- Perform set-based logic using your table parameter. 
UPDATE sc 
SET Fail = 1 
FROM dbo.StudentClass sc 
JOIN @tvpStudentsToFail fail 
    ON fail.StudentID = sc.StudentID 
    AND fail.Class = sc.Class 
相關問題