我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Oracle专题16之触发器

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Oracle专题16之触发器

1、触发器的概述

a、触发器是什么?

  • 触发器是指存放在数据库中,并且被隐含执行的存储过程。
  • 当发生特定事件时,Oracle会自动执行触发器的相应代码。

    b、触发器的类型

  • DML触发器;DDL触发器;替代(instead of)触发器;系统触发器。

    c、触发器的组成

    1、触发事件:即在何种情况下触发TRIGGER。
    2、触发时间:即该TRIGGER是在触发事件发生之前(BEFORE)还是之后(AFTER)触发。
    3、触发器本身:即该TRIGGER被触发之后的目的和意图,正是触发器本省要做的事情。
    4、触发频率:说明触发器内定义的动作被执行的次数。

    d、创建第一个触发器

  • 示例:每次执行删除操作之后,都会信息提示:“这是删除操作!”

    SQL> --当对emp01表执行删除操作之后,它就会出现一个提示信息,提示:这是删除操作
    SQL> CREATE TRIGGER first_trigger
        2  AFTER DELETE
        3  ON emp01
        4  BEGIN
        5     DBMS_OUTPUT.put_line('这是删除操作!');
        6  END;
        7  /
    
    Trigger created
    
    SQL> SET SERVEROUTPUT ON
    SQL> DELETE FROM emp01 WHERE empno = 7782;
    
    这是删除操作!
    1 row deleted

    2、DDL触发器

    a、什么是DDL触发器?

  • 当创建、修改或者删除数据库对象时,也会引起相应的触发器操作事件,而此时就可以利用触发器来对这些数据库对象的DDL操作进行监控。

    b、创建DDL触发器的语法格式

    CREATE [OR REPLACE] TRIGGER 触发器的名称
    [BEFORE  | AFTER | INTEAD OF ] [DDL事件] ON [DATABASE | SCHEMA] 
    [WHEN 触发条件] 
    [DECLARE] 
        [程序的声明部分;] 
    BEGIN
        程序的代码部分
    END;
    /

    c、DDL事件描述和触发时机

    Oracle专题16之触发器

    d、代码示例1:禁止scott用户的触发器操作

  • 禁止scott用户的DDL操作

    SQL> CREATE OR REPLACE TRIGGER scott_trigger
        2  BEFORE DDL
        3  ON SCHEMA
        4  BEGIN
        5     RAISE_APPLICATION_ERROR(-20005, 'scott用户禁止所有的DDL操作');
        6  END;
        7  /
    
    Trigger created
    
    SQL> CREATE SEQUENCE test_seq;
    CREATE SEQUENCE test_seq
    
    ORA-00604: 递归 SQL 级别 1 出现错误
    ORA-20005: scott用户禁止所有的DDL操作
    ORA-06512: 在 line 2
  • 注意:RAISE_APPLICAITON_ERROR是用来测试的异常处理,能够将应用程序专有的错误从服务器端转达到客户端应用程序中(其他机器上的SQLPlus或者其他前台开发语言),其存储过程有两个参数,如:
    RAISE_APPLICAITON_ERROR(error_number_in IN NUMBER, error_msg_in IN VARCHAR2);
    -- error_msg_in的长度不能超过2k,超过2k后会进行截取

    e、代码示例2:实现对数据库对象操作的日志记录

  • 分解成三个步骤:
    1、创建数据库对象DDL操作日志记录表;2、创建实现对数据库对象DDL操作记录的触发器;3、测试。

    SQL> connect system/02000059 as sysdba;
    Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 
    Connected as system AS SYSDBA
    
    SQL> CREATE TABLE object_log(   --创建数据库对象DDL操作日志记录表
        2  logid number constraint pk_logid primary key,
        3  operatedate date not null,
        4  objecttype varchar2(50) not null,
        5  objectowner varchar2(50) not null);
    
    Table created
    
    SQL> CREATE SEQUENCE object_log_seq;  
    
    Sequence created
    
    SQL> CREATE OR REPLACE TRIGGER ojbect_trigger  --创建实现对数据库对象DDL操作记录的触发器
        2  AFTER CREATE OR DROP OR ALTER
        3  ON DATABASE
        4  BEGIN
        5     INSERT INTO object_log(logid, operatedate, objecttype, objectowner) VALUES (object_log_seq.nextval, sysdate, ora_dict_obj_type, ora_dict_obj_owner);
        6  END;
        7  /
    
    Trigger created
    
    SQL> CREATE SEQUENCE test_seq;  --测试
    
    Sequence created
    
    SQL> select * from object_log;
    
             LOGID OPERATEDATE OBJECTTYPE                                         OBJECTOWNER
    ---------- ----------- -------------------------------------------------- --------------------------------------------------
                     1 2017/12/21  SEQUENCE                                           SYS
  • 注意:此DDL触发器事件示例中的使用了两个属性函数(之前未使用):
  • ORA_DICT_OBJ_OWNER:触发DDL的数据库对象的用户;ORA_DICT_OBJ_TYPE:触发DDL的数据库对象的类型。

    3、DML触发器

    a、什么是DML触发器?

  • DML触发器是指基于DML操作所建立的触发器。

    b、DML触发器的作用

  • DML触发器可用于实现数据安全保护、数据审计、数据完整性、参照完整性、数据复制等功能。

    c、DML触发器类型

  • 包括语句触发器和行触发器。
    1、语句触发器:在指定操作语句之前或者之后执行一次,不管这条语句影响了多少行。(针对行)
    2、行触发器:触发语句作用的每一条记录都被触发,在行级触发器中使用:old和:new伪记录变量,识别值的状态。(针对表)
  • :old表示操作该行之前,这一行的值;:new 表示操作该行之后,这一行的值。

    d、创建DML触发器的语法格式

    CREATE [OR REPLACE] TRIGGER trigger_name 
    {BEFORE | AFTER}
    {DELETE | INSERT | UPDATE [ OF 列名]}
    ON 表名
    [FOR EACH ROW [WHEN (条件)])
    PLSQL块

    e、示例1:实现数据安全保护(数据的安全性检查)

  • 示例:禁止在休息日(周六、周日)改变emp表的数据。
  • 分析:1、使用to_char(sysdate, 'day')函数;2、采用语句触发器。

    SQL> CREATE OR REPLACE TRIGGER emp_trigger
        2  BEFORE INSERT OR UPDATE OR DELETE
        3  ON emp
        4  BEGIN
        5     IF to_char(sysdate, 'day') IN ('星期六', '星期日') THEN
        6        RAISE_APPLICATION_ERROR(-20006, '不能在休息日改变员工信息!');
        7     END IF;
        8  END;
        9  /
    
    Trigger created
    
    SQL> DELETE FROM emp WHERE empno = 7369;
    DELETE FROM emp WHERE empno = 7369
    
    ORA-20006: 不能在休息日改变员工信息!
    ORA-06512: 在 "SCOTT.EMP_TRIGGER", line 3
    ORA-04088: 触发器 'SCOTT.EMP_TRIGGER' 执行过程中出错

    f、示例2:实现数据审计

  • 示例:审计员工信息表数据的变化,审计删除时间,以及被删除的雇员名。
  • 使用SQL WINDOW窗口:(逐步执行)

    --创建审计表
    CREATE TABLE delete_emp_audit(
                 name VARCHAR2(10),
                 delete_time DATE
    );
    
    --创建触发器
    CREATE OR REPLACE TRIGGER del_emp_trigger
    AFTER DELETE ON emp
    FOR EACH ROW
    BEGIN
        INSERT INTO delete_emp_audit VALUES(:old.ename, SYSDATE); --插入被删除员工的姓名和当前时间
    END;
    
    --测试
    DELETE FROM emp WHERE empno = 7499;
    SELECT * FROM delete_emp_audit;
  • 在SQL语句和PLSQL语句中,old和new伪记录变量需要加上冒号:;而在WEHN这样的限制性条件语句当中,则不需要加上冒号:。

    g、示例3:实现数据完整性(数据确认)

  • 数据完整性用于确保数据满足商业逻辑或者企业规则。
  • 实现数据完整性首选约束,约束无法实现的,可以使用触发器实现数据完整性。
  • 示例:比如要求员工涨后工资不能低于原来的工资,并且所涨的工资不能超过原工资的50%。

    SQL> CREATE OR REPLACE TRIGGER tr_check_sal
        2  BEFORE UPDATE OF sal ON emp
        3  FOR EACH ROW 
        4  WHEN (new.sal < old.sal OR new.sal > old.sal * 1.5)
        5  BEGIN
        6       RAISE_APPLICATION_ERROR(-20028, '工资直升不降,并且升幅不能超过50%');
        7  END;
        8  /
    
    Trigger created
    
    SQL> UPDATE emp SET sal = sal * 1.8 WHERE empno = 7902;
    UPDATE emp SET sal = sal * 1.8 WHERE empno = 7902
    
    ORA-20028: 工资直升不降,并且升幅不能超过50%
    ORA-06512: 在 "SCOTT.TR_CHECK_SAL", line 2
    ORA-04088: 触发器 'SCOTT.TR_CHECK_SAL' 执行过程中出错

    h、示例4:实现参照完整性(比如级联更新)

  • 为了实现级联删除,可以在定义外部键约束时指定ON DELETE CASCADE关键字。
  • 但是使用约束却不能实现级联更新,为了实现级联更新,需要使用触发器。
  • 示例:级联更新DEPT表的主键以及EMP表的外部键列。

    CREATE OR REPLACE TRIGGER upd_cascade_trigger
    AFTER UPDATE OF deptno
    ON dept
    FOR EACH ROW 
    BEGIN
        UPDATE emp SET deptno = :new.deptno WHERE deptno = :old.deptno;
    END;
    
    --测试
    UPDATE dept SET deptno = 50 WHERE deptno = 10;
    SELECT deptno , ename FROM emp WHERE deptno = 50;

    4、INSTEAD OF触发器

    a、什么是INSTEAD OF触发器(替代触发器)?

  • 适用于视图上的触发器

    b、为什么使用INSTEAD OF触发器?

  • 在简单视图上往往可以执行INSET、UPDATE、DELETE操作。
  • 但是在复杂视图上执行INSET、UPDATE、DELETE操作时有限制。所以为了在这些复杂的视图上执行DML操作,需要建立替代触发器。

    c、INSTEAD OF 触发器的限制

  • 替代触发器只适用于视图。
  • 替代触发器不能指定BEFORE和AFTER选项。
  • 不能在具有WITH CHECK OPTION选项的视图上建立替代触发器。
  • 替代触发器必须包含FOR EACH ROW选项。

    d、示例代码

    1、创建emp_dept视图:

    SQL> CREATE OR REPLACE VIEW emp_dept
        2  AS 
        3  SELECT d.deptno, d.dname, e.empno, e.ename
        4  FROM dept d, emp e
        5  WHERE d.deptno = e.deptno;
    
    View created

    2、当没有创建替代触发器时,对emp_dept视图插入数据出错:

    SQL> INSERT INTO emp_dept VALUES(50, 'DEVELOPMENT', 2222, 'ALICE');
    INSERT INTO emp_dept VALUES(50, 'DEVELOPMENT', 2222, 'ALICE')
    
    ORA-01779: 无法修改与非键值保存表对应的列

    3、创建emp_dept视图(复杂视图)的替代触发器:

    CREATE OR REPLACE TRIGGER instead_of_trigger
    INSTEAD OF 
    INSERT
    ON emp_dept
    FOR EACH ROW
    DECLARE
        v_temp INT;
    BEGIN
        SELECT COUNT(*) INTO v_temp FROM dept WHERE deptno = :new.deptno;
        IF v_temp = 0 THEN
            INSERT INTO dept(deptno, dname) VALUES(:new.deptno, :new.dname);
        END IF;
        SELECT COUNT(*) INTO v_temp FROM emp WHERE empno = :new.empno;
        IF v_temp = 0 THEN
            INSERT INTO emp(empno, ename, deptno) VALUES(:new.empno, :new.ename, :new.deptno);
        END IF;
    END;

    4、对emp_dept视图进行插入操作:

        SQL> INSERT INTO emp_dept VALUES(50, 'DEVELOPMENT', 2222, 'ALICE');
    
        1 row inserted
    
        SQL> SELECT * FROM EMP WHERE empno = 2222;
    
        EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO
        ----- ---------- --------- ----- ----------- --------- --------- ------
         2222 ALICE                                                          50
    
        SQL> SELECT *FROM DEPT WHERE deptno = 50;
    
        DEPTNO DNAME          LOC
        ------ -------------- -------------
                50 ACCOUNTING     NEW YORK
    
        SQL> SELECT * FROM emp_dept WHERE empno = 2222;
    
        DEPTNO DNAME          EMPNO ENAME
        ------ -------------- ----- ----------
                50 ACCOUNTING      2222 ALICE

    5、系统触发器

    a、什么是系统触发器?

  • 系统触发器是由特定系统事件所触发的触发器。(需要注意的是,系统触发器是要有系统用户来创建的)
  • 系统事件是指与例程或者方案相关的数据库事件,它包括STARTUP、SHUTDOWN、DB_ROLE_CHANGE和SERVERERROR的四种事件。
    1、STARTUP事件触发器是在启动数据库后触发。
    2、SHUTDOWN事件触发器在关闭数据之前触发。
    3、DB_ROLE_CHANGE事件触发器在改变角色后第一次打开数据库时触发。
    4、SERVERERROR事件触发器在发生Oracle错误时触发。

    b、示例代码

    1、创建记录发生的数据库系统EVENT_TALBE事件表:

    CREATE TABLE event_table(
                 event VARCHAR2(50),
                 event_time date
                 );

    2、创建系统触发器:

        SQL> CREATE OR REPLACE TRIGGER startup_trigger
            2  AFTER STARTUP ON DATABASE
            3  BEGIN
            4        INSERT INTO event_table VALUES(ORA_SYSEVENT, SYSDATE);
            5  END;
            6  /
    
        Trigger created

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Oracle专题16之触发器

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Oracle专题3之Oracle数据表的

