2013-03-11 6 views
1

У нас есть требование генерации отчетов SSRS, где нам нужно преобразовать многозначные строковые и целочисленные параметры в datatable и передать их хранимой процедуре. Хранимая процедура содержит несколько параметров типа таблицы. Раньше мы использовали varchar(8000), но он также пересекал предел типа данных. Затем мы подумали ввести понятное понятие. Но мы не знали, как передавать значения из SSRS.Табличные параметры для SSRS 2008

Мы нашли решение от GruffCode по адресу Using Table-Valued Parameters With SQL Server Reporting Services.

Решение решило мою проблему, и мы можем создавать отчеты. Однако иногда SSRS возвращает две следующие ошибки:

Произошла ошибка во время обработки отчета.
Выполнение запроса не выполнено для набора данных DSOutput.
Строковые или двоичные данные будут усечены. Заявление было прекращено.

И

непредвиденная ошибка в обработке отчета.
Исключение типа 'System.OutOfMemoryException' было выбрано.

Я не уверен, когда и где это вызывает проблему.

+1

Первая ошибка часто является результатом несогласованных типов/длин. Сравните тип данных/длину вашей базы данных с тем, что вы ожидаете. –

ответ

1

Подход, описанный в этом блоге, основан на создании огромной строки в памяти, чтобы загрузить все выбранные значения параметров в экземпляр параметра таблицы. Если вы выбираете очень большое количество значений для передачи в запрос, я вижу, что это потенциально вызывает «System.OutOfMemoryException» при попытке построить строку, содержащую инструкции insert, которые будут загружать параметр.

Что касается ошибки «строка или двоичные данные, которая была бы усечена», которая звучит так, как будто она возникает в запросе или хранимой процедуре, которую отчет использует для сбора своих данных. Не видя, как выглядит этот t-sql, я не мог сказать, почему это происходит, но я бы предположил, что это также связано с выбором очень большого числа значений параметров.

К сожалению, я не уверен, что для этого есть обходной путь, за исключением того, что вы пытаетесь выяснить, можете ли вы выбрать способ выбора меньшего количества значений параметров. Вот несколько грубых идеи:

  1. Если у Вас есть ситуация, где пользователи могут выбрать несколько значений параметров или значения всех параметров то вы могли бы запрос просто взять очень простое логическое значение, указывающее, что все значения были выбраны вместо того, чтобы сделать отчет отправлением всех значений через параметр.
  2. Вы также можете немного «изменить масштаб» значений параметров и объединить их вместе, если они поддаются этому. Таким образом, пользователи будут выбирать из меньшего количества значений параметров, которые представляют собой группу отдельных значений, все свернутые.
0

Я не являюсь поклонником использования текстового параметра и EXEC в выражении SQL, как описано в статье, на которую ссылается, поскольку это зависит от SQL-инъекции. Поведение SSRS по умолчанию с параметром Multi-value заменяет список значений, разделенных запятыми, непосредственно вместо параметра, когда запрос отправляется на SQL-сервер.Это отлично работает для простых запросов IN, но может быть нежелательным в других местах. Это поведение можно обойти, установив значение параметра в DataSet на выражение =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 

Этот подход также хорошо подходит для обработки введенных пользователем строк разделенных запятыми элементов.

Смежные вопросы