EVENTDATA 関数の使用

更新 : 2005 年 12 月 5 日

DDL トリガを起動するイベントに関する情報は、EVENTDATA 関数を使用してキャプチャされます。この関数は、xml 値を返します。XML スキーマには、次の項目に関する情報が含まれています。

  • イベントの時刻。
  • トリガが実行されたときの接続のシステム プロセス ID (SPID)。
  • トリガを起動したイベントの種類。

イベントの種類に応じて、イベントが発生したデータベース、イベントが発生したオブジェクト、イベントの Transact-SQL ステートメントなどの追加情報がスキーマに含まれます。詳細については、「EVENTDATA (Transact-SQL)」を参照してください。

たとえば、次の DDL トリガが AdventureWorks サンプル データベースに作成されたとします。

CREATE TRIGGER safety 
ON DATABASE 
FOR CREATE_TABLE 
AS 
    PRINT 'CREATE TABLE Issued.'
    SELECT EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
   RAISERROR ('New tables cannot be created in this database.', 16, 1) 
   ROLLBACK
;

次に、以下の CREATE TABLE ステートメントが実行されます。

    CREATE TABLE NewTable (Column1 int);

DDL トリガの EVENTDATA() ステートメントにより、CREATE TABLE ステートメントでは許可されないテキストがキャプチャされます。これは、EVENTDATA によって生成された xml データに対して XQuery ステートメントを使用して、<CommandText> 要素を取得することによって行われます。詳細については、「xml データ型に対する XQuery」を参照してください。

ms187909.Caution(ja-jp,SQL.90).gif注意 :
EVENTDATA は、CREATE_SCHEMA イベントのデータをキャプチャします。対応する CREATE SCHEMA 定義の <schema_element> がある場合にはそれもキャプチャします。さらに、EVENTDATA は <schema_element> 定義を別のイベントとして認識します。したがって、CREATE_SCHEMA イベント、および CREATE SCHEMA 定義の <schema_element> によって表されるイベントの両方で作成される DDL トリガは、TSQLCommand データのように同じイベント データを 2 回返す場合があります。たとえば、CREATE_SCHEMA イベントと CREATE_TABLE イベントの両方で DDL トリガが作成され、次のバッチを実行するとします。 CREATE SCHEMA s CREATE TABLE t1 (col1 int) アプリケーションで CREATE_TABLE イベントの TSQLCommand データを取得する場合は、このデータが 2 回発生する可能性があることに注意してください。つまり、CREATE_SCHEMA イベントの発生時と、CREATE_TABLE イベントの発生時です。CREATE_SCHEMA イベントと、対応する CREATE SCHEMA 定義の <schema_element> テキストの両方で DDL トリガを作成しないようにするか、または同じイベントを 2 回処理しないようにアプリケーションのロジックを作成します。

EVENTDATA 関数を使用して、イベントのログを作成できます。次の例では、イベント情報を格納するためのテーブルが作成されます。次に、現在のデータベースに DDL トリガが作成されます。この DDL トリガにより、データベース レベルの DDL イベントが発生するたびに、次の情報がテーブルに設定されます。

  • イベントの時刻 (GETDATE 関数を使用)。
  • イベントが発生したセッションのデータベース ユーザー (CURRENT_USER 関数を使用)。
  • イベントの種類。
  • イベントが含まれる Transact-SQL ステートメント。

最後の 2 つの項目は、EVENTDATA によって生成された xml データに対して XQuery を使用することによってキャプチャされます。

USE AdventureWorks;
GO
CREATE TABLE ddl_log (PostTime datetime, DB_User nvarchar(100), Event nvarchar(100), TSQL nvarchar(2000));
GO
CREATE TRIGGER log 
ON DATABASE 
FOR DDL_DATABASE_LEVEL_EVENTS 
AS
DECLARE @data XML
SET @data = EVENTDATA()
INSERT ddl_log 
   (PostTime, DB_User, Event, TSQL) 
   VALUES 
   (GETDATE(), 
   CONVERT(nvarchar(100), CURRENT_USER), 
   @data.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(100)'), 
   @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(2000)') ) ;
GO
--Test the trigger
CREATE TABLE TestTable (a int)
DROP TABLE TestTable ;
GO
SELECT * FROM ddl_log ;
GO
ms187909.note(ja-jp,SQL.90).gifメモ :
イベント データを返す場合は、query() メソッドの代わりに XQuery の value() メソッドを使用してください。query() メソッドでは、出力として XML の他に、アンパサンド記号でエスケープされたキャリッジ リターンとライン フィード (CRLF) の組み合わせが返されます。それに対して value() メソッドの出力には、CRLF の組み合わせが表示されません。

同様の DDL トリガの例を、AdventureWorks サンプル データベースで提供しています。この例を入手するには、SQL Server Management Studio を使用して Database Triggers フォルダを探します。このフォルダは、AdventureWorks データベースの [プログラミング] フォルダにあります。[ddlDatabseTriggerLog] を右クリックし、[名前を付けてデータベース トリガをスクリプト化] をクリックします。既定では、DDL トリガ ddlDatabseTriggerLog は無効になっています。

参照

概念

DDL トリガの設計

ヘルプおよび情報

SQL Server 2005 の参考資料の入手

変更履歴

リリース 履歴

2005 年 12 月 5 日

新しい内容 :
  • CREATE_SCHEMA イベントと、対応する CREATE SCHEMA 定義の <schema_element> テキストの両方で DDL トリガを作成する際の注意を追加しました。