1.触发器:
CREATE [OR REAPLACE] TRIGGER Trigger_name
{BEFORE | AFTER} Triggering_event ON table_name
{FOR EACH ROW}
[FOLLOWS another_trigger]
[ENABLE/DISABLE]
[WHEN condition]
DECLARE
declaration statements
BEGIN
executable statements
EXCEPTION
exception-handing statements
END;
BEFORE 或者 AFTER 指明何时触发器执行,即在触发事件发生之前,还是之后。
子句 FOR EACH ROW 指定行触发器,只适用于所插入、修改或者删除的数据行。
使用FOLLOWS 选项,可以指定触发器被触发的顺序,这个选项适用于在相同 表上所定义的,并且在相同时间点会执行的触发器。
如不使用 [ENABLE / DISABLE ] 子句 , 为禁用或启用触发器,需要执行ALTER TRIGGER 命令:
ALTER TRIGGER trigger_name DISABLE/ENABLE;
如果删除一个表,则在该表上所定义的数据库触发器也会被删除 。触发器是定义于数据库表的。
不允许在触发器体中声明LONG 或者 LONG RAW 变量。
例如 :
CREATE OR REPLACE TRIGGER student_bi
BEFORE INSERT ON student
FOR EACH ROW
BEGIN
:NEW.student_id := STUDENT_ID_SEQ.NEXTVAL;
:NEW.created_by := USER;
:NEW.created_date :=SYSDATE;
:NEW.modified_by := USER;
:NEW.modified_date := SYSDATE;
END;
触发器体中包含伪记录::NEW,使得你可以访问当前正在被处理的数据行。:NEW 伪记录是一种TRIGGERING_TABLE%TYPE,所以在这种情况下,这是student%TYPE的类型。为访问伪记录:NEW 的单独成员,需要使用点符号。
CREATE OR REPLACE TRIGGER instructor_aud
AFTER UPDATE OR DELETE ON INSTRUCTOR
DECLARE
v_type VARCHAR2(10);
BEGIN
IF UPDATING THEN
v_type := 'UPDATE';
ELSIF DELETING THEN
v_type := 'DELETE';
END IF;
UPDATE statistics
SET transaction_user=USER,
transaction_date=SYSDATE
WHERE table_name = 'INSTRUCTOR' AND transaction_name=v_type;
IF SQL%NOTFOUND THEN
INSERT INTO statistics
VALUES('INSTRUCTOR',v_type,USER,SYSDATE);
END IF;
END;
------------------------------------------------------------------------------------
CREATE TRIGGER student_au
AFTER UPDATE ON STUDENT
FOR EACH ROW
WHEN (NVL(NEW.ZIP,' ') <> OLD.ZIP )
UPDATE student
SET zip='01247' WHERE zip='02189'
使用伪记录:OLD 可以访问当前被处理的数据行。 当在WHEN 语句 的条件中使用时,:NEW 和:OLD 都不再使用冒号作为前缀 。
:NEW 标识被更新的值,:OLD 标识被更新之前的那个值。所以:ZIP列的值01247 是个新值,用:NEW.ZIP 来引用它。02189 是ZIP 列的先前值,使用:OLD.ZIP 来引用。
CREATE OR REPLACE TRIGGER instructor_biud
DEFORE INSERT OR UPDATE OR DELETE ON INSTRUCTOR
DECLARE
v_day VARCHAR2(10);
BEGIN
v_day := RTRIM(TO_CHAR(SYSDATE, 'DAY' ));
IF v_day LIKE ('S%') THEN
RAISE_APPLICATION_ERROR(-20000, 'A table cannot be modified during off hours ');
END IF;
END;
创建针对 视图(VIEW) 的 INSTEAD OF 触发器
CREATE VIEW student_address AS
SELECT s.student_id, s.first_name, s.last_name, s.street_address, z.city, z.state, z.zip
FROM student s JOIN zipcode z ON (s.zip= z.zip );
CREATE OR REPLACE TRIGGER student_address_ins
INSTEAD OF INSERT ON student_address
FOR EACH ROW
BEGIN
INSERT INTO STUDENT
(student_id,first_name,last_name,street_address,zip,registration_date,created_by,created_date,
modified_by,modified_date)
VALUES(:NEW.student_id , :NEW.first_name, :NEW.last_name,:NEW.street_address,
:NEW.zip, SYSDATE, USER , SYSDATE , USER, SYSDATE );
END;