定义新触发器。

语法

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,则将触发触发器。
  • 如果触发器定义包含 FOR EACH ROW 关键字,那么 WHEN 子句可以分别通过写入 OLD.column_name 或 NEW.column_name 来引用旧和/或新行值的列。INSERT 触发器无法引用 OLD,DELETE 触发器无法引用 NEW。
  • 如果触发器包含 INSTEAD OF 关键字,则可能不会包含 WHEN 子句。WHEN 子句不能包含子查询。
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;