イベントをパブリッシュするトリガー
トリガーを使用してイベントをパブリッシュするには、次のようなトリガーを作成します。
-
トリガーに、トリガーを起動するイベントとしてそのイベントを含めること。
-
トリガーで、
DBMS_AQ
パッケージの適切なサブプログラムを起動すること。このパッケージには、Oracleアドバンスト・キューイング(AQ)に対するインタフェースが含まれます。DBMS_AQ
パッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。AQの詳細は、『Oracle Databaseアドバンスト・キューイング・ユーザーズ・ガイド』を参照してください。
このようなトリガーを有効化および無効化することで、イベント通知のオンとオフを切り替えることができます。トリガーの有効化および無効化の詳細は、「トリガーの有効化および無効化」を参照してください。
トリガーによるイベントのパブリッシュ方法
データベースは、イベントを検出すると、そのイベントに対して定義されている有効なすべてのトリガーを起動します。これには次の例外があります。
-
トリガーがトリガーを起動するイベントのターゲットである場合、このトリガーは起動されません。
たとえば、すべての
DROP
イベントのトリガーは、トリガー自体が削除される場合は起動されません。 -
変更されたトリガーが、トリガーを起動するイベントと同じトランザクション内でコミットされなかった場合、このトリガーは起動されません。
たとえば、システム・トリガー内の再帰DDL文によって別のトリガーが変更されると、同じトランザクション内のイベントでは、変更されたトリガーを起動できなくなります。
トリガーによってAQが起動されると、AQはイベントをパブリッシュして、トリガーにパブリケーション・コンテキストおよび指定された属性を渡します。トリガーでは、イベント属性ファンクションを起動することでこれらの属性にアクセスできます。
トリガーが(IN
パラメータとしてAQに渡すことで)AQに対して指定し、その後イベント属性ファンクションを使用してアクセスできる属性は、トリガーを起動するイベント(データベース・イベントまたはクライアント・イベント)によって異なります。
ノート:
-
トリガーは、常に定義者権限(DR)ユニットのように動作します。イベントのトリガー・アクションは、アクションの定義者として(コールアウト内のパッケージまたはファンクションの定義者、またはキュー内のトリガーの所有者として)実行されます。トリガーの所有者には基礎となるキュー、パッケージまたはサブプログラムに対する
EXECUTE
権限が必要なため、このアクションには一貫性があります。DRユニットの詳細は、「実行者権限および定義者権限(AUTHIDプロパティ)」を参照してください。 -
データベースでは、すべてのイベントについてコールバック・ファンクションからの戻りステータスが無視されます。たとえば、データベースでは、
SHUTDOWN
イベントからの戻りステータスに対して何も実行できません。
ここでのトピック
イベント属性ファンクション
トリガーでは、表10-5のシステム定義のイベント属性ファンクションを起動することで、トリガーを起動するイベントの特定の属性を取り出すことができます。すべてのトリガーがすべてのイベント属性ファンクションを起動できるわけではありません(詳細は、「データベース・イベント・トリガーのイベント属性ファンクション」および「クライアント・イベント・トリガーのイベント属性ファンクション」を参照してください)。
ノート:
-
以前のリリースでは、これらのファンクションには
SYS
パッケージを介してアクセスする必要がありました。現在、各ファンクションにアクセスするには、そのパブリック・シノニム(表10-5の最初の列のora_
で始まる名前)を使用することをお薦めします。 -
ファンクション・パラメータ
ora_name_list_t
は、DBMS_STANDARD
パッケージ内で次のように定義されます。TYPE ora_name_list_t IS TABLE OF VARCHAR2(2*(ORA_MAX_NAME_LEN+2)+1);
表10-5 システム定義のイベント属性
属性 | 戻り型および値 | 例 |
---|---|---|
ora_client_ip_address |
|
DECLARE
v_addr VARCHAR2(11);
BEGIN
IF (ora_sysevent = 'LOGON') THEN
v_addr := ora_client_ip_address;
END IF;
END;
/ |
ora_database_name |
|
DECLARE
v_db_name VARCHAR2(50);
BEGIN
v_db_name := ora_database_name;
END;
/ |
ora_des_encrypted_password |
|
IF (ora_dict_obj_type = 'USER') THEN
INSERT INTO event_table
VALUES (ora_des_encrypted_password);
END IF; |
ora_dict_obj_name |
|
INSERT INTO event_table
VALUES ('Changed object is ' ||
ora_dict_obj_name); |
ora_dict_obj_name_list ( name_list OUT ora_name_list_t ) |
|
DECLARE
name_list ora_name_list_t;
number_modified PLS_INTEGER;
BEGIN
IF (ora_sysevent='ASSOCIATE STATISTICS') THEN
number_modified :=
ora_dict_obj_name_list(name_list);
END IF;
END; |
ora_dict_obj_owner |
|
INSERT INTO event_table
VALUES ('object owner is' ||
ora_dict_obj_owner); |
ora_dict_obj_owner_list ( owner_list OUT ora_name_list_t ) |
|
DECLARE
owner_list ora_name_list_t;
number_modified PLS_INTEGER;
BEGIN
IF (ora_sysevent='ASSOCIATE STATISTICS') THEN
number_modified :=
ora_dict_obj_name_list(owner_list);
END IF;
END; |
ora_dict_obj_type |
|
INSERT INTO event_table
VALUES ('This object is a ' ||
ora_dict_obj_type); |
ora_grantee ( user_list OUT ora_name_list_t ) |
|
DECLARE
user_list ora_name_list_t;
number_of_grantees PLS_INTEGER;
BEGIN
IF (ora_sysevent = 'GRANT') THEN
number_of_grantees :=
ora_grantee(user_list);
END IF;
END; |
ora_instance_num |
|
IF (ora_instance_num = 1) THEN
INSERT INTO event_table VALUES ('1');
END IF; |
ora_is_alter_column ( column_name IN VARCHAR2 ) |
|
IF (ora_sysevent = 'ALTER' AND
ora_dict_obj_type = 'TABLE') THEN
alter_column := ora_is_alter_column('C');
END IF; |
ora_is_creating_nested_table |
|
IF (ora_sysevent = 'CREATE' AND
ora_dict_obj_type = 'TABLE' AND
ora_is_creating_nested_table) THEN
INSERT INTO event_table
VALUES ('A nested table is created');
END IF; |
ora_is_drop_column ( column_name IN VARCHAR2 ) |
|
IF (ora_sysevent = 'ALTER' AND
ora_dict_obj_type = 'TABLE') THEN
drop_column := ora_is_drop_column('C');
END IF; |
ora_is_servererror ( error_number IN VARCHAR2 ) |
|
IF ora_is_servererror(error_number) THEN
INSERT INTO event_table
VALUES ('Server error!!');
END IF; |
ora_login_user |
|
SELECT ora_login_user FROM DUAL; |
ora_partition_pos |
|
-- Retrieve ora_sql_txt into sql_text variable
v_n := ora_partition_pos;
v_new_stmt := SUBSTR(sql_text,1,v_n - 1)
|| ' ' || my_partition_clause
|| ' ' || SUBSTR(sql_text, v_n)); |
ora_privilege_list ( privilege_list OUT ora_name_list_t ) |
|
DECLARE
privilege_list ora_name_list_t;
number_of_privileges PLS_INTEGER;
BEGIN
IF (ora_sysevent = 'GRANT' OR
ora_sysevent = 'REVOKE') THEN
number_of_privileges :=
ora_privilege_list(privilege_list);
END IF;
END; |
ora_revokee ( user_list OUT ora_name_list_t ) |
|
DECLARE
user_list ora_name_list_t;
number_of_users PLS_INTEGER;
BEGIN
IF (ora_sysevent = 'REVOKE') THEN
number_of_users := ora_revokee(user_list);
END IF;
END; |
ora_server_error ( position IN PLS_INTEGER ) |
|
INSERT INTO event_table
VALUES ('top stack error ' ||
ora_server_error(1)); |
ora_server_error_depth |
|
n := ora_server_error_depth;
-- Use n with functions such as ora_server_error |
ora_server_error_msg ( position IN PLS_INTEGER ) |
|
INSERT INTO event_table
VALUES ('top stack error message' ||
ora_server_error_msg(1)); |
ora_server_error_num_params ( position IN PLS_INTEGER ) |
|
n := ora_server_error_num_params(1); |
ora_server_error_param ( position IN PLS_INTEGER, param IN PLS_INTEGER ) |
|
-- Second %s in "Expected %s, found %s":
param := ora_server_error_param(1,2); |
ora_sql_txt ( sql_text OUT ora_name_list_t ) |
|
CREATE TABLE event_table (col VARCHAR2(2030)); DECLARE sql_text ora_name_list_t; n PLS_INTEGER; v_stmt VARCHAR2(2000); BEGIN n := ora_sql_txt(sql_text); FOR i IN 1..n LOOP v_stmt := v_stmt || sql_text(i); END LOOP; INSERT INTO event_table VALUES ('text of triggering statement: ' || v_stmt); END; |
ora_sysevent |
|
INSERT INTO event_table
VALUES (ora_sysevent); |
ora_with_grant_option |
|
IF (ora_sysevent = 'GRANT' AND
ora_with_grant_option = TRUE) THEN
INSERT INTO event_table
VALUES ('with grant option');
END IF; |
ora_space_error_info ( error_number OUT NUMBER, error_type OUT VARCHAR2, object_owner OUT VARCHAR2, table_space_name OUT VARCHAR2, object_name OUT VARCHAR2, sub_object_name OUT VARCHAR2 ) |
|
IF (ora_space_error_info ( eno,typ,owner,ts,obj,subobj) = TRUE) THEN DBMS_OUTPUT.PUT_LINE('The object '|| obj || ' owned by ' || owner || ' has run out of space.'); END IF; |
脚注1
位置1は、スタックの先頭です。
データベース・イベント・トリガーのイベント属性ファンクション
表10-6に、イベント属性ファンクションを起動できるデータベース・イベント・トリガーの概要を示します。表10-6のトリガーを起動するイベントの詳細は、「database_event」を参照してください。
表10-6 データベース・イベント・トリガー
トリガー・イベント | トリガーが起動されるタイミング | WHEN条件 | 制限事項 | トランザクション | 属性ファンクション |
---|---|---|---|---|---|
AFTER STARTUP |
データベースのオープン時。 |
なし |
トリガーではデータベース操作は実行できません。 |
トリガーの起動後、別のトランザクションを開始してコミットします。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name |
BEFORE SHUTDOWN |
サーバーでインスタンスの停止が開始される直前。 これによって、カートリッジを完全に停止できます。非標準インスタンスの停止の場合、このトリガーは起動されない場合があります。 |
なし |
トリガーではデータベース操作は実行できません。 |
トリガーの起動後、別のトランザクションを開始してコミットします。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name |
AFTER DB_ROLE_CHANGE |
ロールの変更後最初のデータベースのオープン時。 |
なし |
なし |
トリガーの起動後、別のトランザクションを開始してコミットします。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name |
AFTER SERVERERROR |
条件がある場合、指定したエラーが発生するたびに起動。条件がない場合、任意のエラーが発生するたびに起動。 トリガーは、「database_event」にリストされているエラーに対しては起動されません。 |
|
エラーによって異なります。 |
トリガーの起動後、別のトランザクションを開始してコミットします。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_server_error ora_is_servererror ora_space_error_info |
クライアント・イベント・トリガーのイベント属性ファンクション
表10-7に、イベント属性ファンクションを起動できるクライアント・イベント・トリガーの概要を示します。表10-7のトリガーを起動するイベントの詳細は、「ddl_event」および「database_event」を参照してください。
ノート:
クライアント・イベント・トリガーがDDL操作(CREATE
OR
REPLACE
TRIGGER
など)のターゲットになった場合、同じトランザクション中に後でこのトリガーを起動することはできません。
表10-7 クライアント・イベント・トリガー
トリガー・イベント | トリガーが起動されるタイミング | WHEN条件 | 制限事項 | トランザクション | 属性ファンクション |
---|---|---|---|---|---|
BEFORE ALTER AFTER ALTER |
カタログ・オブジェクトの変更時。 |
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_dict_obj_type ora_dict_obj_name ora_dict_obj_owner ora_des_encrypted_password (for ALTER USER events) ora_is_alter_column (for ALTER TABLE events) ora_is_drop_column (for ALTER TABLE events) |
BEFORE DROP AFTER DROP |
カタログ・オブジェクトの削除時。 |
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_dict_obj_type ora_dict_obj_name ora_dict_obj_owner |
BEFORE ANALYZE AFTER ANALYZE |
|
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_dict_obj_name ora_dict_obj_type ora_dict_obj_owner |
BEFORE ASSOCIATE STATISTICS AFTER ASSOCIATE STATISTICS |
|
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_dict_obj_name ora_dict_obj_type ora_dict_obj_owner ora_dict_obj_name_list ora_dict_obj_owner_list |
BEFORE AUDIT AFTER AUDIT BEFORE NOAUDIT AFTER NOAUDIT |
|
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name |
BEFORE COMMENT AFTER COMMENT |
オブジェクトのコメント化時。 |
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_dict_obj_name ora_dict_obj_type ora_dict_obj_owner |
BEFORE CREATE AFTER CREATE |
カタログ・オブジェクトの作成時。 |
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_dict_obj_type ora_dict_obj_name ora_dict_obj_owner ora_is_creating_nested_table (for CREATE TABLE events) |
BEFORE DDL AFTER DDL |
ほとんどのSQL DDL文の発行時。PL/SQLサブプログラム・インタフェースを介して発行された |
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_dict_obj_name ora_dict_obj_type ora_dict_obj_owner |
BEFORE DISASSOCIATE STATISTICS AFTER DISASSOCIATE STATISTICS |
|
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_dict_obj_name ora_dict_obj_type ora_dict_obj_owner ora_dict_obj_name_list ora_dict_obj_owner_list |
BEFORE GRANT AFTER GRANT |
|
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_dict_obj_name ora_dict_obj_type ora_dict_obj_owner ora_grantee ora_with_grant_option ora_privilege_list |
BEFORE LOGOFF |
ユーザー・ログオフの開始時。 |
|
他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name |
AFTER LOGON |
ユーザーが正常にログオンした後。 |
|
他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
トリガーの起動後、別のトランザクションを開始してコミットします。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_client_ip_address |
BEFORE RENAME AFTER RENAME |
|
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_dict_obj_name ora_dict_obj_owner ora_dict_obj_type |
BEFORE REVOKE AFTER REVOKE |
|
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_dict_obj_name ora_dict_obj_type ora_dict_obj_owner ora_revokee ora_privilege_list |
AFTER SUSPEND |
領域不足状態のためSQL文が一時停止された後。 (トリガーは、文を再開できるようにこの状態を修正する必要があります。) |
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_server_error ora_is_servererror ora_space_error_info |
BEFORE TRUNCATE AFTER TRUNCATE |
オブジェクトの切捨て時。 |
オブジェクトの型と名前、 |
トリガーは、イベントを生成したオブジェクトに対してDDL操作を実行できません。 他のオブジェクトに対するDDLは、オブジェクトのコンパイル、トリガーの作成、および表の作成、変更、削除に制限されます。 |
カレント・トランザクションでトリガーが起動されます。 |
ora_sysevent ora_login_user ora_instance_num ora_database_name ora_dict_obj_name ora_dict_obj_type ora_dict_obj_owner |