触发器
触发器是当特定事件出现时自动执行的存储过程
特定事件可以是执行更新的DML语句和DDL语句
触发器不能被显式调用
触发器的功能:
1. 自动生成数据
2. 自定义复杂的安全权限
3. 提供审计和日志记录
4. 启用复杂的业务逻辑
创建触发器的语法
CREATE [OR REPLACE] TRIGGER trigger_name
AFTER | BEFORE | INSTEAD OF
[INSERT] [[OR] UPDATE [OFcolumn_list]]
[[OR] DELETE]
ON table_or_view_name
[REFERENCING {OLD [AS] old / NEW [AS] new}]
[FOR EACH ROW]
[WHEN ( condition ) ]
pl/sql_block;
:new or :old
触发器由三部分组成:
触发器语句(事件)
1. 定义激活触发器的 DML 事件和 DDL事件
触发器限制
1. 执行触发器的条件,该条件必须为真才能激活触发器
触发器操作(主体)
1. 包含一些 SQL 语句和代码,它们在发出了触发器语句且触发限制的值为真时运行
触发器的工作原理
更新------>表-----触发----触发器----->保存更新
创建触发器
CREATE OR REPLACE TRIGGER aiu_itemfile
AFTER INSERT --触发时间:after;触发事件是insert
ON itemfile
FOR EACH ROW --每一行
BEGIN
IF(:NEW.qty_hand = 0) THEN
DBMS_OUTPUT.PUT_LINE('警告:已插入记录,但数量为零');
ELSE
DBMS_OUTPUT.PUT_LINE(‘已插入记录');
ENDIF;
END;
例:禁止工作人员在休息日改变员工信息
CREATE ORREPLACE TRIGGER TR_SEC_EMP
BEFORINSERT OR UPDATE OR DELETE ON EMP2
BEGIN
IF TO_CHAR(SYSDATE,’DY’,‘nls_date_language=AMERICAN’) IN (‘SAT’, ‘SUN’) THEN
RAISE_APPLICATION_ERROR(-20002,’禁止修改数据!’);
END IF;
END;
触发器的类型有:
模式DDL触发器,数据库级触发器,DDL触发器(行级、语句级、instead of级)
触发器组成:
l 触发事件:引起触发器被触发的事件。例如:DML语句(INSERT, UPDATE, DELETE语句对表或视图执行数据处理操作)、DDL语句(如CREATE、ALTER、DROP语句在数据库中创建、修改、删除模式对象)、数据库系统事件(如系统启动或退出、异常错误)、用户事件(如登录或退出数据库)。
l 触发时间:即该TRIGGER是在触发事件发生之前(BEFORE)还是之后(AFTER)触发,也就是触发事件和该TRIGGER的操作顺序。
l 触发操作:即该TRIGGER被触发之后的目的和意图,正是触发器本身要做的事情。例如:PL/SQL 块。
l 触发对象:包括表、视图、模式、数据库。只有在这些对象上发生了符合触发条件的触发事件,才会执行触发操作。
l 触发条件:由WHEN子句指定一个逻辑表达式。只有当该表达式的值为TRUE时,遇到触发事件才会自动执行触发器,使其执行触发操作。
l 触发频率:说明触发器内定义的动作被执行的次数。即语句级(STATEMENT)触发器和行级(ROW)触发器。
语句级(STATEMENT)触发器:是指当某触发事件发生时,该触发器只执行一次;行级(ROW)触发器:是指当某触发事件发生时,对受到该操作影响的每一行数据,触发器都单独执行一次。
注意:触发器不接受参数。
l 一个表上最多可有12个触发器,但同一时间、同一事件、同一类型的触发器只能有一个。并各触发器之间不能有矛盾。
l 在一个表上的触发器越多,对在该表上的DML操作的性能影响就越大。
l 触发器最大为32KB。若确实需要,可以先建立过程,然后在触发器中用CALL语句进行调用。
l 在触发器的执行部分只能用DML语句(SELECT、INSERT、UPDATE、DELETE),不能使用DDL语句(CREATE、ALTER、DROP)。
l 触发器中不能包含事务控制语句(COMMIT,ROLLBACK,SAVEPOINT)。因为触发器是触发语句的一部分,触发语句被提交、回退时,触发器也被提交、回退了。
l 在触发器主体中调用的任何过程、函数,都不能使用事务控制语句。
l 在触发器主体中不能申明任何Long和blob变量。新值new和旧值old也不能向表中的任何long和blob列。
l 不同类型的触发器(如DML触发器、INSTEAD OF触发器、系统触发器)的语法格式和作用有较大区别。
语句级触发器
CREATE OR REPLACE TRIGGER trgdemo
AFTER INSERT OR UPDATE OR DELETE
ONorder_master
BEGIN
IFUPDATING THEN
DBMS_OUTPUT.PUT_LINE(‘已更新 ORDER_MASTER中的数据');
ELSIF DELETING THEN
DBMS_OUTPUT.PUT_LINE(‘已删除 ORDER_MASTER中的数据');
ELSIF INSERTING THEN
DBMS_OUTPUT.PUT_LINE(‘已在 ORDER_MASTER中插入数据');
END IF;
END;
行触发器和语句触发器的区别表现在:行触发器要求当一个DML语句操走影响数据库中的多行数据时,对于其中的每个数据行,只要它们符合触发约束条件,均激活一次触发器;而语句触发器将整个语句操作作为触发事件,当它符合约束条件时,激活一次触发器。当省略FOR EACH ROW选项时,BEFORE 和AFTER触发器为语句触发器,而INSTEAD OF 触发器则只能为行触发器
模式触发器
SQL> CREATE TABLE dropped_obj (
obj_name VARCHAR2(30),
obj_type VARCHAR2(20),
drop_date DATE);
SQL> CREATE OR REPLACE TRIGGERlog_drop_obj
AFTER DROP ON SCHEMA
BEGIN
INSERT INTO dropped_obj
VALUES( ORA_DICT_OBJ_NAME,
ORA_DICT_OBJ_TYPE, SYSDATE);
END;
启用和禁用触发器
ALTER TRIGGER aiu_itemfile DISABLE;
ALTER TRIGGER aiu_itemfile enable;
内置程序包
扩展数据库的功能
为PL/SQL 提供对SQL 功能的访问
用户SYS 拥有所有程序包
是公有同义词
可以由任何用户访问
STANDARD和DBMS_STANDARD |
定义和扩展PL/SQL语言环境 |
DBMS_LOB |
提供对LOB数据类型进行操作的功能 |
DBMS_OUTPUT |
处理PL/SQL块和子程序输出调试信息 |
DBMS_RANDOM |
提供随机数生成器 |
DBMS_SQL |
允许用户使用动态SQL |
DBMS_XMLDOM |
用DOM模型读写XML类型的数据 |
DBMS_XMLPARSER |
XML解析,处理XML文档内容和结构 |
DBMS_XMLQUERY |
提供将数据转换为XML类型的功能 |
DBMS_XSLPROCESSOR |
提供XSLT功能,转换XML文档 |
UTL_FILE |
用PL/SQL程序来读写操作系统文本文件 |
DBMS_OUTPUT包显示 PL/SQL块和子程序的调试信息。
SQL> SET SERVEROUTPUT ON
SQL> BEGIN
DBMS_OUTPUT.PUT_LINE('打印三角形');
FORi IN 1..9 LOOP
FOR j IN 1..i LOOP
DBMS_OUTPUT.PUT('*');
END LOOP for_j;
DBMS_OUTPUT.NEW_LINE;
ENDLOOP for_i;
END;
UTL_FILE 包用于读写操作系统文本文件
操作文件的一般过程是打开、读或写、关闭
UTL_FILE 包指定文件路径依赖于 DIRECTORY对象
总结:
触发器是当特定事件出现时自动执行的存储过程
触发器分为 DML触发器、DDL 触发器和数据库级触发器三种类型
DML 触发器的三种类型包括行级触发器、语句级触发器和 INSTEAD OF触发器
一些常用的内置程序包:
1. DBMS_OUTPUT 包输出 PL/SQL 程序的调试信息
2. DBMS_LOB 包提供操作LOB 数据的子程序
3. DBMS_XMLQUERY 将查询结果转换为 XML 格式
4. DBMS_RANDOM 提供随机数生成器
5. UTL_FILE 用于读写操作系统文本文件