替代动态 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..
我有几个使用动态 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..