SQL用户函数(和性能):在多个RETURN语句中组合SELECT和IF

时间:2011-08-18 10:05:57

标签: sql sql-server-2008

我的问题的原因部分是由于性能问题。见最后的注释。

是否可以做这样的事情:

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 x,而不是select * from fn_x()。表“y”和“z”表示权限表,“@ value”表示用户ID,“@ Something1”和“@ Something2”表示外部设置。

2 个答案:

答案 0 :(得分:1)

由于语法原因,您必须使用替代方法:您只能使用内联表值函数返回一个。

就个人而言,我会说不同的JOIN意味着单独的功能......

答案 1 :(得分: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,似乎原始代码bock 3优于第2块,但上面的代码是最好的。