2014-06-27 43 views
2

我有一個存儲過程,用於搜索需要幾個可選參數。其中之一是@keywords定義爲如何在WHERE子句中使用CASE來短路CONTAINS

@keywords nvarchar(1000) = null, 

如果@keywords爲空或空字符串,我想短路,否則我需要尋找一個完整的文本索引。用看起來像這樣我的邏輯:

WHERE 
(@keywords IS NULL OR CONTAINS((Title, CrossRef, company_name), @keywords)) 
AND 
-- other search terms 

然而,我剛發現,或者不能保證短路,所以有時這會返回一個錯誤「空全文謂詞。」顯然CASE應該保證短路,但某些版本的SQL服務器有一個錯誤,但情況並非如此。

這裏就是我想:

WHERE 
(1 = CASE 
    WHEN @keywords IS NULL THEN 1 
    WHEN @keywords = '""' THEN 1 
    ELSE (CASE WHEN CONTAINS((Title, CrossRef, company_name), @keywords) THEN 1 ELSE 0 END) 
) 
AND 
-- other search terms 

這仍然給出了「空全文謂詞」錯誤。我很樂意將@keywords替換爲永遠匹配的內容,但我不知道該怎麼做。

回答

0

既然你已經使用了SP,爲什麼不把它扔到IF THEN ELSE模塊來實現你的短路邏輯。不僅會更容易閱讀,而且優化器也會更好地閱讀。

+0

據我所知,我不能只是把一部分的WHERE子句放在IF語句中。我必須將整個查詢放入,這意味着重複查詢的其餘部分。儘管這可能是最好的解決方案。 – RyanB

+0

您需要將查詢的一個迭代放在IF塊中,而另一個迭代放在ELSE中。基本上你必須用兩種不同的方式編寫查詢語句,IF將評估@keywords爲NULL或空。如果是,請使用您的捷徑邏輯。如果不是,不要。無論哪種情況,您最終都會得到一個針對該條件的量身定製的SQL語句。 –

0

這是我最終做的。在SP的頂部:

DECLARE @fix_keywords nvarchar(1000) 
SET @fix_keywords = @keywords 
IF @keywords IS NULL OR @keywords = '' SET @fix_keywords = 'zqxvMatchNothing321' 

然後

WHERE 
(@keywords IS NULL OR @keywords = '' OR CONTAINS((Title, CrossRef, company_name), @fix_keywords)) 
AND 
-- other search terms 

我意識到這是一個有點哈克,但我認爲這是我的情況下,最好的解決辦法,因爲我沒有複製IF/ELSE中的整個查詢。

另一種可能的解決方案是使用動態SQL。