我有一個塞納里奧其中i具有從不是Temptable傳遞參數給存儲過程從一個臨時表
#student(table)
StudentID Class
10008 A
10009 A
10010 C
的存儲過程接受2個參數StudentID和Class將參數傳遞給存儲過程。
Student_Fail @StudentID,@Class
我想爲所有的studentID執行這個存儲過程(3次)。
這怎麼辦?使用while循環?
我有一個塞納里奧其中i具有從不是Temptable傳遞參數給存儲過程從一個臨時表
#student(table)
StudentID Class
10008 A
10009 A
10010 C
的存儲過程接受2個參數StudentID和Class將參數傳遞給存儲過程。
Student_Fail @StudentID,@Class
我想爲所有的studentID執行這個存儲過程(3次)。
這怎麼辦?使用while循環?
理想情況下,您應該重新編寫存儲過程,以便它可以直接使用#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;
正如您所指出的,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
是的,這可以被實現爲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