• ORACLE 触发器 基础


    --触发器
    --语法

    CREATE OR REPLACE TRIGGER TRIGGER_NAME
    AFTER|BEFORE|INSTEAD OF
    [INSERT][OR UPDATE [OF COLUMN_LIST]] [OR [DELETE]]
    ON TABLE_OR_VIEW_NAME
    [REFERENCING{OLD[AS]OLD/NEW[AS]NEW} ]
    [FOR EACH ROW]
    [WHEN(condition)]
    pl/sql_block;
    
    --sqlserver        oracel
    deleted          :old
    inserted        :new

    --触发器中不能使用 ROLLBACK ,COMMIT,SAVEPOINT
    --如果在触发器中PLSQL使用了:NEW :OLD时,就必须是行级触发器,必须要有 FOR EACH ROW

    --创建实验环境
    CREATE TABLE SC(CODE NUMBER ,SNAME VARCHAR2(10),SCORE NUMBER);
    INSERT INTO SC VALUES (1,'AA',87);
    INSERT INTO SC VALUES (2,'BB',67);
    INSERT INTO SC VALUES (3,'CC',57);
    INSERT INTO SC VALUES (4,'DD',88);
    COMMIT;
    SELECT * FROM SC;
    
    SET SERVEROUT ON
    
    CREATE OR REPLACE TRIGGER TRIG1
    BEFORE INSERT OR UPDATE 
    ON SC
    FOR EACH ROW
    BEGIN
    DBMS_OUTPUT.put_line('TRIG1 IS VALID');
    END;
    /
    INSERT INTO SC VALUES (5,'EE',90);
    UPDATE SC SET SCORE=SCORE+1;
    ROLLBACK;
    
    --SCORE 必须在0-100中
    CREATE OR REPLACE TRIGGER TRIG2
    BEFORE INSERT 
    ON SC 
    FOR EACH ROW --使用了:NEW,:OLD时必须要有这句话
    BEGIN
    IF :NEW.SCORE<0 OR :NEW.SCORE>100 
    THEN RAISE_APPLICATION_ERROR(-20001,'ERROR');
    END IF; 
    END;
    /
    INSERT INTO SC VALUES (6,'EE',-1);
    INSERT INTO SC VALUES (6,'EE',101);
    INSERT INTO SC VALUES (6,'EE',10);
    ROLLBACK;
    
     
    --当插入的CODE是负数时,将其转为正数再插入 必须在0-100中
    CREATE OR REPLACE TRIGGER TRIG3
    BEFORE INSERT 
    ON SC 
    FOR EACH ROW
    BEGIN
    IF :NEW.CODE < 0 
    THEN :NEW.CODE := -:NEW.CODE;
    END IF;
    END;
    /
    INSERT INTO SC VALUES (-7,'EE',90);
    --当用户对表进行操作时记录操作
    CREATE OR REPLACE TRIGGER TRIG5 
    BEFORE INSERT OR UPDATE OR DELETE 
    ON SC
    FOR EACH ROW
    BEGIN 
    IF INSERTING --关键词
    THEN DBMS_OUTPUT.PUT_LINE('INSERT:'||:NEW.CODE||','||:NEW.NAME||','||:NEW.SCORE);
    END IF;
    IF DELETING --关键词
    THEN DBMS_OUTPUT.PUT_LINE('DELETE:'||:OLD.CODE||','||:OLD.NAME||','||:OLD.SCORE);
    END IF;
    IF UPDATING --关键词
    THEN DBMS_OUTPUT.PUT_LINE('UPDATE_B:'||:OLD.CODE||','||:OLD.NAME||','||:OLD.SCORE);
    DBMS_OUTPUT.PUT_LINE('UPDATE_A:'||:NEW.CODE||','||:NEW.NAME||','||:NEW.SCORE);
    END IF;
    END;
    /
    
    INSERT INTO SC VALUES (10,'EE',90);
    UPDATE SC SET SCORE=100 WHERE CODE=10;
    DELETE SC WHERE CODE=10;
    
    --用触发器修改视图(非键保留表)
    --创建实验环境
    CREATE TABLE STUDENT (SNO INT ,SNAME VARCHAR2(10),SAGE INT);
    INSERT INTO STUDENT VALUES (1,'AA',22);
    INSERT INTO STUDENT VALUES (2,'BB',23);
    INSERT INTO STUDENT VALUES (3,'CC',24);
    INSERT INTO STUDENT VALUES (4,'DD',25);
    INSERT INTO STUDENT VALUES (5,'EE',26);
    
    CREATE TABLE ADDRESS (SNO INT ,ZZ VARCHAR2(10));
    INSERT INTO ADDRESS VALUES (1,'ZZ');
    INSERT INTO ADDRESS VALUES (2,'LY');
    INSERT INTO ADDRESS VALUES (3,'KF');
    INSERT INTO ADDRESS VALUES (4,'XX');
    INSERT INTO ADDRESS VALUES (5,'XC');
    COMMIT;
    
    GRANT CREATE VIEW TO SCOTT ; --DBA
    
    CREATE OR REPLACE VIEW V1
    AS 
    SELECT A.SNO,A.SNAME ,A.SAGE,B.ZZ
    FROM STUDENT A LEFT JOIN ADDRESS B 
    ON A.SNO=B.SNO;
    --实现更新操作
    UPDATE V1 SET ZZ='AY' WHERE SNAME = 'BB';
    -- ORA-01779: cannot modify a column which maps to a non key-preserved table
    
    CREATE OR REPLACE TRIGGER TRIG4 
    INSTEAD OF UPDATE
    ON V1
    FOR EACH ROW
    DECLARE 
    A NUMBER :=0; --用在存储SNO
    BEGIN
    SELECT SNO INTO A FROM STUDENT WHERE SNAME = :OLD.SNAME; --赋值
    DELETE ADDRESS WHERE SNO=A; --删除原数据
    INSERT INTO ADDRESS VALUES (A,:NEW.ZZ); --插入新数据
    END;
    /
    UPDATE V1 SET ZZ='AY' WHERE SNAME = 'BB';
    
     
    --模式触发器
    --
    CREATE TABLE DROPPDE_OBJ(OBJ_NAME VARCHAR2(30),OBJ_TYPE VARCHAR2(20),DROP_DATE DATE);
    CREATE OR REPLACE TRIGGER LOG_DROP_OBJ
    AFTER DROP --类型
    ON SCHEMA --模式
    BEGIN
    INSERT INTO DROPPED_OBJ
    VALUES (ora_dict_obj_name,ora_dict_obj_type,SYSDATE);
    END;
    /
    
    CREATE TABLE TT (ID INT);
    DROP TABLE TT ;
    
    ora_client_ip_address --返回客户端的IP
    ora_database_name --返回当前数据库名
    ora_login_user --返回登录用户名
    ora_dict_obj_name --返回DDL操作对应的数据库对象名
    ora_dict_obj_type --返回DDL操作对应的数据库对象类型
    --数据库启动、关闭 触发器 --SYS使用
    
    --数据库启动触发器 
    CREATE TABLE EVENT_TABLE (EVENT VARCHAR2(30),TIME DATE);
    
    CREATE OR REPLACE TRIGGER TR_STARTUP
    AFTER STARTUP --AFTER
    ON DATABASE
    BEGIN
    INSERT INTO EVENT_TABLE VALUES (ora_sysevent,SYSDATE);
    END;
    /
    --数据库关闭触发器
    
    CREATE OR REPLACE TRIGGER TR_STARTUP
    BEFORE SHUTDOWN --BEFORE
    ON DATABASE
    BEGIN
    INSERT INTO EVENT_TABLE VALUES (ora_sysevent,SYSDATE);
    END;
    /
    --用户登录和退出触发器
    CREATE TABLE LOGIN_TABLE (USERNAME VARCHAR2(10),LOGON_TIME DATE,LOGOFF_TIME DATE,ADDRESS VARCHAR2(30));
    
    --登陆
    CREATE OR REPLACE TRIGGER TRIG_LOGON
    AFTER LOGON 
    ON DATABASE
    BEGIN
    INSERT INTO LOGIN_TABLE(USERNAME,LOGON_TIME,ADDRESS)
    VALUES (ora_login_user,SYSDATE,ora_client_ip_address);
    END;
    /
    --退出
    CREATE OR REPLACE TRIGGER TRIG_LOGOFF
    BEFORE LOGOFF 
    ON DATABASE
    BEGIN
    INSERT INTO LOGIN_TABLE(USERNAME,LOGOFF_TIME,ADDRESS)
    VALUES (ora_login_user,SYSDATE,ora_client_ip_address);
    END;
    /
    --启用、禁用与删除
    ALTER TRIGGER TRIGGER_NAME DISABLE;
    ALTER TRIGGER TRIGGER_NAME ENABLE;
    DROP TRIGGER TRIGGER_NAME ;
    
    
    --查看触发器相关信息
    SELECT * FROM USER_TRIGGERS;

    --更多内容可以查看:http://blog.csdn.net/indexman/article/details/8023740/

  • 相关阅读:
    从拟物化到扁平,再到Material Design
    如何写一个解释器(1):编译原理
    理解JavaScript中的原型继承(2)
    Redis简介
    谈谈积累
    Hadoop(三):MapReduce程序(python)
    Hadoop(二):MapReduce程序(Java)
    统计学习方法十:隐马尔科夫模型二
    统计学习方法十:隐马尔科夫模型
    统计学习方法九:EM算法
  • 原文地址:https://www.cnblogs.com/chenqs/p/6794278.html
Copyright © 2020-2023  润新知