定义新触发器。
语法
CREATE [ OR REPLACE ] TRIGGER name
{ BEFORE | AFTER | INSTEAD OF }
{ INSERT | UPDATE | DELETE }
[ OR { INSERT | UPDATE | DELETE } ] [, ...]
ON table
[ REFERENCING { OLD AS old | NEW AS new } ...]
[ FOR EACH ROW ]
[ WHEN condition ]
[ DECLARE
[ PRAGMA AUTONOMOUS_TRANSACTION; ]
declaration; [, ...] ]
BEGIN
statement; [, ...]
[ EXCEPTION
{ WHEN exception [ OR exception ] [...] THEN
statement; [, ...] } [, ...]
]
END
说明
CREATE TRIGGER 定义新触发器。CREATE OR REPLACE TRIGGER 将创建新触发器,或替换现有定义。
如果使用 CREATE TRIGGER 关键字创建新触发器,则新触发器的名称不得与同一表中定义的任何现有触发器匹配。新触发器将在与定义触发事件的表相同的 schema 中创建。
如果要更新现有触发器的定义,可使用 CREATE OR REPLACE TRIGGER 关键字。
如果使用与 Oracle 兼容的语法创建触发器,则触发器作为 SECURITY DEFINER 函数运行。
参数
参数 | 说明 |
---|---|
name | 要创建的触发器的名称。 |
BEFORE | AFTER | 确定是在触发事件之前还是之后触发触发器。 |
INSERT | UPDATE | DELETE | 定义触发事件。 |
table | 在其中发生触发事件的表的名称。 |
condition | condition 是 Boolean 表达式,确定是否实际执行触发器。如果 condition 的求值结果为 TRUE,则将触发触发器。
|
REFERENCING { OLD AS old | NEW AS new } ... | 用于引用旧行和新行的 REFERENCING 子句,但受到限制,因为 old 只能由名为 old 的标识符或以全小写形式保存的任何等效项替换(例如,REFERENCING
OLD AS old、REFERENCING OLD AS OLD 或 REFERENCING OLD AS "old")。此外,new 只能由名为 new 的标识符或以全小写的形式保存的任何等效项替换(例如,REFERENCING
NEW AS new、REFERENCING NEW AS NEW 或 REFERENCING NEW AS "new")。
可以在 REFERENCING 子句中指定以下两个短语或其中一个:OLD AS old 和 NEW AS new(例如,REFERENCING NEW AS New OLD AS Old)。 说明 此子句与 Oracle 数据库不兼容,因为不能使用 old 或 new 之外的标识符。
|
FOR EACH ROW | 确定是应当为受触发事件影响的每一行触发一次触发器,还是只按每个 SQL 语句触发一次。如果指定,则为受影响的每一行触发一次触发器(行级触发器),否则触发器为语句级触发器。 |
PRAGMA AUTONOMOUS_TRANSACTION | PRAGMA AUTONOMOUS_TRANSACTION 是将触发器设置为自治事务的指令。 |
declaration | 变量、类型、REF CURSOR 或子程序声明。如果包括子程序声明,则它们必须在所有其他变量、类型和 REF CURSOR 声明之后。 |
statement | 一个 SPL 程序语句。请注意,DECLARE - BEGIN - END 块被视为 SPL 语句本身。因此,触发器主体可能包含嵌套块。 |
exception | 异常条件名称,如 NO_DATA_FOUND、OTHERS 等。 |
示例
以下是语句级触发器,在执行触发语句(在表 emp 中进行插入、更新或删除操作)之后触发。
CREATE OR REPLACE TRIGGER user_audit_trig
AFTER INSERT OR UPDATE OR DELETE ON emp
DECLARE
v_action VARCHAR2(24);
BEGIN
IF INSERTING THEN
v_action := ' added employee(s) on ';
ELSIF UPDATING THEN
v_action := ' updated employee(s) on ';
ELSIF DELETING THEN
v_action := ' deleted employee(s) on ';
END IF;
DBMS_OUTPUT.PUT_LINE('User ' || USER || v_action ||
TO_CHAR(SYSDATE,'YYYY-MM-DD'));
END;
以下是行级触发器,在表 emp 中对每一行进行插入、更新或删除操作之前触发。
CREATE OR REPLACE TRIGGER emp_sal_trig
BEFORE DELETE OR INSERT OR UPDATE ON emp
FOR EACH ROW
DECLARE
sal_diff NUMBER;
BEGIN
IF INSERTING THEN
DBMS_OUTPUT.PUT_LINE('Inserting employee ' || :NEW.empno);
DBMS_OUTPUT.PUT_LINE('..New salary: ' || :NEW.sal);
END IF;
IF UPDATING THEN
sal_diff := :NEW.sal - :OLD.sal;
DBMS_OUTPUT.PUT_LINE('Updating employee ' || :OLD.empno);
DBMS_OUTPUT.PUT_LINE('..Old salary: ' || :OLD.sal);
DBMS_OUTPUT.PUT_LINE('..New salary: ' || :NEW.sal);
DBMS_OUTPUT.PUT_LINE('..Raise : ' || sal_diff);
END IF;
IF DELETING THEN
DBMS_OUTPUT.PUT_LINE('Deleting employee ' || :OLD.empno);
DBMS_OUTPUT.PUT_LINE('..Old salary: ' || :OLD.sal);
END IF;
END;