Sql-Server
如何將項目列表送出到儲存過程以限制結果?
可能重複:
假設您想通過唯一標識符列表過濾結果,這樣您的 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 ;