WMI Provider for Server イベントで WQL を使用する

適用対象: SQL サーバー

管理アプリケーションは、WMI クエリ言語 (WQL) ステートメントを発行して、WMI Provider for Server イベントを使用して SQL Server イベントにアクセスします。 WQL は、WMI 特有の拡張機能を複数持つ、構造化照会言語 (SQL) の単純化されたサブセットです。 WQL を使用する場合、アプリケーションは SQL Server、データベース、またはデータベース オブジェクトの特定のインスタンスに対してイベントの種類を取得します (現在サポートされているオブジェクトはキューのみです)。 WMI Provider for Server Events は、データベース スコープまたはオブジェクト スコープのイベント通知の場合はターゲット データベースで作成されるイベント通知に、サーバー スコープのイベント通知の場合は master データベースに作成されるイベント通知にクエリを変換します。

たとえば、次の WQL クエリを考えてみましょう。

SELECT * FROM DDL_DATABASE_LEVEL_EVENTS WHERE DatabaseName = 'AdventureWorks2022'

このクエリから、WMI プロバイダーは、このイベント通知と同等のものをターゲット サーバー上に生成しようとします。

USE AdventureWorks2022;
GO

CREATE EVENT NOTIFICATION SQLWEP_76CF38C1_18BB_42DD_A7DC_C8820155B0E9
    ON DATABASE
    WITH FAN_IN
    FOR DDL_DATABASE_LEVEL_EVENTS
    TO SERVICE
        'SQL/Notifications/ProcessWMIEventProviderNotification/v1.0',
        'A7E5521A-1CA6-4741-865D-826F804E5135';
GO

WQL クエリ (FROM) の DDL_DATABASE_LEVEL_EVENTS 句の引数には、イベント通知を作成できる有効なイベントを指定することができます。 SELECT 句および WHERE 句の引数は、イベントまたはその親イベントに関連付けられたイベント プロパティを指定することができます。 有効なイベントとイベントのプロパティの一覧については、「Event Notifications (データベース エンジン)」を参照してください。

次の WQL 構文は、WMI Provider for Server Events によって明示的にサポートされます。 追加の WQL 構文を指定することもできますが、このプロバイダーに固有ではなく、WMI ホスト サービスによって解析されます。 WMI Query Language の詳細については、Microsoft Developer Network (MSDN) の WQL のドキュメントを参照してください。

構文

SELECT { event_property [ , ...n ] | * }
FROM event_type
WHERE where_condition
[ ; ]

引数

event_property [ , ...n ] |*

イベントのプロパティ。 例には、PostTimeSPID、および LoginName が含まれています。 WMI Provider for Server Events のクラスとプロパティに関するページに記載されている各イベントを検索してどのプロパティを保持するかを確認します。 たとえば、DDL_DATABASE_LEVEL_EVENTS イベントには、DatabaseName プロパティおよび UserName プロパティがあります。 また、親イベントから SQLInstance プロパティ、LoginName プロパティ、PostTime プロパティ、SPID プロパティ、および ComputerName プロパティを継承しています。

  • ...n

    event_propertyをコンマで区切って複数回照会できることを示します。

  • *

    イベントに関連付けられたすべてのプロパティを照会することを指定します。

event_type

イベント通知を作成できるイベント。 使用可能なイベントの一覧については、「 WMI Provider for Server Events のクラスとプロパティを参照してください。 イベントの種類名前は、CREATE EVENT NOTIFICATIONを使用してイベント通知を手動で作成するときに指定できるのと同じevent_type | event_groupに対応します。 イベントの種類の例CREATE_TABLELOCK_DEADLOCKDDL_USER_EVENTSTRC_DATABASEなどがあります。

Note

DDL に似た操作を実行する一部のシステム ストアド プロシージャもイベント通知を起動することができます。 イベント通知はテストして、実行されているシステム ストアド プロシージャに応答するかどうか、確認してください。 たとえば、 CREATE TYPE ステートメントとストアド プロシージャ sp_addtype 両方が、 CREATE_TYPE イベントに対して作成されたイベント通知を発生します。 ただし、 sp_rename ストアド プロシージャはイベント通知を発生しません。 詳細については、「 DDL イベント」を参照してください。

where_condition

event_property名と論理演算子と比較演算子で構成されるWHERE句クエリ述語。 where_conditionは、対応するイベント通知がターゲット データベースに登録されるスコープを決定します。 また、 event_type. のクエリの対象となる特定のスキーマまたはオブジェクトを対象とするフィルターとして機能することもできます。詳細については、「 Remarks 」セクションを参照してください。

DatabaseNameSchemaName、および ObjectName と共に使用できるのは、= オペランドのみです。 他の式は、これらのイベント プロパティでは使用できません。

解説

WMI Provider for Server Events 構文の where_condition によって、次の内容が決まります。

  • プロバイダーが指定した event_type (サーバー レベル、データベース レベル、またはオブジェクト レベル) を取得しようとするスコープ (現在サポートされているオブジェクトはキューだけです)。 最終的に、このスコープは対象データベースで作成されたイベント通知の種類を決定します。 このプロセスは、イベント通知登録と呼ばれます。

  • データベース、スキーマ、オブジェクトのうちの適切な登録場所。

