2010-07-18 75 views
4

環境Select語句:SQL Server 2005中的SQL Server 2005:在ISNULL條件

我有收到逗號,一個參數的值分開存儲的過程。我在SQL中編寫了一個Table Value UDF函數來打破它,並將它作爲表返回給我。我正在使用該值來過濾存儲過程的where子句中的數據。一切正常,直到在傳遞給存儲過程的逗號分隔變量中有NULL。我想以這樣的方式編寫我的where子句,如果傳遞的變量是NULL,那麼它不應該使用Split函數。這是我在存儲過程中所做的。

Declare @list varchar(100), @Col2 varchar(100) 

SELECT * 
    FROM Table1 t1 
INNER JOIN dbo.Table2 t2 ON t1.Col1 = t2.Col1 
WHERE t1.Col2 = ISNULL(@Col2,t1.Col2) 
--I want to write below condition the same way i have written the above condition 
    AND t1.Col3 IN (select * from dbo.SplitMe(@list)) 

有沒有辦法編寫條件來選擇Col3選擇Col2的方式?

回答

2

如果這個想法是不是Col3如果@list是空濾,那麼你可能用同樣的方式

Declare @list varchar(100), @Col2 varchar(100) 

SELECT * 
    FROM Table1 t1 
INNER JOIN dbo.Table2 t2 
on t1.Col1 = t2.Col1 

where t1.Col2 = ISNULL(@Col2,t1.Col2) 
AND (@list IS NULL OR t1.Col3 IN (select * from dbo.SplitMe(@list))) 

,但它不會是一個好主意,除非這些表是非常小的。對於計劃緩存的原因,通常最好將所有這些排列闖入自己的SQL語句,而不是試圖寫一個一刀切的查詢或者(如果置換的數量變得太大)考慮使用動態SQL(見Dynamic Search Conditions in T-SQL

注意這保證Split函數將不會被調用。沒有保證條款評估的順序。但是這意味着如果它被調用,它將不會影響查詢的結果。 (編輯假設當然是被調用時NULL實際上並沒有造成某種錯誤C.F. Remus的評論)

+1

依賴布爾運算符在SQL中短路是非常危險的,因爲它是**不**保證:http://rusanu.com/2009/09/13/on-sql-server-boolean- operator-short-circuit/ – 2010-07-18 17:37:19

+0

這就是我一直在尋找的東西。非常感謝。截至目前,我將與此同時進行,但如果性能會下降,我會將其更改爲動態查詢以查看是否有所改進。 – Asdfg 2010-07-21 07:38:37

1

您有現在的兩個變量是相互獨立的查詢。在一個查詢中包括它們兩個會產生一個非可查詢的查詢 - 根據變量值查詢會有很大的不同,並且您使用的是昂貴的條件表達式來將它們放在一起。這是一個痛苦的維護,並表現不佳。

你可以使用IF語句:

IF 
BEGIN 

    SELECT * 
     FROM TABLE1 t1 
     JOIN TABLE2 t2 ON t2.col1 = t1.col1 
    WHERE t1.col1 = COALESCE(@col2, t1.col2) 

END 
ELSE 
BEGIN 

    SELECT * 
     FROM TABLE1 t1 
     JOIN TABLE2 t2 ON t2.col1 = t1.col1 
     WHERE t1.col2 = COALESCE(@col2, t1.col2) 
      AND t1.col3 IN (SELECT * FROM dbo.splitme(@list)) 

END 

...但仍有空處理。對於兩個變量,這是四種可能的價值結果。像這樣的情況是動態SQL的意圖 - 構建查詢是必要的,因爲拖拉行李運行不佳。

+0

我知道這是一個很好的動態SQL候選人,但我更喜歡編寫乾淨的SQL。另外參數的數量不限於2,所以我不認爲爲每個排列和組合編寫SQL都是一個好主意。糾正我,如果我錯了。 – Asdfg 2010-07-21 07:35:59

+0

@Asdfg:當你有兩個或更多個參數,可能的組合增加了通過平方的參數#:2變爲4點的可能性,3裝置9等更多的可能性,越有可能的查詢高速緩存將無益處提供小在非動態的方法。這不僅是嵌入到SQL中的OR和其他條件邏輯的影響。動態SQL *是*乾淨的SQL - 它只是實際需要運行的內容,而不是處理各種情況的所有行李。參數越多,動態SQL的執行效果就會比您選擇的答案更好。 – 2010-07-21 15:53:36

1
WHERE (t1.Col2 = @Col2 OR @Col2 IS NULL) 
AND (t1.Col3 IN (select * from dbo.SplitMe(@list)) OR @list IS NULL)