sql PIVOT中的条件

时间:2014-01-06 09:17:36

标签: sql-server pivot pivotviewer

我在跟踪SQL查询时遇到问题.. 当我在没有where条件的情况下执行此查询时它工作正常...但是当我使用where条件时它不起作用..它给出以下错误消息..

'Msg 137,Level 15,State 2,Line 4 必须声明标量变量“@ courseid1”。'

ALTER PROCEDURE [dbo].[SP_Attendance]
    @courseid as int=null, @subjid int=null
AS

Declare @colList varchar(max)
Declare @qry varchar(max)

Declare @courseid1 as int=@courseid, 
@subjid1 int=@subjid

SET @colList = STUFF((SELECT distinct ',' + QUOTENAME(SA.Attend_Date)
            FROM Student_Attendance_Sheet SA
            FOR XML PATH(''), TYPE
            ).value('/', 'NVARCHAR(MAX)') 
        ,1,1,'')

SET @qry = 'SELECT Roll_No, EnrollmentNo, STUD_FNAME + STUD_MNAME + STUD_LNAME as [Student Name] , '+@colList+'
FROM (
    select SA.Roll_No, SA.Attend_Date, SA.Attendance from Student_Attendance_Sheet SA
    where (SA.Course_ID = +@courseid1+) and (SA.Subject_ID =  +@subjid1+) 
) as s
PIVOT
(
    MAX(Attendance)
    FOR Attend_Date IN (' + @colList + ')
) pvt '
print(@qry)
Exec(@qry)

执行SP_Attendance 2,3

还有一件事......当我在

中使用条件时
SET @colList = STUFF((SELECT distinct ',' + QUOTENAME(SA.Attend_Date)
            FROM Student_Attendance_Sheet SA
where (SA.Course_ID = +@courseid1+) and (SA.Subject_ID =  +@subjid1+) 
            FOR XML PATH(''), TYPE
            ).value('/', 'NVARCHAR(MAX)') 
        ,1,1,'')

它有效,但没有过滤..所以我必须使用上述方式的条件... 请帮我解决这个问题...谢谢

2 个答案:

答案 0 :(得分:0)

现有查询的问题是您的变量@courseid1@subjid1未在动态SQL中定义,因此它们超出了范围。

解决这个问题的一种方法是将变量的字符串值连接到sql字符串:

SET @qry 
  = 'SELECT Roll_No, EnrollmentNo, 
      STUD_FNAME + STUD_MNAME + STUD_LNAME as [Student Name] , '+@colList+'
     FROM 
     (
        select SA.Roll_No, SA.Attend_Date, SA.Attendance 
        from Student_Attendance_Sheet SA
        where (SA.Course_ID = '+cast(@courseid1 as varchar(50))+ ') 
          and (SA.Subject_ID = '+cast(@subjid1 as varchar(50))+ ') 
     ) as s
    PIVOT
    (
        MAX(Attendance)
        FOR Attend_Date IN (' + @colList + ')
    ) pvt '
print(@qry)
Exec(@qry)

编写上述查询的另一种方法是sp_executesql,您将传入参数值:

DECLARE @ParmDefinition nvarchar(500);
SET @ParmDefinition = N'@courseid1 int, @subjid1 int';


SET @qry 
  = 'SELECT Roll_No, EnrollmentNo, 
      STUD_FNAME + STUD_MNAME + STUD_LNAME as [Student Name] , '+@colList+'
     FROM 
     (
        select SA.Roll_No, SA.Attend_Date, SA.Attendance 
        from Student_Attendance_Sheet SA
        where (SA.Course_ID = @courseid1) 
          and (SA.Subject_ID = @subjid1) 
     ) as s
    PIVOT
    (
        MAX(Attendance)
        FOR Attend_Date IN (' + @colList + ')
    ) pvt '

EXECUTE sp_executesql @qry, 
  @ParmDefinition, 
  @courseid1 = @courseid,
  @subjid1 = @subjid;

至于WHERE子句的第二个问题,您应该编写查询以生成类似于以下内容的名称列表:

SET @colList 
    = STUFF((SELECT distinct ',' + QUOTENAME(SA.Attend_Date)
             FROM Student_Attendance_Sheet SA
             where (SA.Course_ID = @courseid1) 
               and (SA.Subject_ID = @subjid1) 
            FOR XML PATH(''), TYPE
            ).value('/', 'NVARCHAR(MAX)') 
        ,1,1,'')

答案 1 :(得分:0)

我建议你..不要不必要地创建更多变量..它会占用你的内存空间 你只需要......

ALTER PROCEDURE [dbo].[SP_Attendance]
    @courseid as int=null, @subjid int=null
AS

Declare @colList varchar(max)
Declare @qry varchar(max)

SET @colList = STUFF((SELECT distinct ',' + QUOTENAME(SA.Attend_Date)
            FROM Student_Attendance_Sheet SA
            where Course_ID= @courseid AND Subject_ID = @subjid
            FOR XML PATH(''), TYPE
            ).value('/', 'NVARCHAR(MAX)') 
        ,1,1,'')

SET @qry = 'SELECT Roll_No, EnrollmentNo, STUD_FNAME + STUD_MNAME + STUD_LNAME as [Student Name] , '+@colList+'
FROM (
    select Roll_No, EnrollmentNo, STUD_FNAME, STUD_MNAME, STUD_LNAME, Attend_Date, Attendance from Student_Attendance_Sheet
    where (Course_ID = '+cast(@courseid as varchar(50))+ ') and (Subject_ID =  '+cast(@subjid as varchar(50))+ ') 
) as s
PIVOT
(
    MAX(Attendance)
    FOR Attend_Date IN (' + @colList + ')
) pvt '
print(@qry)
Exec(@qry)

试试这个..