• 数据库之十五:触发器


    触发器的一般语法结构:

    create [or replace] trigger Ttrigger_name
    {before|after} Triggering_event  on  table_name
    [for each row]
    [follows another_trigger]
    [enable/disable]
    [when  condition]
    declare
        declaration statemebts
    begin
        executable statements
    exception
        exception-handling sttements
    end;

    解析:
    create [or replace] trigger: 表示将创建或者替换一个触发器,如果没有写or replace则只会创建一个触发器,当数据库中已经有该触发器了,则新创建不会成功。

    Ttrigger_name:触发器的名字

    {before|after} Triggering_event on table_name:表示在table_name表上创建的触发器事件发生的前或者后,触发器会触发

    Triggering_event:比如插入或者更新等操作,也可能是时间

    [for each row]:表示行级触发器,是对每一行数据都会触发判断。若没有这一句,则是语句级触发器,一次触发只会执行一次

    [enable/disable]:是触发器启用或禁用选项,默认是启用的,禁用触发器的例句:after trigger trigger_anme disable

    follows :可以指定触发器的顺序

    declare:后面是申明部分

    beigin...end:中间是主体语句

    exception后面抛出异常

    a、删除一个表,表上的触发器也会一起被删除
    触发器的一些作用:
    a、执行不能通过使用完整性约束来定义的复杂业务规则
    b、维护复杂的安全规则
    c、自动生成衍生列的值
    d、收集有关访问数据库表的统计信息
    e、防止无效的事务
    f、提供值审计
    触发器不会执行事务控制语句,比如commit和rollback等,当触发器执行时,执行commit和rollback时,触发器也会被提交或者回滚

     例句:

    1:

    CREATE OR REPLACE TRIGGER forbid_emp_trigger
    BEFORE INSERT OR DELETE OR UPDATE ON emp
    DECLARE  
        v_currentweak VARCHAR(20);   
        v_currenthour VARCHAR(20);
    BEGIN
        SELECT TO_CHAR(SYSDATE,'day'),TO_CHAR(SYSDATE,'hh24') 
        INTO v_currentweak, v_currenthour FROM dual ;  
        IF TRIM(v_currentweak)='星期一' OR TRIM(v_currentweak)='星期六' 
        OR TRIM(v_currentweak)='星期日' THEN   
        RAISE_APPLICATION_ERROR(-20008,'在周末及周一不允许更新emp数据表!') ;    
        ELSIF TRIM(v_currenthour)<'9' OR TRIM(v_currenthour)>'18' THEN    
        RAISE_APPLICATION_ERROR(-20009,'在下班时间不能够修改emp表数据!') ;   
        END IF;
    END;

    会判断当前日期,如果在周一、周末或者下班时间,不允许插入,删除,更新数据库数据 

    2:

    create or replace trigger tri_no_gzjiang
    before update
    on emp
    declare
        var_data varchar2(20);
    begin
        select to_char(sysdate,'hh24') into var_date from dual;
        if var_date > '12' then
            raise_application_error(-20009,'12点之后不能够修改emp表数据!');
        end if;
    end;

    3:

    create or replace trigger CASCADE_DEL_UPD
    before  update of deptno or delete
    on dept
    for each row
    declare
    begin
        if deleting  then 
            delete from emp where deptno=:old.deptno;  
        end if;  
        if updating then 
            update emp set deptno=:new.deptno 
            where deptno=:old.deptno;  
        end if;
    end;

    4: 

    --创建一个视图
    create or replace view view_emp_dept as
    select empno,ename,dept.deptno,dname,job,hiredate
    from emp ,dept
    where emp.deptno = dept.deptno;
     
    --插入记录
    insert into view_emp_dept(empno,ename,deptno,dname,job,hiredate)
    values (999,'ttgg',10,'ACCOUNTING','CASHIER',sysdate);
     
    --插入数据失败,通过关联触发器来
    --创建触发器
    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;
    --验证触发器
     
    insert into view_emp_dept(empno,ename,deptno,dname,job,hiredate)
    values (999,'ttgg',10,'ACCOUNTING','CASHIER',sysdate);
     
    select * from view_emp_dept;
    尽管很渺小,但终究会变得伟大
  • 相关阅读:
    MSP430:实时时钟-DS1302
    STM32: TIMER门控模式控制PWM输出长度
    LVM磁盘管理
    python的面向对象,类,以及类的使用
    pymysql模块
    paramiko模块
    正则表达式和re模块
    python3的soker模块实现功能
    根据生日测星座
    多进程,进程池,协程
  • 原文地址:https://www.cnblogs.com/chenbao1012/p/11849106.html
Copyright © 2020-2023  润新知