【问题标题】:ssrs multivalue parameter stored proceduressrs 多值参数存储过程
【发布时间】:2018-10-31 02:56:33
【问题描述】:

我在 SSRS (2008) 中创建了一份报告,报告的数据来自 MS SQL 中的存储过程。

我想要一个多值参数(做了一百万次但没有使用 SP)

我已经根据查询创建了参数,勾选了允许多个值并修改了 SP 以使用 IN 语句(所以 IN (@Param))

它只是不能工作 SQL Server 探查器显示这正在通过

@RC=N'1,2'

如果我选择一个值,它会起作用(返回一个值)

我看过关于拆分加入的帖子,我尝试了所有这些都无济于事。

任何想法(当然很简单!!)理想情况下,我也希望能够返回 NULL(或者这要求太多了?

谢谢大家

【问题讨论】:

  • 只是想在这里了解更多,您正尝试将多个comma separated values 作为您的parameter 之一传递给您的stored procedure,这不起作用?
  • @abhishek SSRS 以我似乎无法控制的预定义格式传递参数(除了更改数据类型)@RC=N'1,2,3,4,5,如果我选择几个,可以发送 6,7,8,9'(我更喜欢 @RC='1','2','3','4' 但似乎无法完成。
  • 查看表值参数。

标签: sql-server reporting-services parameter-passing


【解决方案1】:

在你的数据库中创建这个函数:

USE [YourDatabase]
GO

/****** Object:  UserDefinedFunction [dbo].[SplitListToTable]    Script Date: 5/21/2018 8:13:29 AM ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO


--==========================================================
-- Author: Gugg
-- Created: 2015-10-06
-- Description: Converts a delimited string into a table of values.  Based heavily on code from this url:
--              https://social.msdn.microsoft.com/Forums/sqlserver/en-US/0ead7ceb-3fdd-4625-aa82-1d4195f984b1/passing-multivalue-parameter-in-stored-procedure-ssrs
-- Modification History:
--===========================================================

CREATE FUNCTION [dbo].[SplitListToTable]
    (
      @List NVARCHAR(2000) ,
      @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;



GO

然后你可以像这样解析你的参数:

SELECT *
FROM YourDatabase.dbo.YourTable
WHERE YourColumn IN(SELECT value FROM dbo.SplitListToTable(@YourParameter, ','))

【讨论】:

  • 你先生是个天才,这第一次奏效。易于遵循且易于添加到我的项目中。非常感谢。
【解决方案2】:

我感觉到你的痛苦,我们在使用带有 SP 的 SSRS 时遇到了同样的问题。您确实需要拆分要传递给存储过程的值。

在您的存储过程中期待 SQL;

 Alias.Field1 IN (@RC) 

编译成

Alias.Field1 IN ('Value1','Value2,'Value3')

但是,SSRS 会将参数值作为一个长字符串传递(MS 为什么这样做超出了我的理解),最终会变成这样

Alias.Field1 IN ('Value1,Value2,Value3')

正如您正确指出的那样,您对此的控制权为零。因此,您需要使用拆分字符串功能。 Aaron Bertrand 在SQLPerformance.com 上写了一篇很棒的博文,根据数据库的大小为您提供了每种方法的优缺点。我们使用了 SplitStrings CTE,因为它在我们大多数 DB 的大小下提供了最佳性能。

这里是函数;

CREATE FUNCTION [dbo].[fn_SplitStringsCTE]
(
   @List       NVARCHAR(MAX),
   @Delimiter  NVARCHAR(255)
)
RETURNS @Items TABLE (Item NVARCHAR(4000))
WITH SCHEMABINDING
AS
BEGIN
   DECLARE @ll INT = LEN(@List) + 1, @ld INT = LEN(@Delimiter);

   WITH a AS
   (
       SELECT
           [start] = 1,
           [end]   = COALESCE(NULLIF(CHARINDEX(@Delimiter, 
                       @List, 1), 0), @ll),
           [value] = SUBSTRING(@List, 1, 
                     COALESCE(NULLIF(CHARINDEX(@Delimiter, 
                       @List, 1), 0), @ll) - 1)
       UNION ALL
       SELECT
           [start] = CONVERT(INT, [end]) + @ld,
           [end]   = COALESCE(NULLIF(CHARINDEX(@Delimiter, 
                       @List, [end] + @ld), 0), @ll),
           [value] = SUBSTRING(@List, [end] + @ld, 
                     COALESCE(NULLIF(CHARINDEX(@Delimiter, 
                       @List, [end] + @ld), 0), @ll)-[end]-@ld)
       FROM a
       WHERE [end] < @ll
   )
   INSERT @Items SELECT [value]
   FROM a
   WHERE LEN([value]) > 0
   OPTION (MAXRECURSION 0);

   RETURN;
END
GO

这是在存储过程中实现它的方法;

AND (Alias.Field1 IN (SELECT Item FROM [dbo].[fn_SplitStringsCTE](@RC,',')))

至于将 NULL 传递给存储过程,这也是我们想要做的事情,但决定使用以下内容,然后向您的 SSRS 参数添加一个传递“所有值”的值,这是一个很好的捕获 -当我们想要返回该参数的所有值时,这一切都是为了我们,但是如果您的数据集中有 NULL,它们也需要被处理。

AND (@RC = 'All Values' OR Alias.Field1 IN (SELECT Item FROM [dbo].[fn_SplitStringsCTE](@RC,',')))

【讨论】:

  • 谢谢你的回复(和同情哈)为什么在地球上 MS 这病永远不知道。上面的 Daves 解决方案对我来说是第一次尝试。但是你这么多的时间和帮助。我知道有几篇关于这方面的文章,但我只是无法让解决方案在我的项目中发挥作用。干杯哥们
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-14
相关资源
最近更新 更多