2011-08-18 63 views
2

我的問題的原因部分是由於性能問題。最後見注。SQL用戶函數(和性能):在多個RETURN語句中結合SELECT和IF

是否有可能做這樣的事情:

create function fn_x() 
returns table 
as 
begin 
if @Something1 
    return select distinct y.val, x.* from x join y on x.a = y.a where y.val = @val 
else if @Something2 
    return select distinct z.val, x.* from x join z on x.a = z.a where z.val = @val 
else 
    return select @val val, x.* from x 
end 

另一種方法是這樣的:

return 
      select distinct y.val, x.* from x join y on x.a = y.a where @Something1 and y.val = @val 
union all select distinct z.val, x.* from x join z on x.a = z.a where @Something2 and z.val = @val 
union all select '' val, x.* from x where not @Something1 and not @Something2 

或像這樣:

return 
    select @val val, x.* 
    from x 
    where (not @Something1 and not @Something2) 
    or  (@Something1 and exists(select * from y where x.a = y.a and y.val = @val)) 
    or  (@Something2 and exists(select * from z where x.a = z.a and z.val = @val)) 

假設 「X」是一個經常使用的非常大的桌子。我擔心的是替代方案會減慢我的查詢速度。

(我使用SQL Server 2008 R2)

編輯:爲什麼我需要一個單一的功能?該過濾器基於外部設置(可能不理想但需要)。簡而言之,該功能就是替代表格。我現在必須使用select * from fn_x(),而不是使用select * from x。表「y」和「z」代表權限表,「@val」代表用戶ID,「@ Something1」和「@ Something2」代表外部設置。

回答

1

如果有意願,有辦法:-)

create function fn_x() 
returns @x table 
(
    col1 int, 
    col2 varchar(20) 
) 
as 
begin 
    -- declare @Something1 ... 

    if @Something1 
     insert @x select ... 
    else if @Something2 
     insert @x select ... 
    else 
     insert @x select ... 
    return 
end 
go 

性能的說明:從快打電話給SET SHOWPLAN_ALL ON似乎原來的代碼塊3比塊2好,但是這個代碼是最好的。

1

由於語法,您必須使用替代方法:只能使用內聯表值函數進行返回。

就個人而言,我會說不同的連接意味着獨立的功能...

+0

由於外部設置,我需要一個功能(我更新了我的帖子來解釋)。對性能有任何想法? –