Oracle触发器基础
【触发器与触发该触发器的SQL语句同属于一个事务】
触发器不允许发出任何事务控制语句,如commit、rollback、savepoint或者set transaction,它只能随着外部事务的提交、回滚而提交、回滚。
【一点明确的地方】Insert触发器,其中新插入的数据对本事务是可见的。
(但在oracle8i 以及更高的版本中,你可以创建作为自治事务而执行的触发器,在这种情况下,触发器可以做提交或回滚操作,而与触发该触发器的外部SQL所在的事务无关,声明自治事务需要 DECLARE PRAGMA AUTONOMOUS_TRANSACTION,自治事务中需要自己Commit )
【触发器类型】
1、 语句触发器(对insert、update、delete,注意的是无论update多少行,也只会调用一次update语句触发器。)
2、 行触发器(for each row)
3、 instead of 触发器
4、 系统条件触发器(系统事件:数据库启动、关闭,服务器错误)
5、 用户事件触发器(用户事件:用户登陆、注销,create / alter / drop / analyze / audit / grant / revoke / rename / truncate / logoff)
【禁用和启用触发器】
alter trigger <trigger_name> disable;
alter trigger <trigger_name> enable;
【触发器写法】
pl/sql 语句
区别:无论使用before与after,均可读取:old与:new的记录信息
触发时机为before时,能修改:new的记录信息,不能修改:old记录信息
触发时机为after时,:new与:old的信息均不能被修改
BEFORE
To cause the database to fire the trigger before executing the triggering event. For row triggers, the trigger is fired before each affected row is changed.
Restrictions on BEFORE Triggers
BEFORE triggers are subject to the following restrictions:
You cannot specify a BEFORE trigger on a view or an object view.
You can write to the :NEW value but not to the :OLD value.
AFTER
To cause the database to fire the trigger after executing the triggering event. For row triggers, the trigger is fired after each affected row is changed.
Restrictions on AFTER Triggers
AFTER triggers are subject to the following restrictions:
You cannot specify an AFTER trigger on a view or an object view.
You cannot write either the :OLD or the :NEW value.
【实例】
CREATE OR REPLACE TRIGGER usertotemp
AFTER INSERT OR UPDATE OR DELETE
ON user_info
FOR EACH ROW
DECLARE
integrity_error EXCEPTION;
errno INTEGER;
errmsg CHAR (200);
dummy INTEGER;
FOUND BOOLEAN;
BEGIN
IF INSERTING
THEN
INSERT INTO user_info_temp (id, username, password,createdate, status)
VALUES (:new.id, :new.username, :new.password, :new.createdate, :new.status);
ELSIF UPDATING
THEN
UPDATE user_info_temp
SET id = :new.id, username = :new.username, password = :new.password, status = :new.status
WHERE id = :old.id;
ELSIF DELETING
THEN
DELETE FROM user_info_temp
WHERE id = :old.id;
END IF;
EXCEPTION
WHEN integrity_error
THEN
raise_application_error (errno, errmsg);
END;
create sequence foo_seq;
before insert on foo
for each row
begin
select foo_seq.nextval into :new.id from dual;
end;