具有多选参数的分隔符

时间:2016-12-19 09:07:39

标签: sql string csv reporting-services

我正在使用SSRS将多选参数传递给存储过程,为此我在存储过程中使用字符串拆分函数(下面的相关行)。

ALTER PROCEDURE [dbo].[GetPerformance] (
@ItemName varchar(max)
)
...

SELECT Item
INTO #ItemNames
FROM dbo.DelimitedSplit8K(@ItemName,',');

SELECT * FROM SomeTable
WHERE ItemName IN(SELECT Item FROM #ItemNames)

这很好用,直到列表中的一个项目包含逗号,然后我得不到任何结果。即:如果在我的SSRS报告中,用户选择这些项目:

Apples
Bananas
Grapes, Strawberries, and Melons
Oranges

在存储过程中,我最终得到以下结果:

Apples
Bananas
Grapes
Strawberries
and Melons
Oranges

并排除所有相关行。有没有办法更改SSRS连接多选参数使用的字符?

3 个答案:

答案 0 :(得分:1)

我认为你最好的选择是将下拉列表值中的逗号替换为其他内容,例如分号。通过在运行时对数据执行REPLACE,也可以在存储过程中处理它。这是阻力最小的路径。

填写下拉列表的SQL:

SELECT DISTINCT REPLACE(ItemName, ',', ';') AS ItemName FROM SomeTable

存储过程更改:

ALTER PROCEDURE [dbo].[GetPerformance] (
@ItemName varchar(max)
)
...
SELECT Item
INTO #ItemNames
FROM dbo.DelimitedSplit8K(@ItemName,',');

SELECT * FROM SomeTable
WHERE REPLACE(ItemName, ',', ';') IN (SELECT Item FROM #ItemNames)

或者,只需从数据中删除逗号即可。如果可以,将该类别更改为其他类别。可能不是最理想的选项,但如果您可以说服数据所有者进行更改,那么您可能不必担心更改报告。

IN子句列表中的逗号是通用的。更改SSRS中的分隔符(如果可能的话)会破坏使用IN子句但不使用存储过程的报表。

答案 1 :(得分:1)

我同意,首选使用ID。
但是有时您别无选择,只能使用逗号插入数据值本身的数据项。
在这种情况下,请考虑使用双引号之类的限定符来包装列表中的每个项目。 然后调整您的“拆分”例程以处理限定符。 所以我提供参数的代码看起来像;

Select Label = myField, Value = '"' + myField + '"' From myTable;

我的分割函数看起来像;

Create Function fn_SSRS_Split
    (@Parameters Varchar(Max), @Qualifier varchar(10))
    Returns @Result Table (Value varchar(8000))
As
Begin
    Declare @Value Varchar(Max), @Pos Int
    Declare @Search Varchar(10), @SearchLength Tinyint, @QualifierLength Tinyint;

    -- Default Delimiter and Qualifier parameters if blank or null
    Set @Delimiter          = IsNull(NullIf(@Delimiter, ''), ',');
    Set @Qualifier          = IsNull(NullIf(@Qualifier, ''), '"');
    Set @QualifierLength    = DataLength(@Qualifier)
    Set @Search             = @Qualifier + @Delimiter;
    Set @SearchLength       = Len(@Search);

    Set @Parameters         = @Parameters + @Delimiter

    Set @Pos = CharIndex(@Search, @Parameters, 1)

    While @Pos > 0 
    Begin
            Set @Value = Right(Left(@Parameters, @Pos - (@SearchLength - 1)), @Pos - ((@SearchLength - 1) * 2))
            If @Value <> ''
                Insert Into @Result (Value) Values (@Value) 
            Set @Parameters = SubString(@Parameters, @Pos + @SearchLength, DataLength(@Parameters) - @Pos - 1)
            Set @Pos = CharIndex(@Search, @Parameters, @SearchLength)
    End 
    Return
End

答案 2 :(得分:0)

我通过使用ItemID而不是名称来解决这个问题。 @R。理查德的双重/替换逗号的答案可能有效,但使用ID似乎更合乎逻辑。