DBMS_ALERT パッケージは、アラートを登録、送信、および受信する機能を提供しています。

表 1. DBMS_ALERT 関数とストアドプロシージャ
関数/ストアドプロシージャ 戻り値の型 説明
REGISTER(name) N/A name という名前のアラートを受信できるように登録します。
REMOVE(name) N/A name という名前のアラートの登録を削除します。
REMOVEALL N/A すべてのアラートの登録を削除します。
SIGNAL(name, message) N/A name という名前のアラートを message とともに通知します。
WAITANY(name OUT, message OUT, status OUT, timeout) N/A 登録されたアラートが生じるのを待ちます。
WAITONE(name, message OUT, status OUT, timeout) N/A name という指定されたアラートが生じるのを待ちます。

Oracle と互換性のある POLARDB の DBMS_ALERT パッケージは、Oracle のバージョンと比較すると部分的に実装されています。 Oracle と互換性のある POLARDB は、前の表にリストされている関数とストアドプロシージャのみをサポートしています。

Oracle と互換性のある POLARDB は、最大 500 の同時アラートを許可します。 dbms_alert.max_alerts GUC 変数 (postgresql.conf ファイルにあります) を使用して、システムで許可される同時アラートの最大数を指定することができます。

dbms_alert.max_alerts 変数の値を設定するには、エディターを選択して postgresql.conf ファイル (デフォルトの場所: /opt/PostgresPlus/9.3AS/data) を開きます。 次の例に示すように、dbms_alert.max_alerts パラメーターを編集します。

dbms_alert.max_alerts = alert_count
alert_count は、同時アラートの最大数を指定します。 dbms_alert.max_alerts のデフォルト値は 100 です。 この機能を無効にするには、dbms_alert.max_alerts に 0 を設定します。

dbms_alert.max_alerts GUC 変数が期待どおりに機能するには、custom_variable_classes パラメーターに dbms_alerts が含まれている必要があります。

custom_variable_classes = 'dbms_alert, …'

postgresql.conf ファイルのパラメーターを編集した後、変更を有効にするためにサーバーを再起動する必要があります。

REGISTER

REGISTER ストアドプロシージャを使用すると、指定したアラートを現在のセッションに通知することができます。

構文

REGISTER(name VARCHAR2) 

パラメーター

パラメーター 説明
name 登録するアラートの名前。

次の匿名ブロックは、alert_test という名前のアラートを登録し、シグナルを待ちます。

DECLARE
    v_name           VARCHAR2(30) := 'alert_test';
    v_msg            VARCHAR2(80);
    v_status         INTEGER;
    v_timeout        NUMBER(3) := 120;
BEGIN
    DBMS_ALERT.REGISTER(v_name);
    DBMS_OUTPUT.PUT_LINE('Registered for alert ' || v_name);
    DBMS_OUTPUT.PUT_LINE('Waiting for signal...') ;
    DBMS_ALERT.WAITONE(v_name,v_msg,v_status,v_timeout);
    DBMS_OUTPUT.PUT_LINE('Alert name   : ' || v_name);
    DBMS_OUTPUT.PUT_LINE('Alert msg    : ' || v_msg);
    DBMS_OUTPUT.PUT_LINE('Alert status : ' || v_status);
    DBMS_OUTPUT.PUT_LINE('Alert timeout: ' || v_timeout || ' seconds');
    DBMS_ALERT.REMOVE(v_name);
END;

Registered for alert alert_test
Waiting for signal...

REMOVE

REMOVE ストアドプロシージャは、指定されたアラートのセッションを登録解除します。

構文

REMOVE(name VARCHAR2)

パラメーター

パラメーター 説明
name 登録を解除するアラートの名前。

REMOVEALL

REMOVEALL ストアドプロシージャは、すべてのアラートのセッションを登録解除します。

構文

REMOVEALL

SIGNAL

SIGNAL ストアドプロシージャは、名前付きアラートが生じたことを通知します。

構文

SIGNAL(name VARCHAR2, message VARCHAR2)

パラメーター

パラメーター 説明
name アラートの名前。
message このアラートで渡す情報。

次の匿名ブロックは、alert_test のアラートを通知します。

DECLARE
    v_name   VARCHAR2(30) := 'alert_test';
BEGIN
    DBMS_ALERT.SIGNAL(v_name,'This is the message from ' || v_name);
    DBMS_OUTPUT.PUT_LINE('Issued alert for ' || v_name);
END;

Issued alert for alert_test    

WAITANY

