4

次のようなストアド プロシージャがあります。

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 句を有効にするにはどうすればよいですか? 助けてくれてありがとう。

4

4 に答える 4

6
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 以外の場合、列の条件が評価されます。

于 2008-09-30T10:44:57.073 に答える
3

この方法は、クエリ オプティマイザを混乱させる傾向があります。私は、SQL Server 2000 がまったく逆の方法で実行計画を構築し、フラグが設定されているときに Column1 のインデックスを使用するのを見てきました。SQL Server 2005 は、少なくとも最初のコンパイルでは正しい実行計画を取得しているように見えましたが、新しい問題が発生しました。システムは、コンパイルされた実行計画をキャッシュし、それらを再利用しようとします。最初にクエリを 1 つの方法で使用すると、追加のパラメーターが変更されても、その方法でクエリが実行され、別のインデックスがより適切になります。

WITH RECOMPILEステートメントで使用するか、EXECステートメントで指定することにより、この実行時WITH RECOMPILEにストアド プロシージャを強制的に再コンパイルすることができますCREATE PROCEDURE。SQL Server が毎回クエリを再解析して最適化するため、ペナルティが発生します。

一般に、クエリの形式が変更される場合は、パラメーターを使用して動的 SQL 生成を使用します。SQL Server は、パラメーター化されたクエリと自動パラメーター化されたクエリ (どの引数がパラメーターであるかを推測しようとする場合)、さらには通常のクエリの実行計画もキャッシュしますが、ストアド プロシージャの実行計画に最も重点を置き、次にパラメーター化、自動パラメーター化、および通常のクエリをこの順序で実行します。重みが高いほど、サーバーが別の目的でメモリを必要とする場合に、プランが破棄されるまでに RAM に長く留まることができます。

于 2008-09-30T12:06:04.227 に答える
1
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)
于 2008-09-30T10:44:32.627 に答える
0
select *
from SomeTable t
where t.Column1 is null
and (@AdditionalFilter = 0 or t.Column2 is not null)
于 2008-09-30T10:44:54.217 に答える