传递参数给存储过程从一个临时表

问题描述:

我有一个塞纳里奥其中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