2

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

我们从 GruffCode 中找到了使用 SQL Server Reporting Services 使用表值参数的解决方案。

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

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

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

我不确定它何时何地导致了这个问题。

4

2 回答 2

2

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

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

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

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

我不喜欢在 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

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

于 2015-06-26T22:31:16.173 回答