我有一个针对sql Server数据库运行的查询.其中一列使用STUFF()函数.
1234
当我尝试在SSRS报告中使用此查询时,SSRS会自动在STUFF()函数中放置一个列别名,从而产生如下所示的值:
<Expr1>,1</Expr1><Expr1>,2</Expr1><Expr1>,3</Expr1><Expr1>,4</Expr1>
两者之间的唯一区别是,当我在SSRS中保存查询时,会自动添加术语“AS Expr1”(请参阅下面的代码).
SELECT FirstName,LastName,CourseTitle,LastLoginDate,NoOfModules,COUNT(CourseCompleted) AS ModulesStarted,STUFF( ( SELECT ',' + CAST(CourseModule AS varchar(20)) -- SSRS puts "AS Expr1" here FROM EDSF WHERE FirstName = e.FirstName AND LastName = e.LastName AND Coursecompleted = '1' AND CourseTitle = e.CourseTitle FOR XML PATH('') ),1,'' ) AS CoursesCompleted FROM EDSF e WHERE Coursecompleted = '1' OR Coursecompleted = '0' GROUP BY FirstName,NoOfModules;
编辑:代码已重新排列,问题重新编写,以使问题更清晰.我没有对返回列本身产生别名的问题:相反,SSRS实际上是在我的STUFF()函数中向子查询添加别名,从而导致字段内的额外垃圾.
解决方法
我认为最初的注释中存在一些混淆:问题不在于为列提供别名,问题是为什么SSRS不允许STUFF()命令中的子查询在没有别名的情况下存在. XML正在解释该字段并在字段值本身中包含列名,将“1”,“2”,“3”和“4”的输入转换为(格式化为代码,因为它被解释为HTML):
"<Expr1>,4</Expr1>"
我很确定有一种方法可以告诉FOR XML忽略列名,我也很确定存储过程选项是一种更好的方法.虽然如此,有时存储过程不是一个选项,所以我将包括一种用REPLACE()去除违规值的方法
SELECT FirstName,lastlogindate,Noofmodules,COUNT(Coursecompleted) AS modulesstarted,REPLACE(REPLACE(REPLACE('<' + STUFF(( SELECT ',' + CAST(CourseModule AS varchar(20)) AS Expr1 FROM Esdf WHERE FirstName = e.FirstName AND LastName = e.LastName AND Coursecompleted = '1' AND CourseTitle = e.CourseTitle FOR XML PATH('')),'' ),'<Expr1>',''),'</Expr1>',','' ) AS CoursesCompleted FROM Esdf e WHERE Coursecompleted = '1' OR Coursecompleted = '0' GROUP BY FirstName,Noofmodules