Oracle SQL Developer是Oracle官方出品的免费图形化开发工具,相对于SQL * Plus来说,图形化的界面便于操作,不必记忆大量的命令,输出结果美观。它的基本功能有结果的格式化输出、编辑器自动提示、代码优化、显示SQL
2023-01-31

Oracle触发器详解

Oracle触发器是一种数据库对象,它可以在特定的数据操作(如插入、更新或删除)发生时自动执行一段预定义的PL/SQL代码。触发器可以用于实现复杂的业务逻辑,数据约束和数据一致性的维护等功能。Oracle触发器可以在表级别或行级别上定义,
Oracle触发器详解
2024-04-09

oracle触发器定时触发怎么配置

在Oracle数据库中,可以使用触发器来定时触发某些操作。触发器可在以下情况下自动触发:在插入、更新或删除表中的数据时,或在满足某些特定条件时。要在Oracle数据库中配置定时触发器,可以按照以下步骤进行操作:1. 创建一个新的触发器:
2023-08-09

Oracle DML触发器和DDL触发器实例详解

目录一、概念二、DML触发器2.1、语句触发器2.2、行级触发器2.3、DML触发器语法:2.4、触发器谓词:2.5、实例说明三、DDL 触发器3.1、DDL触发器语法3.2、DDL 事件3.3、可用属性3.4、实例说明总结一、概念触发器
2023-03-13

Oracle DML触发器和DDL触发器实例详解

Oracle触发器是使用者对Oracle数据库的对象做特定的操作时,触发的一段PL/SQL程序代码器,下面这篇文章主要给大家介绍了关于Oracle DML触发器和DDL触发器的相关资料,需要的朋友可以参考下
2023-03-13

Oracle DML触发器和DDL触发器怎么使用

今天小编给大家分享一下Oracle DML触发器和DDL触发器怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、概念
2023-07-05

MySQL触发器之初见

触发器语法CREATE TRIGGER trigger_nametrigger_timetrigger_event NO table_nameFOR EACH ROWtrigger_stmttrigger_name: 标识触发器名称,用户自行指定;trigg
2014-11-27

编程热搜

目录