【问题标题】:Table valued parameters for SSRS 2008SSRS 2008 的表值参数
【发布时间】:2013-02-27 03:53:39
【问题描述】:

我们需要生成 SSRS 报告,我们需要将多值字符串和整数参数转换为数据表并将其传递给存储过程。存储过程包含多个表类型参数。早些时候我们使用了varchar(8000),但它也超过了数据类型限制。然后我们想到引入数据表的概念。但是我们不知道如何从 SSRS 传递值。

我们在Using Table-Valued Parameters With SQL Server Reporting Services 上找到了 GruffCode 的解决方案。

该解决方案解决了我的问题,并且我们能够生成报告。但是,有时 SSRS 会返回以下两个错误:

报告处理过程中发生错误。
数据集“DSOutput”的查询执行失败。
字符串或二进制数据将被截断。声明已终止。

还有

报告处理中出现意外错误。
引发了“System.OutOfMemoryException”类型的异常。

我不确定它是在何时何地导致问题的。

【问题讨论】:

  • 第一个错误通常是类型/长度不匹配的结果。将数据库的数据类型/长度与您的预期进行比较。

标签: reporting-services ssrs-2008 table-valued-parameters


【解决方案1】:

该博客文章中概述的方法依赖于在内存中构建一个巨大的字符串,以便将所有选定的参数值加载到表值参数实例中。如果您选择大量值传递到查询中,我可能会看到它可能会导致“System.OutOfMemoryException”,同时尝试构建包含将加载参数的插入语句的字符串。

至于“字符串或二进制数据将被截断”错误,这听起来像是源自报表用来收集其数据的查询或存储过程。没有看到 t-sql 的样子,我无法说出为什么会这样,但我猜它也与选择大量参数值有关。

不幸的是,我不确定是否有解决此问题的方法,除了尝试查看是否可以找到一种方法来选择更少的参数值。这里有几个粗略的想法:

  1. 如果您遇到用户可能选择少数参数值或所有参数值的情况,那么您可以让查询简单地采用一个非常简单的布尔值,指示所有值都已被选中,而不是报告通过参数发送所有值。
  2. 您还可以考虑稍微“缩小”您的参数值,并在它们适合的情况下以某种方式将它们组合在一起。这样一来,用户就可以从较少数量的参数值中进行选择,这些参数值代表一组全部汇总的单个值。

【讨论】:

    【解决方案2】:

    我不喜欢在 SQL 语句中使用 Text 参数和 EXEC,就像您引用的文章所描述的那样,这样做会受到 SQL 注入的影响。将查询发送到 SQL 服务器时,具有多值参数的默认 SSRS 行为直接替换以逗号分隔的值列表来代替参数。这对于简单的 IN 查询很有用,但在其他地方可能不受欢迎。通过将 DataSet 上的 Parameter Value 设置为 =Join(Parameters!CustomerIDs.Value, ", ") 的表达式,可以绕过此行为。完成后,您可以使用以下 SQL 加载表变量:

    DECLARE @CustomerIDsTable TABLE (CustomerID int NOT NULL PRIMARY KEY)
    
    INSERT INTO @CustomerIDsTable (CustomerID)
    SELECT DISTINCT TextNodes.Node.value(N'.', N'int') AS CustomerID
    FROM (
        SELECT CONVERT(XML, N'<A>' + COALESCE(N'<e>' + REPLACE(@CustomerIDs, N',', N'</e><e>') + N'</e>', '') + N'</A>') AS pNode
        ) AS xmlDocs
    CROSS APPLY pNode.nodes(N'/A/e') AS TextNodes(Node)
    
    -- Do whatever with the resulting table variable, i.e.,
    EXEC rpt_CustomerTransactionSummary @StartDate, @EndDate, @CustomerIDsTable
    

    如果使用文本而不是整数,那么有几行会像这样更改:

    DECLARE @CustomerIDsTable TABLE (CustomerID nvarchar(MAX) NOT NULL PRIMARY KEY)
    
    INSERT INTO @CustomerIDsTable (CustomerID)
    SELECT DISTINCT TextNodes.Node.value(N'.', N'nvarchar(MAX)') AS CustomerID
    FROM (
        SELECT CONVERT(XML, N'<A>' + COALESCE(N'<e>' + REPLACE(@CustomerIDs, N',', N'</e><e>') + N'</e>', '') + N'</A>') AS pNode
        ) AS xmlDocs
    CROSS APPLY pNode.nodes(N'/A/e') AS TextNodes(Node)
    
    -- Do whatever with the resulting table variable, i.e.,
    EXEC rpt_CustomerTransactionSummary @StartDate, @EndDate, @CustomerIDsTable
    

    这种方法也适用于处理用户输入的逗号分隔项字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多