2013-03-11 116 views
1

我們需要從我們需要將多值字符串和整數參數轉換爲數據表並將其傳遞給存儲過程的位置生成SSRS報表。存儲過程包含多個表類型參數。之前我們使用varchar(8000),但它也跨越了數據類型限制。然後我們想引入可數據概念。但是我們並不知道如何傳遞SSRS的值。SSRS 2008表值參數

我們發現了一個來自GruffCode的解決方案Using Table-Valued Parameters With SQL Server Reporting Services

解決方案解決了我的問題,並且我們能夠生成報告。但是,有時SSRS會返回以下兩個錯誤:

報告處理期間發生錯誤。
數據集「DSOutput」的查詢執行失敗。
字符串或二進制數據將被截斷。該語句已終止。

而且

意外的錯誤發生在報表處理。
類型'System.OutOfMemoryException'的異常被拋出。

我不確定何時何地導致問題。

+1

第一個錯誤通常是由於不匹配的類型/長度造成的。比較數據庫的數據類型/長度和您的期望值。 – 2013-03-11 20:38:10

回答

1

該博客文章中概述的方法依賴於在內存中構建一個巨大的字符串,以便將所有選定的參數值加載到表值參數實例中。如果您選擇大量值傳遞到查詢中,我可能會在嘗試構建包含將加載參數的插入語句的字符串時看到它可能導致'System.OutOfMemoryException'。

至於「字符串或二進制數據會被截斷」的錯誤,聽起來好像它是源於查詢或存儲過程中的報告正在使用它來收集其數據。沒有看到t-sql看起來像什麼,我不能說爲什麼會發生這種情況,但我猜測它也與選擇大量參數值有關。

不幸的是,我不確定是否有解決方法,除了試圖找出一種方法來選擇更少的參數值。這裏有幾個粗略的想法:

  1. 如果你有一個情況,用戶可以選擇參數值的少數或所有參數值,那麼你可以讓查詢簡單地表示所有值一個很簡單的布爾值而不是讓報告通過參數發送所有的值。
  2. 您也可以考慮將參數值「縮小」一些,並將它們按照某種方式分組在一起,如果它們適合於此。這樣用戶可以從較少數量的參數值中進行選擇,這些參數值代表一組所有捲起的單個值。
0

我不喜歡在SQL語句中使用Text參數和EXEC,就像您引用的文章描述的一樣,這樣做會受到SQL注入的影響。使用多值參數的默認SSRS行爲將查詢發送到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 

這種方法也適用於處理用戶輸入的逗號分隔項目的字符串。