oracle触发器

来源:互联网 发布:vb 类模块 编辑:程序博客网 时间:2024/06/06 20:57
  1. 21-1:建立before触发器   
  2.     CREATE OR REPLACE TRIGGER tr_sec_emp   
  3.     BEFORE INSERT OR UPDATE OR DELETE ON emp   
  4.     BEGIN   
  5.       IF to_char(sysdate,'DY','nls_date_language=AMERICAN')   
  6.         IN ('SAT','SUN') THEN   
  7.           raise_application_error(-20001,   
  8.            '不能在休息日改变雇员信息');   
  9.       END IF;   
  10.     END;   
  11.     /   
  12. 21-2:建立after触发器   
  13.     CREATE TABLE aud_upd_table(   
  14.       host VARCHAR2(30),statement VARCHAR2(100),exectime DATE);   
  15.     CREATE OR REPLACE TRIGGER tr_upd_emp   
  16.     AFTER UPDATE ON emp   
  17.     DECLARE   
  18.       sql_txt ora_name_list_t;   
  19.       v_stmt VARCHAR2(100);   
  20.       n BINARY_INTEGER;   
  21.     BEGIN   
  22.       n:=ora_sql_txt(sql_txt);   
  23.       FOR i IN 1..n LOOP   
  24.         v_stmt:=v_stmt||sql_txt(i);   
  25.       END LOOP;   
  26.       INSERT INTO aud_upd_table VALUES(   
  27.         sys_context('userenv','host'),v_stmt,SYSDATE);   
  28.     END;   
  29.     /   
  30. 21-3:使用条件谓词   
  31.     CREATE OR REPLACE TRIGGER tr_sec_emp   
  32.     BEFORE INSERT OR UPDATE OR DELETE ON emp   
  33.     BEGIN   
  34.       IF to_char(sysdate,'DY','nls_date_language=AMERICAN')   
  35.          IN ('SAT','SUN') THEN   
  36.         CASE   
  37.           WHEN INSERTING THEN   
  38.             raise_application_error(-20001,   
  39.               '不能在休息日执行INSERT');   
  40.           WHEN UPDATING THEN   
  41.             raise_application_error(-20002,   
  42.               '不能在休息日执行UPDATE');   
  43.           WHEN DELETING THEN   
  44.             raise_application_error(-20003,   
  45.               '不能在休息日执行DELETE');   
  46.          END CASE;   
  47.       END IF;   
  48.     END;   
  49.     /   
  50. 21-4:建立before行触发器   
  51.     CREATE OR REPLACE TRIGGER tr_emp_sal   
  52.     BEFORE UPDATE OF sal ON emp   
  53.     FOR EACH ROW   
  54.     BEGIN   
  55.       IF :new.sal<:old.sal THEN   
  56.         raise_application_error(-20010,'工资只涨不降');   
  57.       END IF;   
  58.     END;   
  59.     /   
  60. 21-5:建立after行触发器   
  61.     CREATE TABLE audit_emp_change (   
  62.       name VARCHAR2(10),oldsal NUMBER(6,2),   
  63.       newsal NUMBER(6,2),time DATE);   
  64.     CREATE OR REPLACE TRIGGER tr_sal_change   
  65.     AFTER UPDATE OF sal ON emp   
  66.     FOR EACH ROW   
  67.     DECLARE   
  68.       v_temp INT;   
  69.     BEGIN   
  70.       SELECT count(*) INTO v_temp FROM audit_emp_change   
  71.         WHERE name=:old.ename;   
  72.       IF v_temp=0 THEN   
  73.         INSERT INTO audit_emp_change   
  74.           VALUES(:old.ename,:old.sal,:new.sal,SYSDATE);   
  75.       ELSE   
  76.         UPDATE audit_emp_change   
  77.           SET oldsal=:old.sal,newsal=:new.sal,time=SYSDATE   
  78.           WHERE name=:old.ename;   
  79.       END IF;   
  80.     END;   
  81.     /   
  82. 21-6:限制行触发器   
  83.     CREATE OR REPLACE TRIGGER tr_sal_change   
  84.     AFTER UPDATE OF sal ON emp   
  85.     FOR EACH ROW WHEN (old.job='SALESMAN')   
  86.     DECLARE   
  87.       v_temp INT;   
  88.     BEGIN   
  89.       SELECT count(*) INTO v_temp FROM audit_emp_change   
  90.         WHERE name=:old.ename;   
  91.       IF v_temp=0 THEN   
  92.         INSERT INTO audit_emp_change   
  93.            VALUES(:old.ename,:old.sal,:new.sal,SYSDATE);   
  94.       ELSE   
  95.         UPDATE audit_emp_change   
  96.           SET oldsal=:old.sal,newsal=:new.sal,time=SYSDATE   
  97.           WHERE name=:old.ename;   
  98.       END IF;   
  99.     END;   
  100.     /   
  101. 21-7:组合触发器   
  102. CREATE OR REPLACE TRIGGER tr_update_sal   
  103. FOR UPDATE OF sal ON emp COMPOUND TRIGGER   
  104.   msg1 VARCHAR2(50):='工资必须在1000到5000之间!';   
  105.   msg2 VARCHAR2(50):='不能在休息日更新!';   
  106. BEFORE STATEMENT IS   
  107. BEGIN   
  108.   IF to_char(sysdate,'DY','nls_date_language=AMERICAN')   
  109.      IN ('SAT','SUN') THEN   
  110.      raise_application_error(-20000,msg2);   
  111.   END IF;   
  112. END BEFORE STATEMENT;   
  113. AFTER EACH ROW IS   
  114. BEGIN   
  115.   IF :new.sal NOT BETWEEN 1000 AND 5000 THEN   
  116.      raise_application_error(-20001,msg1);   
  117.   END IF;   
  118. END AFTER EACH ROW;   
  119. END;   
  120. /   
  121.   
  122. 21-8:控制数据安全   
  123.     CREATE OR REPLACE TRIGGER tr_emp_time   
  124.     BEFORE INSERT OR UPDATE OR DELETE ON emp   
  125.     BEGIN   
  126.       IF to_char(SYSDATE,'HH24') NOT BETWEEN   
  127.          '9' AND '17' THEN   
  128.         raise_application_error(-20101,'非工作时间');   
  129.       END IF;   
  130.     END;   
  131.     /   
  132.     UPDATE emp SET sal=3200 WHERE empno=7788;   
  133. 21-9:实现数据审计   
  134.     CREATE TABLE audit_delete_emp(name VARCHAR2(10),time DATE);   
  135.     CREATE OR REPLACE TRIGGER tr_delete_emp   
  136.     AFTER DELETE ON emp FOR EACH ROW   
  137.     BEGIN   
  138.       INSERT INTO audit_delete_emp VALUES(:old.ename,SYSDATE);   
  139.     END;   
  140.     /   
  141.     DELETE FROM emp WHERE empno=7788;   
  142.     SELECT * FROM audit_delete_emp;   
  143. 21-10:实现数据完整性   
  144.     CREATE OR REPLACE TRIGGER tr_check_sal   
  145.     BEFORE UPDATE OF sal ON emp FOR EACH ROW   
  146.     WHEN (new.sal<old.sal OR new.sal>1.2*old.sal)   
  147.     BEGIN   
  148.       raise_application_error(-20931,   
  149.         '工资只升不降,并且升幅不能超过20%');   
  150.     END;   
  151.     /   
  152.     UPDATE emp SET sal=sal*1.25 WHERE empno=7788;   
  153. 21-11:实现参照完整性   
  154.     CREATE OR REPLACE TRIGGER tr_update_cascade   
  155.     AFTER UPDATE OF deptno ON dept FOR EACH ROW   
  156.     BEGIN   
  157.       UPDATE emp SET deptno=:new.deptno   
  158.         WHERE deptno=:old.deptno;   
  159.     END;   
  160.     /   
  161.     UPDATE dept SET deptno=50 WHERE deptno=10;   
  162.     SELECT ename FROM emp WHERE deptno=50;   
  163. 21-12:instead of 触发器   
  164.     CREATE OR REPLACE VIEW dept_emp AS   
  165.       SELECT a.deptno,a.dname,b.empno,b.ename FROM dept a,emp b   
  166.       WHERE a.deptno=b.deptno;   
  167.     CREATE OR REPLACE TRIGGER tr_instead_of_dept_emp   
  168.     INSTEAD OF INSERT ON dept_emp FOR EACH ROW   
  169.     DECLARE   
  170.       v_temp INT;   
  171.     BEGIN   
  172.       SELECT count(*) INTO v_temp FROM dept WHERE deptno=:new.deptno;   
  173.       IF v_temp=0 THEN   
  174.          INSERT INTO dept (deptno,dname) VALUES(:new.deptno,:new.dname);   
  175.        END IF;   
  176.       SELECT count(*) INTO v_temp FROM emp WHERE empno=:new.empno;   
  177.       IF v_temp=0 THEN   
  178.          INSERT INTO emp (empno,ename,deptno) VALUES(:new.empno,:new.ename,:new.deptno);   
  179.       END IF;   
  180.     END;   
  181.     /   
  182.     INSERT INTO dept_emp VALUES(50,'ADMIN',1223,'MARY');   
  183.     SELECT dname FROM dept WHERE deptno=50;   
  184.     SELECT ename FROM emp WHERE empno=1223;   
  185. 21-13:系统事件触发器   
  186.     conn sys/oracle as sysdba   
  187.     create table event_table(event varchar2(30),time date);   
  188.     CREATE OR REPLACE TRIGGER tr_startup   
  189.     AFTER STARTUP ON DATABASE   
  190.     BEGIN   
  191.       INSERT INTO event_table VALUES(ora_sysevent,SYSDATE);   
  192.     END;   
  193.     /   
  194.     SHUTDOWN   
  195.     STARTUP   
  196.     SELECT * FROM event_table;   
  197. 21-14:建立登录触发器   
  198.     conn sys/oracle as sysdba   
  199.     CREATE TABLE aud_logon_tab(   
  200.        username VARCHAR2(20),time DATE,addr VARCHAR2(20));   
  201.     CREATE OR REPLACE TRIGGER tr_logon   
  202.     AFTER LOGON ON DATABASE   
  203.     BEGIN   
  204.       INSERT INTO aud_logon_tab VALUES(ora_login_user,SYSDATE,ora_client_ip_address);   
  205.     END;   
  206.     /   
  207.     conn scott/tiger@test  
  208.     SELECT * FROM sys.aud_logon_tab;   
  209. 21-15:建立DDL触发器   
  210.     conn sys/oracle as sysdba   
  211.     CREATE TABLE aud_ddl_tab(   
  212.        event VARCHAR2(20),username VARCHAR2(10),   
  213.        owner VARCHAR2(10),objname VARCHAR2(20),   
  214.       objtype VARCHAR2(10),time DATE);   
  215.     CREATE OR REPLACE TRIGGER tr_ddl   
  216.     AFTER DDL ON scott.schema   
  217.     BEGIN   
  218.       INSERT INTO aud_ddl_tab VALUES(   
  219.         ora_sysevent,ora_login_user,ora_dict_obj_owner,   
  220.         ora_dict_obj_name,ora_dict_obj_type,SYSDATE);   
  221.     END;   
  222.     /   
  223.     conn scott/tiger@test  
  224.     CREATE TABLE temp(cola INT);   
  225.     DROP TABLE temp;   
  226.     SELECT username,event,objtype,objname FROM sys.aud_ddl_tab;   
  227. 21-16:显示触发器信息   
  228.     set long 800  
  229.     set pagesize 400  
  230.     SELECT trigger_body FROM user_triggers WHERE trigger_name='TR_UPD_EMP';   
  231. 21-17:禁止触发器   
  232.     ALTER TRIGGER tr_upd_emp DISABLE;   
  233. 21-18:激活触发器   
  234.     ALTER TRIGGER tr_upd_emp ENABLE;   
  235. 21-19:重新编译触发器   
  236.     ALTER TRIGGER tr_upd_emp COMPILE;   
  237. 21-20:删除触发器   
  238.     DROP TRIGGER tr_check_sal;  
原创粉丝点击