动态SQL的替代方案

时间:2017-02-10 11:37:17

标签: sql sql-server tsql sql-server-2012 dynamic-sql

我有几个使用动态SQL的存储过程。 我真的很想改变它们以使它们不动态,纯粹是因为它们可能因为错误处理而排除故障并改变它们非常烦人(点击错误信息并不能带你到错误)。我知道我可以选择文本并将其粘贴为常规SQL来帮助解决这个问题,但这非常令人沮丧。

我遇到的问题是,当查询不是动态时,查询运行得慢得多。具体来说,由于其灵活性增加,where子句在动态查询中要快得多。例如,static where子句类似于:

where
     SomeColumn = case when @variable1 = 0 then SomeColumn else @variable1 end
and(
    (@variable2 = -2 and SomeColumn2 = 1)
    or (@variable2 = -1)
    or (@variable2 = 0 and SomeColumn2 = 0 and SomeColumn3 = 0)
    or (@variable2 = 1 and SomeColumn2 = 0 and SomeColumn3 > 0)
    )

但是动态where子句将是:

where ' + @SomeCondition + @SomeCondition2 + '

使用这样的案例陈述:

declare @SomeCondition nvarchar(max) = case 
    when @variable3 = -2 then N'Condition 1'
    when @variable3 = 0 then N'Condition 2'
    when @variable3 = 1 then N'Condition 3'
    else N''
    end

我能想到的唯一解决方案是使用多个if语句,并且只更改每个语句中的where子句,但这看起来非常浪费和耗时。

动态SQL还有其他替代方法吗? 如果做不到这个问题,我能做些什么来让sql-server正确指导错误吗?

2 个答案:

答案 0 :(得分:3)

OPTION (RECOMPILE)添加到查询中。这将导致它在每次执行时重新编译,并且优化器足够智能,可以快捷方式并消除谓词,就像您现在使用动态SQL一样。

答案 1 :(得分:1)

或者,您可以使用ISNULL(NULLIF语法,如下所示。但请谨慎使用,因为它可能会对性能产生负面影响。

where
     SomeColumn = ISNULL(NULLIF(@variable1,''),SomeColumn) and
     SomeColumn2 = ISNULL(NULLIF(@variable2,''),SomeColumn2) and 
     and so on..