触发器
触发器可以看作特殊的存储过程,它定义了一些与数据库相关事件(如INSERT、UPDATE、DELETE等)发生时应执行的功能代码块,通常用于管理复杂的完整性约束,或监控对表的修改,或通知其它程序,甚至可以实现对数据的审计功能。
触发器组成:
触发事件:引起触发器被触发的事件。 例如:DML语句(INSERT, UPDATE, DELETE语句对表或视图执行数据处理操作)、DDL语句(如CREATE、ALTER、DROP语句在数据库中创建、修改、删除模式对象)、数据库系统事件(如系统启动或退出、异常错误)、用户事件(如登录或退出数据库)。
触发时间:即该TRIGGER 是在触发事件发生之前(BEFORE)还是之后(AFTER)触发,也就是触发事件和该TRIGGER 的操作顺序。
触发操作:即该TRIGGER 被触发之后的目的和意图,正是触发器本身要做的事情。 例如:PL/SQL 块。
触发对象:包括表、视图、模式、数据库。只有在这些对象上发生了符合触发条件的触发事件,才会执行触发操作。
触发条件:由WHEN子句指定一个逻辑表达式。只有当该表达式的值为TRUE时,遇到触发事件才会自动执行触发器,使其执行触发操作。
触发频率:说明触发器内定义的动作被执行的次数。即语句级(STATEMENT)触发器和行级(ROW)触发器。
语句级(STATEMENT)触发器:是指当某触发事件发生时,该触发器只执行一次;
行级(ROW)触发器:是指当某触发事件发生时,对受到该操作影响的每一行数据,触发器都单独执行一次。
创建触发器语法
create [or replace] trigger tri_name
[before | after | instead of] tri_event
on table_name | view_name | user_name | db_name
[for each row [when tri_condition]
begin
plsql_sentences;
end tri_name;
条件谓词(由关键字if或elsif和谓词inserting、updating、deleting组成)
行级(ROW)触发器:是指当某触发事件发生时,对受到该操作影响的每一行数据,触发器都单独执行一次。必须在语法中使用for each row。典型应用----给数据表生成主键值。
创建一个序列:
CREATE SEQUENCE seq_course_id; -- 创建一个行级触发器,该触发器在数据表tb_course插入数据时被触发,并且在该触发器的主体中实现课程表的id列的值 CREATE OR REPLACE TRIGGER TRI_INSERT_COURSE BEFORE INSERT ON TB_COURSE FOR EACH ROW BEGIN SELECT SEQ_COURSE_ID.NEXTVAL INTO :new.cos_id FROM DUAL; END;
列标识符
:NEW 新值标识符(操作完成后列的值)
:OLD 原值标识符(操作完成前列的值)
替换触发器——即instead of触发器,它的“触发时机”关键字是instead of,而不是before或after。与其它类型触发器不同是,替换触发器定义在视图(一种数据库对象,在后面章节中会讲解到)上的,而不是定义在表上。由于视图是由多个基表连接组成的逻辑结构,所以一般不允许用户进行DML操作(如insert、update、delete等操作),这样当用户为视图编写“替换触发器”后,用户对视图的DML操作实际上就变成了执行触发器中的PL/SQL语句块,这样就可以通过在“替换触发器”中编写适当的代码对构成视图的各个基表进行操作。
程序包
程序包由PL/SQL元素组成(变量,类型,匿名pl/sql,存储过程,函数)组成,程序包可以被整体加载到内存,这加快了程序包中任何一个组成部分的访问速度。程序包通常由规范和主体组成。
该“规范”用于规定在程序包中可以使用哪些变量、类型、游标和子程序(指各种命名的PL/SQL块),需要注意的是:程序包一定要在“包主体”之前被创建,其语法格式如下:
create [or replace ] package pack_name is [declare_variable]; [declare_type]; [declare_cursor]; [declare_function]; [declare_ procedure]; end [pack_name];
与创建“规范”不同的是,创建“程序包主体”使用CREATE PACKAGE BODY语句,而不是CREATE PACKAGE,这一点需要读者注意,创建程序包主体的代码如下:
create [or replace] package body pack_name is [inner_variable] [cursor_body] [function_title] {begin fun_plsql; [exception] [dowith _ sentences;] end [fun_name]} [procedure_title] {begin pro_plsql; [exception] [dowith _ sentences;] end [pro_name]} … end [pack_name];