【原】Oracle-pl/sql-触发器

(注:主要摘自尚硅谷oracle教程笔记)

触发器是许多关系数据系统都提供的一项技术。在 ORACLE 系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的 PL/SQL 块

触发器类型

触发器在数据库里以独立的对象存储,它与存储过程不同的是,存储过程通过其他程序来启动运行或者直接启动运行,而触发器是由一个事件来启动运行。即触发器是当某个事件发生时自动地隐式运行。并且,触发器不能接收参数。所以运行触发器就叫触发或点火。ORACLE 事件指的是对数据库的表进行的 INSERT、UPDATE 及DELETE 操作或对视图进行类似的操作。 ORACLE 将触发器的功能扩展到 触发 ORACLE,如数据库的启动与关闭等

  1. DML 触发器
    ORACLE 可以在 DML 语句进行触发,可以在 DML 操作前或操作后进行触发,并且可以对每个行或语句操作上进行触发。
  2. 替代触发器
    由于在 ORACLE 里,不能直接对由两个以上的表建立的视图进行操作。所有给出了替代触发器。
  3. 系统触发器
    它可以在 ORACLE 数据库系统的事件中进行触发,如 ORACLE 系统的启动与关闭等。

触发器的组成:

  • 触发事件:即在何种情况下触发 TRIGGER;例如: INSERT,UPDATE,DELETE
  • 触发时间:即该 TRIGGER 是在触发事件发生之前(BEFORE)还是之后(AFTER)触发,也就是触发事件和该 TRIGGER 的操作顺序。
  • 触发器本身:即该 TRIGGER 被触发之后的目的和意图,正是触发器本身要做的事情。例如: PL/SQL块
  • 触发频率:说明触发器内定义的动作被执行的次数。即语句级(STATEMENT)触发器和行级(ROW)触发器。语句级(STATEMENT)触发器:是指当某触发事件发生时,该触发器只执行一次;行级(ROW)触发器:是指当某触发事件发生时,对受到该操作影响的每一行数据触发器都单独执行一次。

创建触发器

CREATE [OR REPLACE] TRIGGER Trigger_name
{BEFORE |  AFTER}
{INSERT | DELETE | UPDATE [OF column...]}
ON [schema.]table_name
[FOR EACH ROW]
[WHEN condition]
trigger_body;

其中:BEFORE 和 AFTER 指出触发器的触发时序分别为前触发和后触发方式,前触发是在执行触发事件之前触发当前所创建的触发器,后触发器是在执行触发事件之后触发当前所创建的触发器。
FOR EACH ROW 选项说明触发器为行触发器。行触发器和语句触发器的区别表现在:行触发器要求当一个 DML 语句操作影响数据中的多行数据时,对于其中的每个数据行,只要它们符合触发约束条件,均激活一次出触发器;而语句触发器将整个语句操作作为触发事件,当它符合约束条件时,激活一次触发器。
WHEN 子句说明触发约束条件。Condition 为一个逻辑表达式时,其中必须包含相关名称,而不能包含查询语句,也不能调用 PL/SQL 函数。 WHEN 子句指定的触发约束条件只能用 BEFORE 和 AFTER 行触发器中,不能用在 INSTEAD OF 行触发器和其他类型的触发器中。

当触发器被触发时,要使用被插入、更新或删除的记录中的列值,有时要使用操作前、后的值
实现:

:NEW 修饰符访问操作完成后列的值 
:OLD 修饰符访问操作完成前列的值

示例
一个helloworld级别的触发器

create or replace trigger hello_trigger
after 
update on employees
--for each row
begin 
    dbms_output.put_line('hello...');
    --dbms_output.put_line('old.salary:'||
    	 :OLD.salary||',new.salary'||:NEW.salary);
end;
然后执行:update employees set salary = salary + 1000;

触发器的 helloworld: 编写一个触发器, 在向 emp 表中插入记录时, 打印 'helloworld’

create or replace trigger emp_trigger
after 
insert on emp
for each row
begin
       dbms_output.put_line('helloworld');
end;

行级触发器: 每更新 employees 表中的一条记录, 都会导致触发器执行

create or replace trigger employees_trigger
after 
update on employees
for each row
begin
       dbms_output.put_line('修改了一条记录!');
end;

语句级触发器: 一个 update/delete/insert 语句只使触发器执行一次

create or replace trigger employees_trigger
after 
update on employees
begin
       dbms_output.put_line('修改了一条记录!');
end;

使用 :new, :old 修饰符

create or replace trigger employees_trigger
after 
update on employees
for each row
begin
       dbms_output.put_line('old salary: ' 
       || :old.salary || ', new salary: ' || :new.salary);
end;

编写一个触发器, 在对 my_emp 记录进行删除的时候, 在 my_emp_bak 表中备份对应的记录

create or replace trigger bak_emp_trigger
       before delete on my_emp
       for each row       
begin
       insert into my_emp_bak values(
       :old.id, :old.name, :old.sal);
end; 

你可能感兴趣的:(数据库学习)