【问题标题】:Stored procedure bit parameter activating additional where clause to check for null存储过程位参数激活附加 where 子句以检查 null
【发布时间】:2010-09-14 05:32:47
【问题描述】:

我有一个如下所示的存储过程:

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 子句?感谢您的帮助。

【问题讨论】:

    标签: sql stored-procedures


    【解决方案1】:

    这种做法往往会混淆查询优化器。我已经看到 SQL Server 2000 以完全相反的方式构建执行计划,并在设置标志时在 Column1 上使用索引,反之亦然。 SQL Server 2005 似乎至少在第一次编译时就获得了正确的执行计划,但是你遇到了一个新问题。系统缓存已编译的执行计划并尝试重用它们。如果您首先以一种方式使用查询,即使额外的参数发生变化,它仍然会以这种方式执行查询,并且不同的索引会更合适。

    您可以通过在EXEC 语句中使用WITH RECOMPILE 或每次通过在CREATE PROCEDURE 语句中指定WITH RECOMPILE 来强制重新编译存储过程。 SQL Server 每次都会重新解析和优化查询,因此会受到惩罚。

    一般来说,如果您的查询形式要改变,请使用带参数的动态 SQL 生成。 SQL Server 还将缓存参数化查询和自动参数化查询(它试图推断哪些参数是参数)甚至常规查询的执行计划,但它最重视存储过程执行计划,然后是参数化、自动参数化和按该顺序进行常规查询。权重越高,如果服务器需要内存来做其他事情,它在计划被丢弃之前在 RAM 中停留的时间就越长。

    【讨论】:

      【解决方案2】:
      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,则将评估列条件。

      【讨论】:

        【解决方案3】:
        select *
        from SomeTable t
        where t.Column1 is null
        and (@AdditionalFilter = 0 or t.Column2 is not null)
        

        【讨论】:

          【解决方案4】:
          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)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-04-05
            • 1970-01-01
            • 2011-11-22
            • 2011-02-08
            • 1970-01-01
            • 2010-12-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多