[轉][SQL Server] 如果想動態 In 應該怎麼寫?

來自:TONGYI Lingma
 

在 SQL Server 中,如果你需要動態生成 IN 子句來匹配一組不確定數量的值,你不能直接在預編譯的 SQL 語句中使用一個動態的列表。但你可以通過以下幾種方法實現動態 IN 查詢:

方法一:參數化查詢(適用於少量可變參數)

對於少量(通常數據庫驅動程序允許的最大參數數限制內)可變的輸入值,可以創建一個存儲過程或動態SQL語句,併爲每個可能的IN條件值傳遞一個參數。例如:

CREATE PROCEDURE GetItemsByDynamicIds
    @ids NVARCHAR(MAX)
AS
BEGIN
    DECLARE @sql NVARCHAR(MAX);

    SET @sql = N'SELECT * FROM YourTable WHERE Id IN (' + REPLACE(@ids, ',', ', ') + ')';
    -- 或者確保安全性和正確性,可以使用參數化查詢結合表值參數:
    -- SET @sql = N'SELECT * FROM YourTable WHERE Id IN (SELECT Id FROM @IdsTable)';

    EXEC sp_executesql @sql, N'@IdsTable dbo.IdsTableType READONLY', @IdsTable = @ids;
END

這裏假設有一個表值類型(比如 dbo.IdsTableType)用於存儲多個ID。

 

方法二:臨時表或表變量

如果你有一大堆值要處理,可以先將這些值插入到臨時表或表變量中,然後用這個臨時結構進行JOIN操作:

DECLARE @TempTable TABLE (Id INT);

-- 動態插入值到臨時表
INSERT INTO @TempTable (Id)
VALUES (...), (...); -- 這裏根據實際值動態插入

-- 使用臨時表進行查詢
SELECT yt.*
FROM YourTable yt
JOIN @TempTable tt ON yt.Id = tt.Id;

 

方法三:動態SQL與字符串拼接(需注意SQL注入風險)

在一些場景下,特別是當值集合從應用程序端動態獲取時,可以構建包含所有值的字符串並在運行時拼接成SQL語句執行:

DECLARE @ids NVARCHAR(MAX) = N'1, 2, 3'; -- 這個應該來自外部數據源並確保安全
DECLARE @sql NVARCHAR(MAX);

SET @sql = N'SELECT * FROM YourTable WHERE Id IN (' + @ids + ')';

EXEC sp_executesql @sql; 

請注意:這種方法存在SQL注入的風險,務必對用戶提供的任何輸入進行嚴格的驗證和清理,或者使用參數化查詢結合上述提到的表值參數的方法。

 

總結

推薦使用參數化查詢結合表值參數的方法,因爲它既能夠防止SQL注入,又能處理大量動態的輸入值。在處理動態SQL時,始終牢記SQL注入的安全問題,並儘可能採用最安全的做法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章