クエリ通知の作成

クエリ通知機能は、インデックス付きビューを管理するためにデータベース エンジンで使用されている、変更検出のメカニズムに基づいています。クエリ通知のステートメントに対する要件と制限は、インデックス付きビューの要件と制限に似ています。

SET オプションの設定

通知要求で SELECT ステートメントが実行されるとき、要求を送信する接続では、接続のオプションを次のように設定する必要があります。

  • ANSI_NULLS ON

  • ANSI_PADDING ON

  • ANSI_WARNINGS ON

  • CONCAT_NULL_YIELDS_NULL ON

  • QUOTED_IDENTIFIER ON

  • NUMERIC_ROUNDABORT OFF

  • ARITHABORT ON

注意

ANSI_WARNINGS を ON に設定すると、データベース互換性レベルが 90 に設定されている場合、暗黙的に ARITHABORT が ON に設定されます。データベース互換性レベルが 80 以下に設定されている場合は、ARITHABORT オプションを明示的に ON に設定する必要があります。

ステートメントを READ_UNCOMMITTED 分離レベルまたは SNAPSHOT 分離レベルで実行しないでください。

これらのオプションまたは分離レベルが適切に設定されていない場合、SELECT ステートメントが実行された直後に通知が起動します。通知がアクティブな場合、通知を起動するコマンドを実行する接続でも、上記のように SET オプションが設定されている必要があります。これらのオプションが適切に設定されていないと、Transact-SQL エラーが発生してコマンドが失敗します。

ステートメントがストアド プロシージャに含まれている場合、ストアド プロシージャの作成時に、ANSI_NULLS オプションと QUOTED_IDENTIFIER オプションを設定する必要があります。詳細については、「SET ANSI_NULLS (Transact-SQL)」および「SET QUOTED_IDENTIFIER (Transact-SQL)」を参照してください。

通知のステートメント

通常、インデックス付きビューを作成するために使用できる任意のクエリに対して通知を要求できます。次のステートメントに対して、通知を設定できます。

  • SELECT

    SELECT 固有の要件と制限については、下記の「サポートされている SELECT ステートメント」を参照してください。SELECT ステートメントの詳細については、「SELECT (Transact-SQL)」を参照してください。

  • EXECUTE

    この場合、SQL Server では、EXECUTE ステートメント自体ではなく、EXECUTE ステートメントで実行されたコマンドに対する通知が登録されます。コマンドは、SELECT ステートメントの要件と制限を満たしている必要があります。EXECUTE ステートメントの詳細については、「EXECUTE (Transact-SQL)」を参照してください。

通知を登録するコマンドに複数のステートメントが含まれている場合、データベース エンジンによりバッチ内のステートメントごとに通知が作成されます。

サポートされている SELECT ステートメント

クエリ通知は、次の要件を満たす SELECT ステートメントでサポートされています。

  • SELECT ステートメント内で射影された列は、明示的に指定する必要があります。また、テーブル名は 2 つの部分から構成される名前で修飾する必要があります。つまり、ステートメントで参照されているすべてのテーブルは、同じデータベース内に存在している必要があります。

  • ステートメントでは、アスタリスク (*) または table_name.* 構文を使用して、列を指定することはできません。

  • ステートメントでは、名前のない列または重複した列名は使用できません。

  • ステートメントはベース テーブルを参照する必要があります。

  • ステートメントでは、計算列を含むテーブルを参照しないでください。

  • ステートメントで GROUP BY 式を使用しない限り、SELECT ステートメント内の射影された列に集計式を含めることはできません。GROUP BY 式を使用すると、選択リストに集計関数 COUNT_BIG() または SUM() を含めることができます。ただし、NULL 値が許容された列には SUM() は指定できません。ステートメントでは、HAVING、CUBE、または ROLLUP を指定できません。

  • 単純な式として使用される SELECT ステートメント内の射影された列は、複数回指定しないでください。

  • ステートメントには、PIVOT 演算子または UNPIVOT 演算子を含めないでください。

  • ステートメントには、UNION 演算子、INTERSECT 演算子、または EXCEPT 演算子を含めないでください。

  • ステートメントでは、ビューを参照しないでください。

  • ステートメントには、DISTINCT、COMPUTE や COMPUTE BY、または INTO のいずれも含めないでください。

  • ステートメントでは、サーバーのグローバル変数 (@@variable_name) を参照しないでください。

  • ステートメントでは、派生テーブル、一時テーブル、またはテーブル変数を参照しないでください。

  • ステートメントでは、他のデータベースやサーバーのテーブルまたはビューを参照しないでください。

  • ステートメントには、サブクエリ、外部結合、または自己結合を含めないでください。

  • ステートメントでは、text、ntext、および image のラージ オブジェクト型を参照しないでください。

  • ステートメントでは、CONTAINS または FREETEXT のフルテキスト述語は使用しないでください。

  • ステートメントでは、OPENROWSET および OPENQUERY などの行セット関数を使用しないでください。

  • ステートメントでは、集計関数 AVG、COUNT(*)、MAX、MIN、STDEV、STDEVP、VAR、または VARP のいずれも使用しないでください。

  • ステートメントでは、順位付け関数やウィンドウ関数などの非決定的関数を使用しないでください。

  • ステートメントには、ユーザー定義集計関数は含めないでください。

  • ステートメントでは、システム テーブル、またはカタログ ビューや動的管理ビューなどのビューを参照しないでください。

  • ステートメントには、FOR BROWSE 情報は含めないでください。

  • ステートメントでは、キューを参照しないでください。

  • ステートメントには、変更したり結果を返すことができない条件ステートメント (たとえば WHERE 1=0) を含めないでください。

  • ステートメントでは、READPAST ロック ヒントを指定できません。

  • ステートメントでは、Service Broker キューを参照しないでください。

  • ステートメントでは、シノニムを参照しないでください。

  • ステートメントには、double データ型または real データ型に基づいた比較または式を含めないでください。

  • ステートメントでは TOP 構文を使用しないでください。

バッチおよびストアド プロシージャ

バッチまたはストアド プロシージャに対するサブスクリプション要求を作成すると、そのバッチまたはストアド プロシージャ内で実行される各ステートメントに対して、別個のサブスクリプション要求が作成されます。

EXECUTE ステートメントは通知を登録せず、実行されるコマンドへ通知要求をフローします。バッチの場合、実行されるステートメントに対してコンテキストが適用され、さらに同様のルールが適用されます。

重複するサブスクリプション

アクティブなサブスクリプションの複製を送信すると、既存のサブスクリプションは、新しく指定されたタイムアウト値を使用して更新されます。重複するサブスクリプションは、次の条件を満たすサブスクリプションです。

  • クエリが同じデータベース コンテキストで同じユーザーによって送信されている。

  • 同じテンプレート、パラメーター値、通知 ID、および配信場所が使用されている。

つまり、同一内容の複数のクエリに対して通知を要求した場合、通知は 1 つだけ送信されます。これは、バッチ内で重複するクエリやストアド プロシージャ内で複数回呼び出されたクエリに当てはまります。