替代动态 SQL

Alternative to dynamic SQL

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

我遇到的问题是查询 运行 在非动态时要慢得多。具体来说,where 子句在动态查询中的速度要快得多,因为它增加了灵活性。例如,静态 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 + '

使用这样的 case 语句:

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 正确地将我引导到错误中吗?

OPTION (RECOMPILE) 添加到查询中。这将导致它在每次执行时都被重新编译,并且优化器足够聪明,可以简化和消除谓词,就像您现在正在使用动态 SQL.

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

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