[英]Parameterized WHERE clause in SQL Server Stored Procedure
我有一個存儲過程來獲取發票的詳細信息
有些情況下,我只通過發送InvoiceID獲得發票清單。但在其他一些場合,我需要根據用戶提供的搜索字段獲取發票清單。 為此,我將所有字段發送到存儲過程並使用以下參數。 我只包括2列,但還有更多。
SELECT * FROM INVOICES I
WHERE
(@InvoiceNumber is null or I.InvoiceNumber = @InvoiceNumber)
and
(@PONo is null or I.PONo = @PONo)
有沒有辦法將WHERE子句的條件作為一個參數發送?
是的,可以使用Dynamic SQL,但我非常不鼓勵這樣做。
SELECT * FROM tbl WHERE @condition :
如果您正在考慮編寫該程序
CREATE PROCEDURE search_sp @condition varchar(8000) AS SELECT * FROM tbl WHERE @condition
把它忘了吧。 如果您這樣做,您還沒有完成使用存儲過程的轉換,並且您仍然在客戶端中組裝SQL代碼。
它還將打開您的SQL注入攻擊應用程序。
您可以使用自定義類型將表作為參數https://msdn.microsoft.com/pl-pl/library/bb510489(v=sql.110).aspx傳遞,或者您可以使用默認參數
如果您正在使用SQL Server 2016或類似的(通過調用select compatibility_level, name from sys.databases
並查看您的數據庫是130或更高),那么您可以使用string_split內置函數。
我覺得這樣做效果最好(為了清晰起見)
CREATE PROCEDURE [dbo].[GetInvoices]
@InvoiceNumber int = NULL
@PONo nvarchar(1024) = NULL
AS
SELECT * from [Invoices] AS [i]
WHERE
i.InvoiceNumber = ISNULL(@InvoiceNunber, i.InvoiceNunber)
AND CASE
WHEN @PONo is null
THEN 1
ELSE (CASE
WHEN i.PONo IN (select value from string_split(@PONo, ','))
THEN 1
ELSE 0
END)
END
= 1
因此,如果將null傳遞給任一參數,則將其轉換為where x = x
,其始終為true,如果傳入CSV值,則會從值的拆分表中選擇它,如果存在,則會導致子句是where 1=1
,如果輸入列表中不存在該值,則為0=1
或0=1
。
因此,您可以在此處傳遞發票編號或采購訂單編號,或兩者兼而有之,或者既不會返回您期望的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.