zoukankan      html  css  js  c++  java
  • Oracle触发器

    Oracle-触发器

    触发器可以看做一种“特殊”的存储过程,它定义了一些与数据库相关事件(INSERT,UPDATE,CREATE)发生时应执行的“功能代码块”,通常用于管理复杂的完整性约束,或监控对表的修改,或通知其他程序,甚至可以实现对数据的审计功能。

    触发事件:能够引起触发器运行的操作被称为“触发事件”,如执行DML(INSERT,UPDATE,DELETE),DDL(CREATE,ALTER.DROP);引发数据库系统事件(系统启动或退出,产生异常错误);引发用户事件(登陆或退出数据库操作)

    根据触发器的触发事件和触发器的执行情况,Oracle所支持的触发器分为一下5种类型:

    1行级触发器:当DML语句对每一行数据进行操作时都会引起该触发器的运行

    2语句级触发器:无论DML语句影响多上行数据,其所引起的触发器仅执行一次

    3替换触发器:该触发器是定义在视图上的,而不是定义在表上,它是用来替换所使用实际语句的触发器

    4用户事件触发器:与DDL操作或用户登陆、退出数据库事件相关的触发器。

    5.系统事件触发器:指Oracle数据库系统的事件中进行触发的触发器,如Oracle实例的启动与关闭

    语句级触发器

    例子:在SCOTT模式下,创建dept_log数据表,并在其中定义两个字段,分别用来存储操作种类信息和操作日期:

    create table dept_log
    (
    operate_tag varchar2(10),
    operate_tiem date
    );

    创建一个关于emp表的语句级触发器,将用户对dept表的操作信息保存到dept_log表中:

    create or replace trigger tri_dept
    before insert or update or delete
    on dept
    declare
    var_tag varchar2(10);
    begin
    if inserting then
    var_tag:='插入';
    elsif updating then
    var_tag:='修改';
    elsif deleting then
    var_tag:='删除';
    end if;
    insert into dept_log
    values(var_tag,sysdate);
    end tri_dept;
    /

    执行触发器,也就是触发这些事件(insert,update,delete);之后再查看dept_log表就可以观察到结果

    行级触发器

    例子 :在SCOTT模式下,创建一个用于存储商品种类的数据表,其中包括商品序号列和商品名称列:

    create table goods(

    id int primary key,

    good_name varchar2(50));

    创建一个序列:

    create sequence seq_id;

    创建一个触发器,用于为goods表的id赋值

    create or replace trigger tri_insert_good
    before insert
    on goods
    for each row
    begin
    select seq_id.nextval
    into :new.id
    from dual;
    end;
    /

    :new.id--列标识符

      有两种列标识符,

      原值标识符:--:old.id --一般在update delete

      新值标识符:--:new.id--一般在update insert

    触发该触发器:

    可以通过插入语句 insert into goods(good_name) values('苹果');

    同时用insert into goods(id,good_name)values (9,'葡萄');

    然后再查询该表即可知道是否,自动插入了id

    但是第二条记录的id,还是会顺序增长,那是因为,触发器将seq_id的nextval值赋给了:new.id,并且nextval属性值是连续不间断的

    替换触发器

    例子:首先创建一个视图

    (首先该用户要有创建视图的权限,切换到system ,grant create view to scott)

    create view view_emp_dept
    as
    select empno,ename,dept.deptno,dname,job,hiredate from emp,dept
    where emp.deptno=dept.deptno;

    注意:在没有创建“替换触发器”时,试图向该视图中插入数据,是会有错误的ORA-01776:无法通过连接视图修改多个基表

    创建一个关于view_emp_dept视图的替换触发器,在该触发器的主体中实现向emp表和dept表中插入两行相互关联的数据

    create or replace trigger tri_insert_view
    instead of insert
    on view_emp_dept
    for each row
    declare
    row_dept dept%rowtype;
    begin
    select * into row_dept from dept where deptno=:new.deptno;
    if sql%notfound then

    insert into dept(deptno,dname) values(:new.deptno,:new.dname);
    end if;
    insert into emp(empno,ename,deptno,job,hiredate) values
    (:new.empno,:new.ename,:new.deptno,:new.job,:new.hiredate);
    end tri_insert_view;
    /

    触发该触发器:

    insert into view_emp_dept(empno,ename,deptno,dname,job,hiredate)

    values(8888,'东方',10,'ACCOUTNTING','CASHIER',sysdate);

    这样,便可以插入一条记录到视图;

    但是,如果这个deptno不在dept表中,那么会在dept表中插入相关记录,但是,测试时,却出现了错误

    用户事件触发器

    因进行DDL操作或用户登录、退出操作而引起运行的一种触发器,比如CREATE,ALTER,DROP,ANALYZE,COMMENT,GRANT,REVOKE,RENAME,TRUNCATE,SUSPEND,LOGON ,LOGOFF

    创建一个日志信息表,用于保存DDL操作的信息,包括数据对象,数据对象类型,操作行为,操作用户,操作日期

    create table ddl_oper_log
    (
    db_obj_name varchar2(20),
    db_obj_type varchar2(20),
    oper_action varchar2(20),
    oper_user varchar2(20),
    oper_date date);

    关于scott用户的DDL操作(CREATE,ALTER,DROP),创建一个触发器,然后将DDL操作的相关信息插入到ddl_oper_log日志表中

    create or replace trigger tri_ddl_oper
    before create or alter or drop
    on scott.schema
    begin
    insert into ddl_oper_log values(
    ora_dict_obj_name,--获取DDL操作对象的名称
    ora_dict_obj_type,--获取DDL操作所对应的数据库对象的类型
    ora_sysevent,--获取触发器的系统事件名称
    ora_login_user,--获取登陆用户名
    sysdate);
    end;
    /

    触发触发器:

    create,alter,drop 然后再select * from ddl_oper_log;

  • 相关阅读:
    「UVA12293」 Box Game
    「CF803C」 Maximal GCD
    「CF525D」Arthur and Walls
    「CF442C」 Artem and Array
    LeetCode lcci 16.03 交点
    LeetCode 1305 两棵二叉搜索树中的所有元素
    LeetCode 1040 移动石子直到连续 II
    LeetCode 664 奇怪的打印机
    iOS UIPageViewController系统方法崩溃修复
    LeetCode 334 递增的三元子序列
  • 原文地址:https://www.cnblogs.com/sharpest/p/7764660.html
Copyright © 2011-2022 走看看