一,触发器的创建语法解析
触发器创建语法:
--触发器创建语法触发器创建语法的分析:
CREATE [OR REPLACE] TRIGGER trigger_name--触发器名字
{BEFORE|AFTER}--触发时间
{INSERT|UPDATE|DELETE[OF COLUMN]}
ON [schema.]table_name | [shcema.]view_name--触发对象
[REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}]
[FOR EACH ROW ]--触发频率
[WHEN condition]--触发条件
PL/SQL_BLOCK | CALL procedure_name;
(1)CREATE为创建的关键字,[]括起的部分是可以选择的,例如OR REPLACE只有在需要替换原有触发器时,需要加上,
否则,将会先删掉原有触发器,创建同名触发器;
(2)BEFORE和AFTER指明触发器的触发时间,事件执行之前或之后触发触发器;
(3)FOR EACH ROW指明触发频率,当定义成行触发器时,对每行符号要求的数据均激活一次触发器,
语句触发器将整个语句操作作为触发事件,当它符合约束条件时,激活一次触发器。省略FOR EACH ROW 选项时,
BEFORE和AFTER触发器为语句触发器,替代触发器(INSTEAD OF)只能是行级触发器。
(4)REFERENCING子句说明相关名称,在行触发器的 PL/SQL 块和 WHEN 子句中可以使用相关名称参
照当前的新、旧列值,默认的相关名称分别为 OLD 和 NEW。
触发器的 PL/SQL 块中应用相关名称时,必须在它们之前加冒号(:),但在 WHEN 子句中则不能加冒号。
(5)WHEN 子句说明触发约束条件。
每个表最多可以建立12种触发器,主要由INSERT,UPDATE,DELETE与触发时间BEFORE,AFTER组合而成:
--一个表最多建立的12个触发器触发器触发次序:
BEFORE INSERT--插入前(语句级)
BEFORE INSERT FOR EACHE ROW --插入前(行级)
AFTER INSERT --插入后(语句级)
AFTER INSERT FOR EACHE ROW --插入后(行级)
BEFORE UPDATE--更新前(语句级)
BEFORE UPDATE FOR EACHE ROW --更新前(行级)
AFTER UPDATE --更新后(语句级)
AFTER UPDATE FOR EACHE ROW --更新后(行级)
BEFORE DELETE--删除前(语句级)
BEFORE DELETE FOR EACHE ROW --删除前(行级)
AFTER DELETE --删除后(语句级)
AFTER DELETE FOR EACHE ROW --删除后(行级)
1. 执行BEFORE语句级触发器;
2. 对与受语句影响的每一行:
执行 BEFORE 行级触发器;
执行 DML 语句;
执行 AFTER 行级触发器;
3. 执行 AFTER 语句级触发器;
二,DML触发器实例
注意:
:NEW 修饰符访问操作完成后列的值
:OLD 修饰符访问操作完成前列的值
实例1:
--创建触发器在命令窗口中测试触发器:
CREATE OR REPLACE TRIGGER tri_test
BEFORE DELETE--触发时间,在删除时间执行之前
ON mytest--触发对象
FOR EACH ROW--行级触发器
BEGIN--执行部分
DBMS_OUTPUT.PUT_LINE('删除之前执行这段代码');
DBMS_OUTPUT.PUT_LINE(:old.name);--:OLD 修饰符访问操作完成前列的值
END;
实例2:
--限制对表操作日期命令窗口执行:
CREATE OR REPLACE TRIGGER tri_test
BEFORE INSERT OR UPDATE OR DELETE
ON mytest
BEGIN
IF (to_char(SYSDATE,'HH24:MI')) NOT BETWEEN '09:00' AND '18:00' THEN
RAISE_APPLICATION_ERROR(-20001,'大伙还没上班,别动mytest表');
END IF;
END;
实例3:
--创建触发器
CREATE OR REPLACE TRIGGER tri_test
BEFORE UPDATE OF age,NAME OR DELETE--触发事件
ON mytest--触发对象
FOR EACH ROW--行级触发器
WHEN (old.id = 1)--when触发条件:当id=1时触发
BEGIN
dbms_output.put_line('触发器开始执行,执行相关逻辑');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('触发器运行异常');
END;
三,INSTEAD OF(替代触发器)实例
创建触发器语法:
--特别注意,替代触发器是针对视图的
CREATE OR REPLACE TRIGGER trigger_name
INSTEAD OF
{INSERT|UPDATE|DELETE[OF column,....]}
[OR {INSERT|UPDATE|DELETE}[OF column,...]]
ON [SCHEMA.]view_name--这个地方只能定义视图
[REFERENCING {OLD [AS] OLD|NEW [AS] NEW| PARENT [AS] PARENT}]
[FOR EACH ROW]
[WHEN conditon]
使用实例1:
第一步,创建视图:
CREATE OR REPLACE VIEW view_test
AS SELECT * FROM mytest;
第二步,替代触发器使用:
CREATE OR REPLACE TRIGGER tri_inst_test
INSTEAD OF DELETE ON view_test
FOR EACH ROW --只能是行级的
BEGIN
DBMS_OUTPUT.PUT_LINE('替代触发器开始执行了');
DELETE FROM mytest WHERE id = :old.id;
END tri_inst_test;
四,系统触发器实例
CREATE OR REPLACE TRIGGER [sachema.]trigger_name
{BEFORE|AFTER}
{ddl_event_list|database_event_list}
ON {DATABASE|[schema.]SCHEMA}
[WHENcondition]
注意:
ddl_event_list:一个或多个DDL时间,多个用OR隔开;
databa_event_list:一个或多个数据库事件,多个用OR隔开;
用户要在系统中创建系统触发器,需要有管理数据库触发器的权限。
系统触发器的种类和事件出现的时机(前或后):
实例1:
CREATE OR REPLACE TRIGGER tri_ddl实例2,数据库登录或退出时,插入两条测试数据实例:
AFTER DDL ON SCHEMA
BEGIN
DBMS_OUTPUT.PUT_LINE('系统级触发器开始执行处理逻辑');
END tri_ddl;
--登录触发器
CREATE OR REPLACE TRIGGER tri_login
AFTER LOGON ON DATABASE
BEGIN
INSERT INTO mytest VALUES(4,'登录',18);
END tri_login;
--退出触发器将数据库退出,登录,然后看看mytest中的数据状况,看触发器是否创建成功:
CREATE OR REPLACE TRIGGER tri_loginoff
BEFORE LOGOFF ON DATABASE
BEGIN
INSERT INTO mytest VALUES(5,'退出',24);
END tri_loginoff;
根据结果,能知道我们创建的系统触发器成功。
总结:触发器有很多细节,需要在实践中多留心细节。先懂而后深,先广而后专。