DBMS_ALERT包提供了注册、发送和接收告警的能力。
表 1. DBMS ALERT 函数/存储过程
函数/存储过程 | 返回类型 | 说明 |
REGISTER(name) | N/A | 使当前会话可以接收指定告警的通知信息。 |
REMOVE(name) | N/A | 取消接收指定告警的通知信息。 |
REMOVEALL | N/A | 从注册列表中删除此会话的所有告警。 |
SIGNAL(name, message) | N/A | 产生指定名称的告警。 |
WAITANY(name OUT, message OUT, status OUT, timeout) | N/A | 等待产生已注册的告警。 |
WAITONE(name, message OUT, status OUT, timeout) | N/A | 等待产生指定的告警。 |
使用说明
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(name VARCHAR2)
参数
参数名称 | 描述 |
name | 被取消注册的告警名称。 |
REMOVEALL
从注册列表中删除此会话的所有告警。
语法
REMOVEALL
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(name OUT VARCHAR2, message OUT VARCHAR2, status OUT INTEGER, timeout NUMBER)
参数
参数名称 | 描述 |
name | 告警名称。 |
message | 与告警相关的信息。 |
status | 返回的状态码。
|
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(name VARCHAR2, message OUT VARCHAR2, status OUT INTEGER, timeout NUMBER)
参数
参数名称 | 描述 |
name | 告警名称。 |
message | 储过程SIGNAL发送的消息。 |
status | 返回的状态码。
|
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
综合性示例
以下示例中,当表dept和emp发生改变时,您可以使用两个触发器发送告警信息。使用一个匿名代码块监听这些告警,并且当收到告警时,显示相关信息。
准备基础数据。
CREATE TABLE dept ( deptno NUMBER(2) NOT NULL CONSTRAINT dept_pk PRIMARY KEY, dname VARCHAR2(14) CONSTRAINT dept_dname_uq UNIQUE, loc VARCHAR2(13) ); CREATE TABLE emp ( empno NUMBER(4) NOT NULL CONSTRAINT emp_pk PRIMARY KEY, ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7,2) CONSTRAINT emp_sal_ck CHECK (sal > 0), comm NUMBER(7,2), deptno NUMBER(2) CONSTRAINT emp_ref_dept_fk REFERENCES dept(deptno) ); GRANT ALL ON emp TO PUBLIC; GRANT ALL ON dept TO PUBLIC; INSERT INTO dept VALUES (10,'ACCOUNTING','NEW YORK'); INSERT INTO dept VALUES (20,'RESEARCH','DALLAS'); INSERT INTO dept VALUES (30,'SALES','CHICAGO'); INSERT INTO dept VALUES (40,'OPERATIONS','BOSTON'); INSERT INTO emp VALUES (7369,'SMITH','CLERK',7902,'17-DEC-80',800,NULL,20); INSERT INTO emp VALUES (7499,'ALLEN','SALESMAN',7698,'20-FEB-81',1600,300,30); INSERT INTO emp VALUES (7521,'WARD','SALESMAN',7698,'22-FEB-81',1250,500,30); INSERT INTO emp VALUES (7566,'JONES','MANAGER',7839,'02-APR-81',2975,NULL,20); INSERT INTO emp VALUES (7654,'MARTIN','SALESMAN',7698,'28-SEP-81',1250,1400,30); INSERT INTO emp VALUES (7698,'BLAKE','MANAGER',7839,'01-MAY-81',2850,NULL,30); INSERT INTO emp VALUES (7782,'CLARK','MANAGER',7839,'09-JUN-81',2450,NULL,10); CREATE USER mary IDENTIFIED BY password; CREATE USER john IDENTIFIED BY password;
执行如下语句,在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;
在一个会话中执行如下匿名代码块:
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...
在其它会话中对表dept和emp进行更新操作。
用户mary对dept表和emp表执行以下操作:
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对dept表执行以下操作:
INSERT INTO dept VALUES (60,'HR','L0S ANGELES');
此时步骤3的会话将显示从触发器中接收告警信号的匿名代码块显示的输出内容。
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