Sql-Server

如何將項目列表送出到儲存過程以限制結果?

  • December 7, 2011

可能重複:

將數組參數傳遞給儲存過程

假設您想通過唯一標識符列表過濾結果,這樣您的 SQL 語句將顯示為:

WHERE CustomerID in (@CustomerIDs)

這可能嗎?

編輯:

為了澄清和回答尼克的問題,我想將值列表從 C# 傳遞到 SQL Server,並能夠執行類似於我上面發布的 SQL 的選擇。這比獲取比需要的更多的數據並且必須搜尋它更可取,因為存在大量數據。

如果您使用的是 SQL 2008 或更高版本,則可以使用表值參數,它允許您從 .NET 端傳入基本上是數組的內容,然後使用表變數作為 Nick 所說的 in 子句。

如果您不使用 SQL 2008 或更高版本,那麼您需要將值作為 XML 文件傳遞,然後使用 xquery 或 OPENXML 解析 XML 文件並將值放入臨時表(或表變數,具體取決於您期望的許多值)。然後在 WHERE 子句中使用臨時表作為 IN 的一部分。

SQL2008 之前的替代方法是使用 CSV 拆分器。Jeff Moden 對此進行了各種方法的詳盡測試。

您的範例將變為:

DECLARE @CustomerIdList VARCHAR(8000)
SET @CustomerIdList = 
                   'F2D13066-111F-4B85-B85B-2C89F4876D06
                   ,DEF52A31-3272-4296-9C2B-3B3D7DB45BBA
                   ,981BCCF6-D1D2-4F19-B5CF-B4CC4FC6B417'

SELECT
   x, y, z
FROM
   dbo.Customer c
INNER JOIN
   dbo.DelimitedSplit8K(@CustomerIdList, ',') IdList
ON  IdList.Item = c.CustomerId

DelimitedSplit8K 函式:

CREATE FUNCTION [dbo].[DelimitedSplit8K]
       (@pString VARCHAR(8000), @pDelimiter CHAR(1))
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
 WITH E1(N) AS (
                SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
                SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
                SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
               ),                          
      E2(N) AS (SELECT 1 FROM E1 a, E1 b), 
      E4(N) AS (SELECT 1 FROM E2 a, E2 b), 
cteTally(N) AS (
                SELECT TOP (ISNULL(DATALENGTH(@pString),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
               ),
cteStart(N1) AS (
                SELECT 1 UNION ALL
                SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString,t.N,1) = @pDelimiter
               ),
cteLen(N1,L1) AS(
                SELECT s.N1,
                       ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,8000)
                  FROM cteStart s
               )
SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1),
       Item       = SUBSTRING(@pString, l.N1, l.L1)
  FROM cteLen l
;

引用自:https://dba.stackexchange.com/questions/6275