WAITANY ストアドプロシージャは、登録済みのアラートが生じるのを待ちます。

構文

WAITANY(name OUT VARCHAR2, message OUT VARCHAR2, status OUT INTEGER, timeout NUMBER)

パラメーター

パラメーター 説明
name アラートの名前を受け取る変数。
message SIGNAL ストアドプロシージャによって送信されたメッセージを受け取る変数。
status 操作によって返されたステータスコード。 有効な値は 0 および 1で、0 はアラートが生じたことを示します。 1 は、タイムアウトが生じたことを示します。
timeout アラートを待つ時間。 単位: 秒。

次の匿名ブロックは、WAITANY ストアドプロシージャを使用して、alert_test または any_alert という名前のアラートを受信します。

DECLARE
    v_name           VARCHAR2(30);
    v_msg            VARCHAR2(80);
    v_status         INTEGER;
    v_timeout        NUMBER(3) := 120;
BEGIN
    DBMS_ALERT.REGISTER('alert_test');
    DBMS_ALERT.REGISTER('any_alert');
    DBMS_OUTPUT.PUT_LINE('Registered for alert alert_test and any_alert');
    DBMS_OUTPUT.PUT_LINE('Waiting for signal...') ;
    DBMS_ALERT.WAITANY(v_name,v_msg,v_status,v_timeout);
    DBMS_OUTPUT.PUT_LINE('Alert name   : ' || v_name);
    DBMS_OUTPUT.PUT_LINE('Alert msg    : ' || v_msg);
    DBMS_OUTPUT.PUT_LINE('Alert status : ' || v_status);
    DBMS_OUTPUT.PUT_LINE('Alert timeout: ' || v_timeout || ' seconds');
    DBMS_ALERT.REMOVEALL;
END;

Registered for alert alert_test and any_alert
Waiting for signal...        

次の匿名ブロックは、any_alert にシグナルを発行します。

DECLARE
    v_name   VARCHAR2(30) := 'any_alert';
BEGIN
    DBMS_ALERT.SIGNAL(v_name,'This is the message from ' || v_name);
    DBMS_OUTPUT.PUT_LINE('Issued alert for ' || v_name);
END;

Issued alert for any_alert

次の出力は、制御が最初の匿名ブロックに戻り、残りのコードが実行されることを示しています。

Registered for alert alert_test and any_alert
Waiting for signal...
Alert name   : any_alert
Alert msg    : This is the message from any_alert
Alert status : 0
Alert timeout: 120 seconds

WAITONE

WAITONE ストアドプロシージャは、指定された登録済みアラートが生じるのを待ちます。

構文

WAITONE(name VARCHAR2, message OUT VARCHAR2, status OUT INTEGER, timeout NUMBER)

パラメーター

パラメーター 説明
name アラートの名前。
message SIGNAL ストアドプロシージャによって送信されたメッセージを受け取る変数。
status 操作によって返されたステータスコード。 有効な値は 0 および 1で、0 はアラートが生じたことを示します。 1 は、タイムアウトが生じたことを示します。
timeout アラートを待つ時間。 単位: 秒。

次の匿名ブロックは、WAITONE ストアドプロシージャを使用して、alert_test という名前のアラートを受信することを除いて、WAITANY の例で使用されているものと似ています。

DECLARE
    v_name           VARCHAR2(30) := 'alert_test';
    v_msg            VARCHAR2(80);
    v_status         INTEGER;
    v_timeout        NUMBER(3) := 120;
BEGIN
    DBMS_ALERT.REGISTER(v_name);
    DBMS_OUTPUT.PUT_LINE('Registered for alert ' || v_name);
    DBMS_OUTPUT.PUT_LINE('Waiting for signal...') ;
    DBMS_ALERT.WAITONE(v_name,v_msg,v_status,v_timeout);
    DBMS_OUTPUT.PUT_LINE('Alert name   : ' || v_name);
    DBMS_OUTPUT.PUT_LINE('Alert msg    : ' || v_msg);
    DBMS_OUTPUT.PUT_LINE('Alert status : ' || v_status);
    DBMS_OUTPUT.PUT_LINE('Alert timeout: ' || v_timeout || ' seconds');
    DBMS_ALERT.REMOVE(v_name);
END;

Registered for alert alert_test
Waiting for signal...

次の匿名ブロックは、alert_test にシグナルを発行します。

DECLARE
    v_name   VARCHAR2(30) := 'alert_test';
