目录

触发器

类型

触发器设计原则

DML触发器

创建

触发事件

语句触发器

行触发器

INSTEAD_OF触发器

维护

删除

数据库触发器和存储过程之间的区别


触发器

  • 是特殊的PL/SQL块或存储过程
  • 是基于表、视图、方案、数据库的
  • 是针对特定事件发生时触发的
  • 是隐式执行的

能够更为复杂的控制用户的操作,例如:周末不允许进行离职手续等。

自动处理一些值,例如:账目低于多少钱自动发消息。

类型

应用程序触发器

在应用程序内发生特定DML事件时,将隐式触发它

数据库触发器

在表、视图、方案或数据库上发生特定事件时,将隐式触发它

触发器设计原则

设计触发器为了:

  • 保证当一个指定的操作被执行时,执行相关的动作
  • 集中全局操作

如果触发器的算法很长,将算法创建于存储过程中,再在触发器中调用它们,触发器的大小不能超过32K。过分地使用触发器可能导致复杂的依赖,这在大的应用程序中可能会产生维护困难。

DML触发器

一个触发器语句包含:
触发时间

  • 对于表: BEFORE, AFTER
  • 对于视图: INSTEAD OF

触发事件: INSERT, UPDATE或DELETE
表名: On table、view
触发器类型: Row或statement (只执行一次)
WHEN子句:限制条件,只能在行级触发器中使用
触发器体: PL/SQL块

部分

说明

可能值

触发器时机

当触发器涉及触发事件时的触发时机

BEFORE、AFTER、INSTEAD OF

触发事件

在表或视图上的哪一-个数据操纵操作引发了触发器触发

INSERT、UPDATE、DELETE

触发器类型

触发器体被执行多少次

Sta tement、ROW

触发器体

触发器执行的那些动作

PL/SQL块

创建

语法:

CREATE [OR REPLACE] TRIGGER
    trigger_name
[ BEFOREI AFTER]
[ INSERTI UPDATE [of column] | DELETE]
ON table name
Trigger_body

例子:

员工信息只有在工作日才能进行修改

CREAT OR REPLACE TRIGGER sal_emp
BEFORE INSERT ON emp
BEGIN
    IF(to_char(sysdate),'DY') in ('星期六','星期日')
    then
        raise_application_error(-20001,'只有工作日才能录入数据');
    END IF
END;

INSERT INTO
    emp(empno,ename,job,mgr,hiredate,sal)
VALUES(1002,'ljs','clerk',7902,sysdate,2000);

触发事件

触发事件可以是表上的INSERT、UPDATE或DELETE语句。

当触发事件是一个UPDATE语句时,可以用一个字段列表来确定那些必需触发触发器自来改变的列。不能为INSERT或DELETE语句指定字段列表,因为它们总是影响整个行(...UPDATE OF sal...)。

对于语句触发器,触发事件对于触发器执行一次;对于行触发器,触发事件仅当行被修改时触发。

例如:

java编写数据库触发器 数据库设计触发器_数据库

语句触发器

例子:

create or replace trigger trg_empl_ins
    after insert on empl

begin
    INSERT INTO empl_new (empno, ename,sal)
    VALUES (999, '张三', 3000) ;
end trg_empl_ins;
CREATE TABLE empl_new
AS SELECT *FROM emp
WHERE empno IS
NULL
INSERT INTO empl ( empno, ename, sal)
VALUES (888,'李四',4000)

这样就实现了在两张表同时添加数据了,做成了两张表的同步。一条是insert的一条是触发器添加的。

行触发器

使用关键字for each row

创建语法:

CREATE [OR REPLACE] TRIGGER trigger_ name
[BEFORE | AFTER ]
[ INSERT | UPDATE [of column] | DELETE]
ON table_name
[ REFERENCING OLD as old | NEW as new]
FOR EACH ROW
[WHEN (condition)]
Trigger_body

NEW代表新加的数据,OLD代表老数据。灵活使用,例如删除的时候没有新值,修改时old,new都有。

例子:

CREATE OR REPLACE TRIGGER sal_emp
BEFORE UPDATE OF sal ON emp
FOR EACH ROW
BEGIN
    IF(:new.sal >:old.sa1) THEN
    raise_application_error(-20001,薪水太高了); 
END IF;
END;

UPDATE emp SET sal=5000;

在BEGIN之前不用加冒号,在BEGIN内的语句体内需要加冒号(表示外部变量)

例子:

create or replace trigger trg_emp1_ins_row
    after insert on emp1
    for each row
begin
    INSERT INTO emp_new(empno, ename,sal)
    VALUES ( :NEW. empno, :NEW. ename, :NEW.sal);
end trg_empl_ins_row;

这样也能做成两张相同的表。

注意:回滚时两张表的数据均会回滚掉。COMMIT命令不能出现在触发器中。

INSTEAD_OF触发器

视图上是不能插入数据的,但是如果创建一个instead_of触发器,就可以实现在视图中向表中插入数据。

语法:

CREATE OR REPLACE TRIGGER trigger_name
INSTEAD OF
[INSERT | UPDATE [OF column] | DELETE]
ON view_ ame
[REFERENCING OLD as old | NEW as new]
FOR EACH ROW
Trigger_body

 

维护

ALTER TRIGGER trigger name DISABLE| ENABLE

 例如在提前编好触发器,先禁用掉,等需要的时候上线使用。

删除

DROP TRIGGER trigger_name ;

 另外,当表被删除时,表上的所有触发器都被删除。

数据库触发器和存储过程之间的区别

                             触发器

                              过程

用CREATE TRIGGER定 义

用CREATE PROCEDURE定义

在数据字典USER TRIGGERS中包含源代码

在数据字典USER_SOURCE中包含源代码

隐式调用

显式调用

不允许COMMIT,SAVEPOINT和ROLLBACK

允许COMMIT,SAVEPOINT和ROLLBACK