zoukankan      html  css  js  c++  java
  • ORACLE数据库——触发器的创建和使用

    触发器

    • 触发器组成

    1、触发事件
      DML或DDL语句。
    2、触发时间
      是在触发事件发生之前(before) 还是之后(after) 触发
    3、触发操作
      使用PL/SQL块进行相应的数据库操作
    4、触发对象
      表、视图、模式、数据库
    5、触发频率
      触发器内定义的动作被执行的次数,包括语句级和行级ji。

    • 限制

    1、触发器不接受参数
    2、一个表上最多可有12个触发器,但同一时间、同一事件、同一类型的触发器只能有一个。并各触发器之间不能有矛盾。
    3、一个表上的触发器越多,该表上的DM操作的性能影响就越大
    4、触发器代码的大小不能超过32K。如需要大量的代码创建触发器,则首先创建过程,然后在触发器中使用CALL语句调用过程
    5、触发器代码只能包含SELECT、INSERT、UPDATE和DELETE语句,
    6、不能包含DDL语句(CREATE、ALTER和DROP) 和事务控制语句(COMMIT、ROLLBACK和SAVEPOINT)

    • 创建dml触发器

    语句触发器
    1、语句触发器是指当执行DML语句时被隐含执行的触发器
    2、如果在表上针对某种DML操作创建了语句触发器,则当执行DML操作时会自动地执行触发器的相应代码
    3、为了审计DML操作,或者确保DML操作安全执行时,可以使用语句触发器

    触发器用途很多,例如用户清算购物车后将会触发待收货的数据库

    代码示例:

    --创建触发器
    create or replace trigger tri_test
    before--触发之前
    update or delete--更新或删除
    on emp
    for each row--对行进行操作
      begin
        dbms_output.put_line(:old.sal);--old表示数据库旧值
        insert into demo(id) values (:new.sal);--new新值
      end;
    
    update emp set sal=888 where empno=7788;
    commit;
    --代码解释:先执行创建触发器代码后,再执行最后的更新语句。当更新恩平、表后将会输出数据库中本来存放的值,并且触发添加语句在demo表中插入一条语句。

    自定义异常,触发器 拦截

    简单代码示例1:

    -- 触发器  拦截
    create or replace trigger tri_test
    before
    update or delete
    on emp
    for each row
      begin
        if to_char(sysdate,'yyyy-mm-dd')='2018-03-13' then--将系统日期转化为字符类型
          -- 自定义异常,
          raise_application_error(-20000,'今天不能修改数据');-- 负20000之前的异常都已经被定义
        end if;
      end;
    
    update emp set sal=777 where empno=7788;
    commit;
    --触发器创建后,执行最后代码,将会有异常提示:今天不能修改数据

    示例2:

    create or replace trigger tri_test
    before
    update or delete or insert
    on emp
    for each row
      begin
        case
        when updating then
           raise_application_error(-20000,'今天不能修改');
        when inserting then
          raise_application_error(-20001,'今天不能插入');
        when deleting then
          raise_application_error(-20000,'今天不能删除');
        end case;
      end;
    
    update emp set sal=777 where empno=7788;
    insert into emp (empno) values (123);
    commit;
    •  创建替代(instead of)触发器

    一般语法:

    create or peplace trigger 触发器名称

    instead of

    操作条件on视图名称

    for each row(因为instead of 触发器只能在行级上出发,所以没有必要指定)

    begin 

    操作条件from 表名where 列名= :old.列名;

    end;

    其中:

    instead of 选项使oracle 激活触发器,而不是执行触发器。只能对视图和对象视图建立 instead of触发器,而不能对表、模式和数据库建立instead of 触发器。

    总结创建替代触发器的过程:

    1. 为用户授权
    2. 创建视图
    3. 创建触发器
    4. 执行条件

    简答代码示例:

    ------  替换触发器创建过程示例
    
    -- 授权
    grant create view to scott;
    
    -- 创建视图
    create view emp_view as
    select deptno,count(*) total,sum(sal) total_salary
    from emp group by deptno;
    --创建触发器
    create trigger emp_view_delete
    instead of
    delete on emp_view
    for each row
      begin 
        delete from emp where deptno= :old.deptno;
      end;
    --执行条件
    delete from emp_view where deptno=10;
    
    select * from emp;
    
    rollback;

    上述代码中最后 rollback的意思为回滚,和commit用法相反,当不确定要删除数据库中的数据时使用rollback意味着撤回,用commit执行dml语句后,数据库将做出永久改变。

    总结替代触发器创建特点:

    1. 只能被创建在视图上,并且该视图没有指定的with check option选项
    2. 不能被指定before和after选项
    3. for each row语句是可选的
    4. 没有必要针对一个表的视图上创建替代触发器,只要创建dml触发器就可以了

    案例

    使用触发器实现自动编号

    对于表中id自动递增在sql语句中可以用序列来实现,下面是用触发器来实现自动编号;

    思路:

    1. 创建表
    2. 创建序列
    3. 创建触发器
    4. 执行条件

    代码如下:

    --使用触发器实现自动编号
    --创建序列
    create sequence stu_seq
    start with 1
    increment by 1
    --创建触发器
    create or replace trigger tri_stu
    before
    insert on student
    for each row
     begin
        select stu_seq.nextval into :new.id from dual;
     end;
    --执行条件
    insert into student (id,name) values(1,'lwx');
    commit;
  • 相关阅读:
    Django通过中间件配置解决跨域
    Kindeditor初始化、及初始化编辑内容
    Bootstrap免费后台管理模版
    微信小程序开发-网络请求-GET/POST不同方式等
    微信小程序开发-文件系统
    微信小程序开发学习记录-源码分享
    【转载】python实例手册
    【改良的选择排序 】
    【选择 插入 冒泡排序】
    【python基础】 Tkinter 之 几何管理器
  • 原文地址:https://www.cnblogs.com/3sanrenyou/p/8565240.html
Copyright © 2011-2022 走看看