1

光标我使用IS ...如何在SQL Server 2005中使用带有参数的游标?

Create Proc GetExamResults (@Course_Id varchar(100), @Semester varchar(10)) 
as 
begin 
    declare @subjname varchar(100) 
    declare @subjects varchar(7000) 
    declare @subjectsselection varchar(7000) 
    declare @SumSelection varchar(7000) 
    declare @NoOfSubjects int 
    set @NoOfSubjects = 0 

    set @subjects = '' 
    set @subjectsselection = '' 
    set @SumSelection = '' 

    DECLARE subject_cursor CURSOR 
    FOR SELECT distinct Subject_Name FROM Exam_Result where course_id = @Course_Id And Semester = @Semester 

    OPEN subject_cursor 

    FETCH NEXT FROM subject_cursor 
    INTO @subjname 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     set @subjects = @subjects + '[' + @subjname + '],' 
     set @subjectsselection = @subjectsselection + 'Sum(Isnull([' + @subjname + '],0)) As [' + @subjname + '],' 
     set @SumSelection = @SumSelection + 'Sum(Isnull([' + @subjname + '],0))+' 

     set @NoOfSubjects = @NoOfSubjects + 1 

     FETCH NEXT FROM subject_cursor 
     INTO @subjname 
    End 
    CLOSE subject_cursor; 
    DEALLOCATE subject_cursor; 

    select @subjects = LEFT(@subjects, LEN(@subjects) - 1) 
    select @subjectsselection = LEFT(@subjectsselection, LEN(@subjectsselection) - 1) 
    select @SumSelection = LEFT(@SumSelection, LEN(@SumSelection) - 1) 

    print @subjects 
    print @subjectsselection 
    print @SumSelection 

    declare @query nvarchar(4000) 

    set @query = 'select S.Enroll_Number, pvt.Student_Name, pvt.Course_Id, pvt.Semester, ' + @subjectsselection + ',' 
    set @query = @query + 'Exam_Type,' + @SumSelection + ' As Grand_Total, ' 
    set @query = @query + '(' + @SumSelection + ')' + '/' + convert(varchar(10),@NoOfSubjects) + ' As Avg' 
    set @query = @query + ' From ' 
    set @query = @query + '(select Enroll_Number, Student_Name, Course_Id, Semester, Subject_Name, MarksObtained, Exam_Type from Exam_Result) ps ' 
    set @query = @query + ' pivot(sum(MarksObtained) for Subject_Name in (' + @subjects + ')) as pvt' 
    set @query = @query + ' inner join Stud_Info S on S.Enroll_Number = pvt.Enroll_Number ' 
    set @query = @query + ' where pvt.Course_Id = ''' + @Course_Id + ''' and pvt.Semester = ''' + @Semester + '''' 
    set @query = @query + ' group by S.Enroll_Number, pvt.Student_Name, pvt.Course_Id, pvt.Semester, Exam_Type' 
    print @query 
    exec sp_executesql @query 
end 

这些2个表中的光标被用于...

1] Stud_Info

CREATE TABLE Stud_Info 
(Enroll_Number  varchar(20) NOT NULL, 
Salutation   varchar(10) NULL, 
First_Name   varchar(20) NULL, 
Middle_Name   varchar(20) NULL, 
Last_Name   varchar(20) NULL, 
Course_Id   varchar(20) NULL, 
Batch    varchar(20) NULL) 

INSERT into Stud_Info values(11161,'Mr.','Mack','B','Botha','MECH','Batch1');  
INSERT into Stud_Info values(11162,'Mr.','John','A','Los','CIVIL','Batch2');  
INSERT into Stud_Info values(11163,'Ms.','Merry','F','Dsuza','ELCT','Batch1');  
INSERT into Stud_Info values(11164,'Mr.','Pow','B','Janero','MECH','Batch2');  
INSERT into Stud_Info values(11165,'Mr.','Martin','J','Smith','MECH','Batch1');  

2] Exam_Result

CREATE TABLE Exam_Result 
(Result_Id    numeric(18, 0) IDENTITY(1,1) NOT NULL, 
Enroll_Number   varchar(50) NULL, 
Student_Name    varchar(100) NULL, 
Course_Id    varchar(50) NULL, 
Semester     varchar(50) NULL, 
Subject_Id    varchar(50) NULL, 
Subject_Name    varchar(50) NULL, 
MarksObtained   int NULL, 
Exam_Type    varchar(50) NULL) 

INSERT into Exam_Result values(11161,'Mack','MECH',1,'MT','Maths',25,'Internal1'); 
INSERT into Exam_Result values(11161,'Mack','MECH',1,'EN','English',22,'Internal1'); 
INSERT into Exam_Result values(11161,'Mack','MECH',1,'SC','Science',20,'Internal1'); 
INSERT into Exam_Result values(11161,'MACK','MECH',1,'MT','Maths',21,'Internal2'); 
INSERT into Exam_Result values(11161,'Mack','MECH',1,'EN','English',24,'Internal2'); 
INSERT into Exam_Result values(11161,'Mack','MECH',1,'SC','Science',22,'Internal2'); 

在这里,我有两个参数传递给它想我路过GetExamResults 'MECH','2'

然后结果就这样产生......

Enroll_Number Student_Name Course_Id Semester Maths English Science **Exam_Type** total  avg 

11161   Mack   MECH   1   25  22   20  **Internal1**  67  total/all sub 
11161   Mack   MECH   1   21  24   22  **Internal2**  67  total/all sub 

但我想跟踪(通过加入第三个参数用于EXAM_TYPE)与Exam_Type。 ..并期待在结果类似.....

当用户执行GetExamResults 'MECH','1','Internal1'那么结果应该来像...

Enroll_Number Student_Name Course_Id Semester Maths English Science **Exam_Type** total  avg 

    11161   Mack   MECH   1   25  22   20  **Internal1**  67  total/all sub 

当用户执行GetExamResults 'MECH','1','Internal2'那么结果应该来像...

11161   Mack   MECH   1   21  24   22  **Internal2**  67  total/all sub 

回答

0

这里。我添加了一个可选参数@Exam_Type。如果您没有指定值或设置为null,则过程将返回所有行。 游标定义更改为包含LOCAL和FAST_FORWARD以加快执行速度。 And (@Exam_Type is null OR @Exam_Type = Exam_Type)添加到通过@Exam_Type的值筛选exam_results;如果为null,则不会发生过滤。如果@Exam_Type不为null,则将相同的筛选器添加到(select Enroll_Number, Student_Name,动态sql行。

ALTER Proc GetExamResults (@Course_Id varchar(100), @Semester varchar(10), @Exam_Type varchar(50) = null) 
as 
begin 
    declare @subjname varchar(100) 
    declare @subjects varchar(7000) 
    declare @subjectsselection varchar(7000) 
    declare @SumSelection varchar(7000) 
    declare @NoOfSubjects int 
    set @NoOfSubjects = 0 

    set @subjects = '' 
    set @subjectsselection = '' 
    set @SumSelection = '' 

    DECLARE subject_cursor CURSOR LOCAL FAST_FORWARD 
    FOR SELECT distinct Subject_Name FROM Exam_Result where course_id = @Course_Id And Semester = @Semester And (@Exam_Type is null OR @Exam_Type = Exam_Type) 

    OPEN subject_cursor 

    FETCH NEXT FROM subject_cursor 
    INTO @subjname 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     set @subjects = @subjects + '[' + @subjname + '],' 
     set @subjectsselection = @subjectsselection + 'Sum(Isnull([' + @subjname + '],0)) As [' + @subjname + '],' 
     set @SumSelection = @SumSelection + 'Sum(Isnull([' + @subjname + '],0))+' 

     set @NoOfSubjects = @NoOfSubjects + 1 

     FETCH NEXT FROM subject_cursor 
     INTO @subjname 
    End 
    CLOSE subject_cursor; 
    DEALLOCATE subject_cursor; 

    select @subjects = LEFT(@subjects, LEN(@subjects) - 1) 
    select @subjectsselection = LEFT(@subjectsselection, LEN(@subjectsselection) - 1) 
    select @SumSelection = LEFT(@SumSelection, LEN(@SumSelection) - 1) 

    print @subjects 
    print @subjectsselection 
    print @SumSelection 

    declare @query nvarchar(4000) 

    set @query = 'select S.Enroll_Number, pvt.Student_Name, pvt.Course_Id, pvt.Semester, ' + @subjectsselection + ',' 
    set @query = @query + 'Exam_Type,' + @SumSelection + ' As Grand_Total, ' 
    set @query = @query + '(' + @SumSelection + ')' + '/' + convert(varchar(10),@NoOfSubjects) + ' As Avg' 
    set @query = @query + ' From ' 
    set @query = @query + '(select Enroll_Number, Student_Name, Course_Id, Semester, Subject_Name, MarksObtained, Exam_Type from Exam_Result ' + (case when @Exam_Type is null then '' else ' Where Exam_Type =''' + @Exam_Type + '''' end) + ') ps ' 
    set @query = @query + ' pivot(sum(MarksObtained) for Subject_Name in (' + @subjects + ')) as pvt' 
    set @query = @query + ' inner join Stud_Info S on S.Enroll_Number = pvt.Enroll_Number ' 
    set @query = @query + ' where pvt.Course_Id = ''' + @Course_Id + ''' and pvt.Semester = ''' + @Semester + '''' 
    set @query = @query + ' group by S.Enroll_Number, pvt.Student_Name, pvt.Course_Id, pvt.Semester, Exam_Type' 
    print @query 
    exec sp_executesql @query 
end 
+0

尼古拉Markovinovic - 它工作得很好,而我传递的参数与** ** EXAM_TYPE但它给了错误,而不是通过第三个参数** ** EXAM_TYPE .... **错误**像**消息201,Level 16,State 4,Procedure ExamResult,Line 0 过程或函数'ExamResult'需要参数'@Exam_Type',它没有提供。 ** – mack28

+1

@ mack28你忘了在@Exam_type的参数列表中加入'= null'吗?我已经用两种方法测试过程。 –

+0

Nikola Markovinovic - 是的,我忘了添加**(@ Exam_Type为null或@Exam_Type = Exam_Type)**这一行....谢谢.. – mack28