WMI Provider for Server Events は、基になる EVENT NOTIFICATIONに対して可能な限り狭いスコープを生成するために、ボトムアップの優先適合アルゴリズムを使用します。 このアルゴリズムは、SQL Server のインスタンスと WMI ホスト プロセスの間のサーバーとネットワーク トラフィックの内部アクティビティを最小限に抑えようとします。 プロバイダーは、FROM句で指定されたevent_typeWHERE句の条件を調べ、基になるEVENT NOTIFICATIONを可能な限り狭いスコープで登録しようとします。 プロバイダーが最も狭いスコープで登録できない場合は、登録が最終的に成功するまで、連続して上位のスコープで登録を試みます。 最も高いスコープ (サーバーレベル) に到達して失敗した場合、エラーがコンシューマーに返されます。

たとえば、 DatabaseName='AdventureWorks2022'WHERE 句で指定されている場合、プロバイダーはイベント通知を AdventureWorks2022 データベースに登録しようとします。 AdventureWorks2022 データベースが存在し、呼び出し側クライアントが、AdventureWorks2022 のイベント通知を作成するために必要な権限を持っている場合、登録は正常に完了します。 それ以外の場合は、イベント通知をサーバー レベルで登録しようとします。 WMI クライアントが必要な権限を持っている場合、登録は正常に終了します。 ただし、このシナリオでは、 AdventureWorks2022 データベースが作成されるまで、イベントはクライアントに返されません。

where_conditionはフィルターとして機能して、クエリを特定のデータベース、スキーマ、またはオブジェクトに制限することもできます。 たとえば、次の WQL クエリを考えてみましょう。

SELECT * FROM ALTER_TABLE
WHERE DatabaseName = 'AdventureWorks2022' AND SchemaName = 'Sales'
    AND ObjectType='Table' AND ObjectName = 'SalesOrderDetail'

登録プロセスの結果によっては、この WQL クエリがデータベース レベルまたはサーバー レベルで登録される場合があります。 ただし、サーバー レベルで登録されている場合でも、プロバイダーは最終的に、Sales.SalesOrderDetail テーブルに適用されないALTER_TABLE イベントをフィルター処理します。 つまり、プロバイダーは、この特定のテーブル上で発生した ALTER_TABLE イベントのプロパティのみを返します。

DatabaseName='AW1' OR DatabaseName='AW2'などの複合式を指定すると、2 つの個別のイベント通知ではなく、サーバー スコープで 1 つのイベント通知を登録しようとします。 呼び出し側クライアントが権限を持っている場合、登録は正常に終了します。

WHERE句でSchemaName='X' AND ObjectType='Y' AND ObjectName='Z'がすべて指定されている場合は、スキーマ Xのオブジェクト Zにイベント通知を直接登録しようとします。 クライアントが権限を持っている場合、登録は正常に終了します。 現在、オブジェクト レベルのイベントはキューでのみサポートされ、 QUEUE_ACTIVATION event_typeでのみサポートされています。

特定のスコープですべてのイベントを照会できるわけではありません。 たとえば、Lock_Deadlockなどのトレース イベントに対する WQL クエリや、 TRC_LOCKS などのトレース イベント グループは、サーバー レベルでのみ登録できます。 同様に、 CREATE_ENDPOINT イベントと DDL_ENDPOINT_EVENTS イベント グループも、サーバー レベルでのみ登録できます。 イベントを登録するための適切なスコープの詳細については、「イベント通知の作成を参照してください。 event_typeをサーバー レベルでのみ登録できる WQL クエリを登録しようとすると、常にサーバー レベルで行われます。 WMI クライアントが権限を持っている場合、登録は正常に終了します。 それ以外の場合は、クライアントにエラーが返されます。 ただし、場合によっては、 WHERE 句を、イベントに対応するプロパティに基づくサーバー レベルのイベントのフィルターとして引き続き使用できます。 たとえば、多くのトレース イベントには、フィルターとして WHERE 句で使用できるDatabaseName プロパティがあります。

サーバー スコープのイベント通知は、 master データベースに作成され、 sys.server_event_notifications カタログ ビューを使用してメタデータを照会できます。

データベース スコープまたはオブジェクト スコープのイベント通知は、指定されたデータベースに作成され、 sys.event_notifications カタログ ビューを使用してメタデータを照会できます。 (カタログ ビューのプレフィックスには、対応するデータベース名を使用する必要があります)。

この記事の Transact-SQL コード サンプルは AdventureWorks2022 または AdventureWorksDW2022 サンプル データベースを使用します。このサンプル データベースは、Microsoft SQL Server サンプルとコミュニティ プロジェクトのホーム ページからダウンロードできます。

A. サーバー スコープでのイベントのクエリ

次の WQL クエリは、SQL Server のインスタンスで発生するすべての SERVER_MEMORY_CHANGE トレース イベントのすべてのイベント プロパティを取得します。

SELECT * FROM SERVER_MEMORY_CHANGE

B. データベース スコープでのイベントのクエリ

次の WQL クエリは、AdventureWorks2022 データベース内で発生し、DDL_DATABASE_LEVEL_EVENTS イベント グループに存在するイベントの特定のイベント プロパティを取得します。

SELECT SPID, SQLInstance, DatabaseName FROM DDL_DATABASE_LEVEL_EVENTS
WHERE DatabaseName = 'AdventureWorks2022'

C: スキーマとオブジェクトによるフィルター処理を行って、データベース スコープでイベントのクエリを実行する

次のクエリは、テーブル ALTER_TABLE 上で発生する Sales.SalesOrderDetail イベントのイベント プロパティを取得します。

SELECT * FROM ALTER_TABLE
WHERE DatabaseName = 'AdventureWorks2022' AND SchemaName = 'Sales'
    AND ObjectType='Table' AND ObjectName = 'SalesOrderDetail'