2010-11-29 43 views
1

我有接收用於動態過濾結果集或通過對於每個參數可以爲0(對所有項目)SQL數據過濾方法

create proc MyProc 
@Parameter1 int, 
@Parameter2 int, 
@Paremeter3 int 
as 
select * from My_table 
where 
1 = case when @Parameter1 = 0 then 1 when @Parameter1 = Column1 then 1 else 0 end 
and 
1 = case when @Parameter2 = 0 then 1 when @Parameter2 = Column2 then 1 else 0 end 
and 
1 = case when @Parameter3 = 0 then 1 when @Parameter3 = Column3 then 1 else 0 end 
return 

的值非零3個參數的存儲過程用於匹配特定列的項目。

我可能有20個以上的參數(示例中只有3個)。有一種更優雅的方法可以在數據庫變大時擴展嗎?

+2

看看Gail Shaw的博客文章[Catch-all queries](http://sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries/)。 – 2010-11-29 20:48:28

回答

0

我使用類似於你的想法的東西:

select * 
from TableA 
where 
    (@Param1 is null or Column1 = @Param1) 
    AND (@Param2 is null or Column2 = @Param2) 
    AND (@Param3 is null or Column3 = @Param3) 

它通常是相同的,但我用空值中性值,而不是0。它是在一定意義上更靈活,它並不重要什麼是@Param變量的數據類型。

+1

我對原始問題的評論也適用於此。看看Gail Shaw在[Catch-all queries]上的博客文章(http://sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries/)。 – 2010-11-29 21:57:50

+0

所以動態查詢是最好的選擇。表現明智。 – skajfes 2010-11-29 22:10:27

0

我使用一種稍微不同的方法,以上列出的一些,我沒有注意到任何性能影響。而不是傳遞0爲沒有過濾器,我會使用null,我會強制它成爲參數的默認值。

由於我們給出參數的默認值,所以它們使它們成爲可選的,這使得它在調用過程時具有更好的可讀性。

create proc myProc 
    @Parameter1 int = null, 
    @Parameter2 int = null, 
    @Paremeter3 int = null 
AS 
select 
    * 
from 
    TableA 
where 
    column1 = coalesce(@Parameter1,column1) 
    and 
    column2 = coalesce(@Parameter2, column2) 
    and 
    column3 = coalesce(@Parameter3,column3) 

這就是說我可以下一次很好嘗試動態SQL方法,看看我是否發現任何性能差異

0

不幸的是動態SQL是最好的解決方案的性能/穩定性明智的。雖然所有其他常用的方法(@param is not or Col = @paramCOALESCE,CASE ...)都能正常工作,但它們是不可預測且不可靠的,執行計劃可能(並且會因)每次執行而有所不同,並且您可能會花費大量時間試圖弄清楚,爲什麼你的查詢在昨天工作正常時執行得非常糟糕。