我的报告在查询中使用了两个多值参数。
@garageId 和 @createdYear 都设置为多值参数,默认值为零(0)。
如果我在SQL Server Management Studio中运行它,如下所示,我会得到预期的结果。
declare @garageId int = 121212;
declare @createdYear int = 0;
SELECT DISTINCT(ml.methodID) methodID, methodTitle
FROM methodList ml
INNER JOIN methodChallenge mc ON ml.methodID = mc.methodID
WHERE type = 1
AND (mc.garageId IN(@garageId) OR @garageId IN(0))
AND (ml.createdYear IN (@createdYear) OR @createdYear IN(0))
ORDER BY methodTitle
但是,我通过SSRS interace,并从每个参数列中选择多个值,我收到此错误:
“在上下文中指定的非布尔类型的表达式 条件是预期的,靠近','。“
如果我只从每个参数列中选择一行,它可以正常工作,但我需要能够选择多行。
如何正确格式化查询以接受多值参数之间的所有可能选择?
谢谢!
答案 0 :(得分:1)
SSRS在运行查询时将多值参数转换为项目列表。
如果@garageId = 1, 2, 3
和@createdYear = 2015, 2016
那么您的 WHERE 条件:
WHERE type = 1
AND (mc.garageId IN(@garageId) OR @garageId IN(0))
AND (ml.createdYear IN (@createdYear) OR @createdYear IN(0))
将转换为
WHERE type = 1
AND (mc.garageId IN(1, 2, 3) OR 1, 2, 3 IN (0))
AND (ml.createdYear IN (2015, 2016) OR 2015, 2016 IN (0))
由于逗号,1, 2, 3 IN (0)
和2015, 2016 IN (0)
都会出错。
像
一样重做WHERE type = 1
AND (mc.garageId IN (@garageId) OR 0 IN (@garageId))
AND (ml.createdYear IN (@createdYear) OR 0 IN (@createdYear))
转换为:
WHERE type = 1
AND (mc.garageId IN (1, 2, 3) OR 0 IN (1, 2, 3))
AND (ml.createdYear IN (2015, 2016) OR 0 IN (2015, 2016))
答案 1 :(得分:1)
如果您没有在存储过程中使用它,那么您的查询将正常工作。您应该创建一个函数来解析多值参数中的每个值。
我使用这个功能。你也可以使用它。
CREATE FUNCTION [dbo].[FnSplit]
(
@List nvarchar(MAX),
@SplitOn nvarchar(5)
)
RETURNS @RtnValue table
(
Id int identity(1,1),
Value nvarchar(100)
)
AS
BEGIN
While (Charindex(@SplitOn,@List)>0)
Begin
Insert Into @RtnValue (value)
Select
Value = ltrim(rtrim(Substring(@List,1,Charindex(@SplitOn,@List)-1)))
Set @List = Substring(@List,Charindex(@SplitOn,@List)+len(@SplitOn),len(@List))
End
Insert Into @RtnValue (Value)
Select Value = ltrim(rtrim(@List))
Return
END
该函数的作用是将字符串的值拆分为行。
示例:
DECLARE @TEST NVARCHAR(255) = 'value1,value2,value3'
SELECT VALUE FROM [dbo].[FnSplit](@TEST,',')
输出将是:
VALUE
1 value1
2 value2
3 value3
然后从数据集的SQL查询中,您应该将where子句更改为此。
AND (mc.garageId IN(SELECT VALUE FROM dbo.FnSplit(@garageId,',')) OR @garageId IN(0))
AND (ml.createdYear IN (SELECT VALUE FROM dbo.FnSplit(@createdYear)) OR @createdYear IN(0))