WMI Provider for Server Events と WQL の使用

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

たとえば、次の WQL クエリについて考えてみます。

SELECT * FROM DDL_DATABASE_LEVEL_EVENTS WHERE DatabaseName = 'AdventureWorks2008R2'

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

USE AdventureWorks2008R2 ;
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 クエリ (DDL_DATABASE_LEVEL_EVENTS) の FROM 句の引数には、イベント通知を作成できる有効なイベントを指定することができます。SELECT 句および WHERE 句の引数は、イベントまたはその親イベントに関連付けられたイベント プロパティを指定することができます。有効なイベントおよびイベント プロパティのリストについては、「WMI Provider for Server Events のクラスとプロパティ」を参照してください。

次の 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
    イベントのプロパティ。例には、PostTime、SPID、および 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 のクラスとプロパティ」を参照してください。event type の名前は、CREATE EVENT NOTIFICATION を使用してイベント通知を手動で作成する場合に指定できる、同じ event_type | event_group に対応していることに注意してください。event type には、CREATE_TABLE、LOCK_DEADLOCK、DDL_USER_EVENTS、TRC_DATABASE などがあります。

    注意

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

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

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

説明

WMI Provider for Server Events の構文の where_condition によって、次のことが決定されます。

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

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

WMI Provider for Server Events は、bottom-up および first-fit アルゴリズムを使用して、基になる EVENT NOTIFICATION に対してできるだけ小さなスコープを生成します。アルゴリズムにより、サーバーの内部的な利用状況、および SQL Server インスタンスと WMI ホスト プロセス間のネットワーク トラフィックが最小になるように試行されます。プロバイダーは、FROM 句で指定された event_type と、WHERE 句の条件を調べ、基になる EVENT NOTIFICATION を、できるだけ狭いスコープで登録しようとします。プロバイダーが最も狭いスコープで登録できない場合は、登録が正常に終了するまで、順次より高いスコープでの登録が試行されます。最も高いスコープ (サーバーレベル) に到達して失敗した場合、エラーがコンシューマーに返されます。

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

また、where_condition は、特定のデータベース、スキーマ、またはオブジェクトに対するクエリの制限を追加するためのフィルターとして機能します。たとえば、次の WQL クエリについて考えてみます。

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

登録プロセスの結果によっては、この WQL クエリは、データベース レベルまたはサーバー レベルのどちらかに登録されます。ただし、サーバー レベルに登録された場合でも、プロバイダーは、AdventureWorks2008R2.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 句は、イベントに対応するプロパティに基づいたサーバー レベル イベントに対するフィルターとして使用できる場合もあります。たとえば、多くのトレース イベントに含まれている DatabaseName プロパティは、WHERE 句でフィルターとして使用できます。

サーバースコープのイベント通知は、master データベースで作成され、sys.server_event_notifications カタログ ビューを使用して、メタデータに対してクエリを行うことができます。

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

A. サーバー スコープのイベントを照会する

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

SELECT * FROM SERVER_MEMORY_CHANGE

B. データベース スコープのイベントを照会する

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

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

C. データベース スコープのイベントを照会し、スキーマおよびオブジェクトでフィルター処理を行う

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

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