`

Oracle触发器介绍

阅读更多

语句级触发器
我们先看一个AFTER-INSERT-STATEMENT触发器
CREATE OR REPLACE TRIGGER temp_ais
AFTER INSERT ON TEMP
BEGIN
    dbms_output.put_line('executing temp_ais');
END;
看一下下面语句的结果:
SQL> set feedback off
SQL> INSERT INTO temp VALUES (1);          -- insert 1 row
executing temp_ais
SQL> INSERT INTO temp VALUES (1);          -- insert 1 row
executing temp_ais
SQL> INSERT INTO temp SELECT * FROM temp; -- insert 2 rows
executing temp_ais

每个SQL插入语句将触发一次,行级触发器最后一条语句要触发两次。
一、事件顺序
用Insert 语句级触发器可以做:
    ·可以在表上执行一个合计运算,可以在insert前或后来计算。
    ·可以使用语句级触发器去处理行级触发器控制的数据。
    ·可以给事件发信号。可以仅仅是一个打印语句。也可以是一个email或使用DBMS_ALERT包向其他处理过程发送信号。
                                                                                                   Tasks Performed
                                         Stages                                           -------------------
                             ---------------------------------- ———> |   Rehect the     |
Fires once         |   BIS function                    |                    |   Transaction    |
per statement    | Statement Level Trigger |                    -------------------
                               ----------------------------------- ———>    -------------------
                                         |                                                       | Take Action     |
                                         |                                                        -------------------
   insert                            |
   3行记录        |    --------------------------                   |    
     ————> |    |    Row Trigger       |                   |    -------------------------------
     ————> |    --------------------------                  |    |每一个行触发器插入一|
     ————> |                |                                          |    |行触发一次,插入三行|
                       | ----------------------------------------   |     |触发三次,语句级触发|
                          | | Oracle enforces constraints | |    |器在行操作和行数据上|
                         | ---------------------------------------- |    |不可见                            |
                         |                |                                         |    |                                        |
                        |    --------------------------                    |    -------------------------------
                         |    |    Row Trigger          |                |    
                          |    --------------------------                   |        
                                       |
                                         |                                                          ----------------------
                                ---------------------------------- ————> |   Rehect the     |
Fires once          |   AIS function                     |                       |   Transaction    |
per statement    | Statement Level Trigger |                        ---------------------
                             ---------------------------------- ————>   --------------------
                                                                                                  | Take Action |
                                                                                                  --------------------  

上图显示了语句级出发器的行为。同时也显示了在Before statement触发器和After statement触发器间的行级触发器的触发情况。如果一个update SQL语句更新三行,那么行级触发器触发三次,语句级触发器触发一次。

二、insert 语句级触发器定义语法
语法如下:
CREATE OR REPLACE TRIGGER trigger_name
[AFTER | BEFORE] INSERT ON table_name
DECLARE
    Local declarations
BEGIN
    Body written PL/SQL
END;

语句级和行级触发器在语法上关键的不同在于:FOR EACH ROW字句。在行级触发器中指定这个子句而语句级触发器中不需要指定。

1)、WHEN(Boolean expression) 所有行触发器可用
2)、OF column_name clause     仅对update触发器可用
在语句级触发器中:
·引用:NEW.COLUMN_NAME and :OLD.COLUMN_NAME是不正确的。
·不能使用When(boolean expression)子句中包含OLD.COLUMN_NAME和 NEW.COLUMN_NAME.

可以使用下面的语句:
CREATE OR REPLACE TRIGGER temp_biuds
BEFORE INSERT OR UPDATE OR DELETE ON TEMP
BEGIN
     CASE
     WHEN inserting THEN
         PL/SQL code here
     WHEN updating THEN
         PL/SQL code here
     WHEN deleting THEN
         PL/SQL code here
     END CASE;
END;
三、语句级组合

   ·使用错误码来更新Errors包
   ·包商业规则逻辑放到一个约束包中
   ·编写before或after语句级触发器
  
1)、第一步是声明错误码和错误信息。Errors包更新包含了-20002和-2003两个错误码
CREATE OR REPLACE PACKAGE errors IS
     eng_dept_sal CONSTANT PLS_INTEGER := -20001;
     app_error_02 CONSTANT PLS_INTEGER := -20002;
     app_error_03 CONSTANT PLS_INTEGER := -20003;

     eng_dept_sal_txt CONSTANT VARCHAR2(100) :=
     'The salary exceeds the ENGL maximum of $10,000.00';

     app_error_02_txt CONSTANT VARCHAR2(100) :=
     'No additions if the budget exceeds $55,000.00';

     app_error_03_txt CONSTANT VARCHAR2(100) :=
     'Budget cannot be over $60,000.00';
END errors;
2)、把商业逻辑封装在约束包中。
    CREATE OR REPLACE PACKAGE professors_cons IS
     PROCEDURE constrain_budget
         (limit NUMBER,err_code PLS_INTEGER,err_text
         VARCHAR2);
END professors_cons;

CREATE OR REPLACE PACKAGE BODY professors_cons IS
     PROCEDURE constrain_budget
         (limit NUMBER,err_code PLS_INTEGER,err_text
         VARCHAR2)
     IS
         budget_sum NUMBER;
     BEGIN
         SELECT SUM(salary) INTO budget_sum FROM
         professors;
         IF budget_sum > limit THEN
             RAISE_APPLICATION_ERROR(err_code, err_text);
         END IF;
     END constrain_budget;
END professors_cons;
3)、定义before和after触发器
    CREATE OR REPLACE TRIGGER professors_bis
BEFORE INSERT OR UPDATE ON professors
BEGIN
     professors_cons.constrain_budget
         (55000, errors.budget_err_1,
         errors.budget_err_1_txt);
END;

CREATE OR REPLACE TRIGGER professors_ais
AFTER INSERT OR UPDATE ON professors
BEGIN
     professors_cons.constrain_budget
         (60000, errors.budget_err_2,
         errors.budget_err_2_txt);
END;

四、处理行获得的数据
行级触发器可以在全局临时表中存储:OLD 和 :NEW 字段值。全局临时表范围仅是事务。通过复制:OLD 和 :NEW 值,商业规则的处理被延期到语句级触发器上。有时是必须的,因为商业规则是复杂的,需要从表中查询,包括表被更新。
1)、首先需要一个全局临时表,它在行级触发器上用于存储数据。
CREATE global temporary TABLE professors_g
(prof_name     VARCHAR2(10),
specialty     VARCHAR2(20),
hire_date     DATE,
salary        NUMBER(7,2),
tenure        VARCHAR2(3),
department    VARCHAR2(10)) ON COMMIT DELETE ROWS;
2)、为这张表编写存储过程,放于包Professors_cons里.如下:
CREATE OR REPLACE PACKAGE professors_cons IS
    PROCEDURE load_temp_table
        (v_prof_name professors.prof_name%TYPE,
         v_specialty professors.specialty%TYPE,
         v_hire_date professors.hire_date%TYPE,
         v_salary     professors.salary%TYPE,
         v_tenure     professors.tenure%TYPE,
         v_department professors.department%TYPE);

    PROCEDURE dump_temp_table;

END professors_cons;
包体为:
CREATE OR REPLACE PACKAGE BODY professors_cons IS

    PROCEDURE load_temp_table
        (v_prof_name professors.prof_name%TYPE,
         v_specialty professors.specialty%TYPE,
         v_hire_date professors.hire_date%TYPE,
         v_salary     professors.salary%TYPE,
         v_tenure     professors.tenure%TYPE,
         v_department professors.department%TYPE)
    IS
    BEGIN
        INSERT INTO professors_g VALUES
            (v_prof_name, v_specialty, v_hire_date,
             v_salary, v_tenure, v_department);
    END load_temp_table;

    PROCEDURE dump_temp_table IS
    BEGIN
        FOR rec in (SELECT * FROM professors_g) LOOP
            dbms_output.put_line(
                rec.prof_name||' '||rec.specialty||' '||
                rec.hire_date||' '||rec.salary||' '||
                rec.tenure||' '||rec.department);
        END LOOP;
    END dump_temp_table;
END professors_cons;

3)、下面是一个after delete 行触发器。当它触发时,通过Professors_cons插入临时表一行数据。
CREATE OR REPLACE TRIGGER professors_adr
AFTER DELETE ON professors
FOR EACH ROW
BEGIN
    professors_cons.load_temp_table
        (:old.prof_name, :old.specialty, :old.hire_date,
         :old.salary, :old.tenure, :old.department);
END;

下一个是after delete语句级触发器,使用约束包打印删除的行信息。
CREATE OR REPLACE TRIGGER professors_ads
AFTER DELETE ON professors
BEGIN
    professors_cons.dump_temp_table;
END;

delete SQL语句后面是语句级触发器的输出:

SQL> DELETE FROM professors;

Blake Mathematics 08-aug-2003 02:06:27 10000 YES MATH
Milton Am Hist 09-aug-2003 02:06:27 10000 YES HIST
Wilson English 06-aug-2003 02:06:27 10000 YES ENGL
Jones Euro Hist 12-jul-2003 02:06:28 10000 YES HIST
Crump Ancient Hist 12-jul-2003 02:06:28 10000 YES HIST

5 rows deleted.

分享到:
评论

相关推荐

    调试oracle触发器方法

    调试Oracle触发器是开发和维护数据库应用程序时的重要步骤,可以帮助我们找出潜在的错误和逻辑问题。下面我们将详细探讨如何调试Oracle触发器。 1. **PL/SQL Developer工具调试**: - PL/SQL Developer是一款强大...

    oracle 触发器实时调用java 中http接口

    总之,"Oracle触发器实时调用Java中HTTP接口"是一个数据库与应用程序实时通信的示例,涉及Oracle的触发器、存储过程和UTL_HTTP包,以及Java HTTP服务器的设计和实现。这样的设计需要对Oracle PL/SQL和Java网络编程有...

    关于oracle触发器before和after的应用问题

    ### Oracle触发器Before和After应用详解 #### 引言 Oracle数据库系统中,触发器是一项核心功能,用于响应特定事件的自动执行代码块。本文旨在深入解析Oracle触发器中的Before和After两种触发时机,以及它们在...

    个人亲测oracle触发器调用java程序

    在本文中,我们将介绍如何使用Oracle触发器调用Java程序。 一、加载Java程序 首先,我们需要将Java程序加载到Oracle数据库中。我们可以使用LOADJAVA命令来实现这一步骤。LOADJAVA命令位于$ORACLE_HOME/bin目录下,...

    Oracle触发器修改自身表

    1、行级触发器不支持 update 、select 、delete 对自身表的操作。 2、表级触发器 不支持 :new 和 :old对象 所以想要触发器对自身表数据做修该,则用行级触发器得到 :new 和 :old对象中的相关数据,然后将这样的数据...

    Oracle触发器语法详解

    "Oracle触发器语法详解" Oracle 触发器是一种特殊的存储过程,它在插入、删除或修改特定表中的数据时触发执行,它比数据库本身标准的功能有更精细和更复杂的数据控制能力。触发器可以基于数据库的值使用户具有操作...

    oracle_触发器的种类和触发事件

    "oracle触发器的种类和触发事件" Oracle触发器是一种特殊的存储过程,它可以在数据库中自动执行一些操作,主要用于实现数据的完整性、数据的安全性和业务逻辑的实现。触发器可以分为四种类型:DML触发器、DDL触发器...

    oracle触发器的创建与使用

    【Oracle触发器的创建与使用】是数据库管理中不可或缺的一部分,尤其在Oracle数据库系统中,触发器扮演着关键角色。触发器是一种存储过程,当特定的数据库事件发生时(如INSERT、UPDATE或DELETE操作),它会被自动...

    Oracle触发器与存储过程高级编程-第3版itpub.rar

    《Oracle触发器与存储过程高级编程》第3版是一本深入探讨Oracle数据库中触发器和存储过程技术的专业书籍。在Oracle数据库系统中,触发器和存储过程是数据库管理员和开发人员进行复杂业务逻辑处理和数据管理的重要...

    oracle触发器功能介绍

    Oracle触发器是数据库对象之一,它在特定的数据库操作(如INSERT、UPDATE或DELETE)发生时自动执行。触发器主要用于实现复杂的业务规则和数据验证,它们可以扩展SQL的功能,允许在数据修改前后执行一系列的动作。...

    Oracle触发器实验报告

    Oracle触发器是数据库管理系统中的一种特殊程序,它与数据库表的操作紧密相关,可以在特定的数据操作事件(如INSERT、UPDATE或DELETE)发生时自动执行。在本实验报告中,主要涉及了Oracle触发器与参照完整性约束的...

    利用 Oracle 系统触发器防止误删除表操作

    以下详细介绍两种不同的Oracle版本(10g和8i)下如何创建相应的系统触发器。 ### Oracle 10g环境下的解决方案 在Oracle 10g环境中,可以创建一个系统级别的触发器,用于阻止非`SYS`用户执行`DROP TABLE`或`...

    Oracle触发器 实例讲解

    Oracle 触发器实例讲解 Oracle 触发器是一种特定事件出现的时候,自动执行的代码块。类似于存储过程,但是用户不能直接调用他们。它主要有以下几个功能: 1. 允许/限制对表的修改:触发器可以控制对表的修改操作,...

    Oracle触发器备份表数据

    在深入探讨如何利用Oracle触发器备份表数据之前,我们首先需要理解几个关键概念:Oracle数据库、触发器以及备份策略。Oracle数据库是全球领先的数据库管理系统之一,以其强大的性能、可靠的安全性和丰富的功能受到...

    oracle触发器调用存储过程

    "Oracle触发器调用存储过程" Oracle触发器可以调用存储过程,以实现业务逻辑的自动化执行。然而,在触发器中调用存储过程时,需要注意事务的隔离性,以避免出现锁定和死锁的问题。Oracle自治事务(Autonomous ...

    oracle触发器语法要点

    ### Oracle触发器语法要点 #### 一、触发器概述 Oracle触发器是一种存储过程,它在特定的数据库事件(如INSERT、UPDATE或DELETE)发生时自动执行。触发器可以用于实施复杂的业务规则、数据完整性检查或者自动生成...

    oracle触发器执行顺序.pdf

    Oracle触发器可以响应数据表的DML(数据操纵语言)事件,如INSERT、UPDATE或DELETE,也可以响应DDL(数据定义语言)事件,如CREATE、ALTER或DROP等。在本文件中,主要讨论的是针对数据表UPDATE操作的触发器执行顺序...

    Oracle 触发器与存储过程高级编程 上

    Oracle触发器与存储过程高级编程 中文 PDF

    Oracle触发器与存储过程高级编程

    在深入探讨《Oracle触发器与存储过程高级编程》这一主题之前,我们首先应当明确Oracle数据库在企业级应用中的核心地位。Oracle数据库以其强大的数据处理能力、高可用性和安全性,成为众多大型企业和组织首选的数据...

    Oracle触发器里调用Java程序

    本篇文章将探讨如何在Oracle触发器中调用Java程序,以扩展数据库的功能并利用Java丰富的库资源。 首先,我们需要了解Oracle的PL/SQL(Procedural Language/Structured Query Language)语言,它是Oracle数据库内置...

Global site tag (gtag.js) - Google Analytics