• Oracle触发器


    触发器
    触发器是什么
    触发器是在指定一些特定的sql语句(必须是增删改语句)时自动执行的一些pl/sql的代码片段。注意,查询一般不会
    加触发器。触发器也是命名块,但是和之前学习的过程函数等命名块不同,触发器会自动执行。
    触发器的特点:
    1,触发器满足条件会自动执行
    2,触发器只能加上增删改语句操作上,不能加到查询语句上。
    3,一个表上最多只能加12个触发器
    4,触发器不是加的越多越好,一个表最多不要超过6个触发器。触发器会影响查询效率
    5,触发器文本的大小不能超过36kb,如果太大,可以把触发器的封装到过程或者函数中。
    6,触发器中不能有ddl(数据定义命令,好比创建表,修改表结构,删除表等)操作,也不能有事物操作。
    触发器的作用
    1,可以记录用户的日志记录
    2,可以预防一些非法的操作,好比可以预防用户在周六或者周日操作某些表
    触发器在oracle中有三种分类,dml触发器 替代触发器 系统触发器
    dml触发器
    dml 是数据操作语句,包括数据库表的增删改操作。
    语法:
    create [or replace] trigger 触发器名称
    before/after 触发时机 before 是数据操作之前 after 数据操作之后
    delete/update/insert [of 列名1,列名2...] 触发操作 多个触发操作可以用 or 连接,后面还可以跟上数据表的列 of
    列名
    on
    表名称 触发对象
    for each row 表示该触发器是行级触发器还是语句级触发器。行级触发器针对每个表的行都会执行一遍触发器,语
    句级触发器只会执行一次。如果去掉for each row就是语句级触发器.
    when 条件表达式 触发条件
    begin
    语句块;
    end;
     
    举例:当删除部门信息时,把用户删除掉的部门存到历史表中
    --创建表,让表结构参考某一个已经存在的表,如果不希望复制表数据,可以
    --在sql查询后加一个永远不成立的条件
    drop table dept_his;
    create table dept_his as select * from dept where 1=0;
    create or replace trigger tri_dept_his
    --触发时机
    after
    -- 触发操作
    delete
    on
    --触发对象
    dept
    --是行级触发器
    for each row
    begin
    --往历史表中插入用户删除的数据,获取用户删除的数据可以用old这个内置变量
    --引用内置变量的时候要在内置变量前加冒号
    insert into dept_his values(:old.deptno,:old.dname,:old.loc);
    end;
    --测试
    select * from dept;
    delete from dept where deptno=4;
    select * from dept_his;
     
    举例:写一个触发器,不让用户周六周日操作(增删改)部门表数据
    create or replace trigger tri_dept_oper
    before insert or update or delete on dept
    begin
    --判断当前日期是否是周六或者周日
    if to_char(sysdate,'day') in ('星期六','星期日') then
    --阻止用户操作 raise_application_error第一个参数是异常编号
    -- 这里可用的异常编号是-20999到-20000之间
    raise_application_error(-20000,'非工作日不能修改部门表数据');
    end if;
    end;
    select * from dept;
    update dept set dname='住建部1' where deptno=4;
    触发器的执行顺序
    一个表上有可能有行级触发器,有可能有语句级触发器
    before 的语句级触发器
    befroe的行级触发器
    dml语句
    after的行级触发器
    after的语句级触发器
     
    举例:部门编号为10的员工的基本工资不能降低,部门编号为20的员工信息不能删除
    create or replace trigger tri_emp_oper
    after update or delete on emp
    for each row
    --注意 在when中内置变量old就不需要加冒号了
    when (old.deptno=10 or old.deptno=20)
    begin
    --部门编号为10的员工的基本工资不能降低
    if :old.deptno=10 and :new.sal<:old.sal and updating then
    raise_application_error(-20001,'部门编号为10的员工的基本工资不能降低');
    end if;
    --部门编号为20的员工信息不能删除
    --此处需要判断用户对部门编号为20的员工执行的是什么操作
    -- 需要用到触发器谓词 deleting updating inserting
    if :old.deptno=20 and deleting then
    raise_application_error(-20002,'部门编号为20的员工的信息不能删除');
    end if;
    end;
    --修改部门编号为10的基本工资
    select * from emp;
    update emp set sal='2000' where empno=7782;
    --删除部门编号为2员工的信息
    delete from emp where empno=7566;
    触发器中调用存储过程
    举例:删除员工表数据时,把删除的数据存到历史表中
    先创建历史表:
    create table emp_his as select * from emp where 1=0;
    创建触发器:
    --创建一个过程,存储用户历史数据
    create or replace procedure pro_emp_his (
    empno varchar2,ename varchar2
    ) as
    begin
    insert into emp_his(empno,ename) values(empno,ename);
    end;
    --创建触发器 在触发器中调用过程
    create or replace trigger tri_emp_his
    after delete on emp for each row
    begin
    --调用过程
    pro_emp_his(:old.empno,:old.ename);
    end;
  • 相关阅读:
    php解析XML的两种方法
    Windows下xampp搭配php环境以及mysql的设置和php连接Mysql数据库
    管道
    Ubuntu文件系统
    Ubuntu如何使用Vscode写C++代码
    Ubuntu如何百度云盘下载
    Debug程序的使用
    寄存器
    汇编指令
    汇编第二章_寄存器
  • 原文地址:https://www.cnblogs.com/duguangming/p/10848940.html
Copyright © 2020-2023  润新知