存储过程位参数激活添加的where子句以检查是否为空
时间:2020-03-06 14:55:01 来源:igfitidea点击:
我有一个看起来像的存储过程:
CREATE PROCEDURE dbo.usp_TestFilter @AdditionalFilter BIT = 1 AS SELECT * FROM dbo.SomeTable T WHERE T.Column1 IS NOT NULL AND CASE WHEN @AdditionalFilter = 1 THEN T.Column2 IS NOT NULL
不用说,这是行不通的。如何激活检查@AdditionalFilter参数的其他where子句?谢谢你的帮助。
解决方案
CREATE PROCEDURE dbo.usp_TestFilter @AdditionalFilter BIT = 1 AS SELECT * FROM dbo.SomeTable T WHERE T.Column1 IS NOT NULL AND (NOT @AdditionalFilter OR T.Column2 IS NOT NULL)
select * from SomeTable t where t.Column1 is null and (@AdditionalFilter = 0 or t.Column2 is not null)
CREATE PROCEDURE dbo.usp_TestFilter @AdditionalFilter BIT = 1 AS SELECT * FROM dbo.SomeTable T WHERE T.Column1 IS NOT NULL AND (@AdditionalFilter = 0 OR T.Column2 IS NOT NULL)
如果@AdditionalFilter为0,则不会评估该列,因为它不会影响括号之间零件的结果。如果它不是0,则将评估列条件。
这种做法往往会混淆查询优化器。我已经看到SQL Server 2000完全以相反的方式构建执行计划,并在设置标志时在Column1上使用索引,反之亦然。 SQL Server 2005似乎至少在第一次编译时就制定了正确的执行计划,但随后又出现了一个新问题。系统缓存已编译的执行计划,然后尝试重用它们。如果我们首先以一种方式使用查询,即使额外的参数发生了变化,它仍然会以这种方式执行查询,并且不同的索引会更合适。
我们可以通过在EXC语句中使用WITH RECOMPILE来强制执行此存储过程的重新编译,或者每次在CREATE PROCEDURE语句中指定WITH RECOMPILE来强制重新编译存储过程。由于SQL Server每次都会重新解析和优化查询,因此会产生损失。
通常,如果查询的形式要更改,请使用带有参数的动态SQL生成。 SQL Server还将缓存参数化查询和自动参数化查询的执行计划(尝试推导哪些自变量是参数),甚至常规查询,但它最重视存储过程执行计划,然后进行参数化,自动参数化和按此顺序进行常规查询。如果服务器需要内存用于其他目的,权重越高,在放弃计划之前它在RAM中的停留时间就越长。