BEGIN
    DBMS_ALERT.SIGNAL(v_name,'This is the message from ' || v_name);
    DBMS_OUTPUT.PUT_LINE('Issued alert for ' || v_name);
END;

Issued alert for alert_test

次の出力は、最初のセッションが警告され、制御が最初の匿名ブロックに戻り、残りのコードが実行されることを示しています。

Registered for alert alert_test
Waiting for signal...
Alert name   : alert_test
Alert msg    : This is the message from alert_test
Alert status : 0
Alert timeout: 120 seconds

Comprehensive example

次の例では、2 つのトリガーを使用して、dept テーブルまたは emp テーブルが変更されたときにアラートを送信します。 匿名ブロックはこれらのアラートをリッスンし、アラートを受信するとメッセージを表示します。

dept テーブルと emp テーブルのトリガーは、次のように定義されます。

CREATE OR REPLACE TRIGGER dept_alert_trig
    AFTER INSERT OR UPDATE OR DELETE ON dept
DECLARE
    v_action        VARCHAR2(25);
BEGIN
    IF INSERTING THEN
        v_action := ' added department(s) ';
    ELSIF UPDATING THEN
        v_action := ' updated department(s) ';
    ELSIF DELETING THEN
        v_action := ' deleted department(s) ';
    END IF;
    DBMS_ALERT.SIGNAL('dept_alert',USER || v_action || 'on ' ||
        SYSDATE);
END;

CREATE OR REPLACE TRIGGER emp_alert_trig
    AFTER INSERT OR UPDATE OR DELETE ON emp
DECLARE
    v_action        VARCHAR2(25);
BEGIN
    IF INSERTING THEN
        v_action := ' added employee(s) ';
    ELSIF UPDATING THEN
        v_action := ' updated employee(s) ';
    ELSIF DELETING THEN
        v_action := ' deleted employee(s) ';
    END IF;
    DBMS_ALERT.SIGNAL('emp_alert',USER || v_action || 'on ' ||
        SYSDATE);
END;

次の匿名ブロックは、dept テーブルと emp テーブルが他のセッションで更新されている間に、セッションで実行されます。

DECLARE
    v_dept_alert     VARCHAR2(30) := 'dept_alert';
    v_emp_alert      VARCHAR2(30) := 'emp_alert';
    v_name           VARCHAR2(30);
    v_msg            VARCHAR2(80);
    v_status         INTEGER;
    v_timeout        NUMBER(3) := 60;
BEGIN
    DBMS_ALERT.REGISTER(v_dept_alert);
    DBMS_ALERT.REGISTER(v_emp_alert);
    DBMS_OUTPUT.PUT_LINE('Registered for alerts dept_alert and emp_alert');
    DBMS_OUTPUT.PUT_LINE('Waiting for signal...') ;
    LOOP
        DBMS_ALERT.WAITANY(v_name,v_msg,v_status,v_timeout);
        EXIT WHEN v_status ! = 0);
        DBMS_OUTPUT.PUT_LINE('Alert name   : ' || v_name);
        DBMS_OUTPUT.PUT_LINE('Alert msg    : ' || v_msg);
        DBMS_OUTPUT.PUT_LINE('Alert status : ' || v_status);
        DBMS_OUTPUT.PUT_LINE('------------------------------------' ||
            '-------------------------');
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('Alert status : ' || v_status);
    DBMS_ALERT.REMOVEALL;
END;

Registered for alerts dept_alert and emp_alert
Waiting for signal...

次の変更は、mary という名前のユーザーによって行われます。

INSERT INTO dept VALUES (50,'FINANCE,,,CHICAG0');
INSERT INTO emp (empno,ename,deptno) VALUES (9001,'J0NES',50);
INSERT INTO emp (empno,ename,deptno) VALUES (9002,'ALICE',50);
			

次の変更は、john というユーザーによって行われます。

INSERT INTO dept VALUES (60,'HR','L0S ANGELES');

次の例は、トリガーからシグナルを受け取る匿名ブロックによって表示される出力を示しています。

Registered for alerts dept_alert and emp_alert
Waiting for signal...
Alert name   : dept_alert
Alert msg    : mary added department(s) on 25-OCT-07 16:41:01
Alert status : 0
-------------------------------------------------------------
Alert name   : emp_alert
Alert msg    : mary added employee(s) on 25-OCT-07 16:41:02
Alert status : 0
-------------------------------------------------------------
Alert name   : dept_alert
Alert msg    : john added department(s) on 25-OCT-07 16:41:22
Alert status : 0
-------------------------------------------------------------
Alert status : 1