收藏 分享(赏)

ORACLE PLSQL编程之八-把触发器说透.doc

上传人:kpmy5893 文档编号:7657062 上传时间:2019-05-23 格式:DOC 页数:44 大小:304.50KB
下载 相关 举报
ORACLE PLSQL编程之八-把触发器说透.doc_第1页
第1页 / 共44页
ORACLE PLSQL编程之八-把触发器说透.doc_第2页
第2页 / 共44页
ORACLE PLSQL编程之八-把触发器说透.doc_第3页
第3页 / 共44页
ORACLE PLSQL编程之八-把触发器说透.doc_第4页
第4页 / 共44页
ORACLE PLSQL编程之八-把触发器说透.doc_第5页
第5页 / 共44页
点击查看更多>>
资源描述

1、ORACLE PL/SQL 编程之八:把触发器说透摘自和讯网特性 INSERTUPDATEDELETEOLDNULL 实际值实际值 NEW 实际值实际值 NULL 例 1: 建立一个触发器, 当职工表 emp 表被删除一条记录时,把被删除记录写到职工表删除日志表中去。 CREATE TABLE emp_his AS SELECT * FROM EMP WHERE 1=2;CREATE OR REPLACE TRIGGER tr_del_empBEFORE DELETE 指定触发时机为删除操作前触发ON scott.empFOR EACH ROW 说明创建的是行级触发器BEGIN将修改前数据插入

2、到日志记录表 del_emp ,以供监督使用。INSERT INTO emp_his(deptno , empno, ename , job ,mgr , sal , comm , hiredate )VALUES( :old.deptno, :old.empno, :old.ename , :old.job,:old.mgr, :old.sal, :m, :old.hiredate );END;DELETE emp WHERE empno=7788;DROP TABLE emp_his;DROP TRIGGER del_emp;例 2:限制对 Departments 表修改( 包括 INSE

3、RT,DELETE,UPDATE)的时间范围,即不允许在非工作时间修改 departments 表。CREATE OR REPLACE TRIGGER tr_dept_timeBEFORE INSERT OR DELETE OR UPDATEON departmentsBEGINIF (TO_CHAR(sysdate,“DAY“) IN (“星期六“, “ 星期日“) OR (TO_CHAR(sysdate, “HH24:MI“) NOT BETWEEN “08:30“ AND “18:00“) THENRAISE_APPLICATION_ERROR(-20001, “不是上班时间,不能修改

4、departments 表“);END IF;END;例 3:限定只对部门号为 80 的记录进行行触发器操作。CREATE OR REPLACE TRIGGER tr_emp_sal_commBEFORE UPDATE OF salary, commission_pctOR DELETEON HR.employeesFOR EACH ROWWHEN (old.department_id = 80)BEGINCASEWHEN UPDATING (“salary“) THENIF :NEW.salary :old.salary THENRAISE_APPLICATION_ERROR(-20001,

5、 “部门 80 的人员的工资不能降“);END IF;WHEN UPDATING (“commission_pct“) THENIF :NEW.commission_pct :mission_pct THENRAISE_APPLICATION_ERROR(-20002, “部门 80 的人员的奖金不能降“);END IF;WHEN DELETING THENRAISE_APPLICATION_ERROR(-20003, “不能删除部门 80 的人员记录“);END CASE;END;/*实例:UPDATE employees SET salary = 8000 WHERE employee_i

6、d = 177;DELETE FROM employees WHERE employee_id in (177,170);*/例 4:利用行触发器实现级联更新。在修改了主表 regions 中的 region_id 之后(AFTER),级联的、自动的更新子表 countries 表中原来在该地区的国家的 region_id。CREATE OR REPLACE TRIGGER tr_reg_couAFTER update OF region_idON regionsFOR EACH ROWBEGINDBMS_OUTPUT.PUT_LINE(“旧的 region_id 值是“|:old.regio

7、n_id|“、新的 region_id 值是“|:new.region_id);UPDATE countries SET region_id = :new.region_idWHERE region_id = :old.region_id;END;例 5:在触发器中调用过程。CREATE OR REPLACE PROCEDURE add_job_history( p_emp_id job_history.employee_id%type, p_start_date job_history.start_date%type, p_end_date job_history.end_date%type

8、, p_job_id job_history.job_id%type, p_department_id job_history.department_id%type)ISBEGININSERT INTO job_history (employee_id, start_date, end_date,job_id, department_id)VALUES(p_emp_id, p_start_date, p_end_date, p_job_id, p_department_id);END add_job_history;创建触发器调用存储过程.CREATE OR REPLACE TRIGGER u

9、pdate_job_historyAFTER UPDATE OF job_id, department_id ON employeesFOR EACH ROWBEGINadd_job_history(:old.employee_id, :old.hire_date, sysdate,:old.job_id, :old.department_id);END;8.2.3 创建替代(INSTEAD OF)触发器创建触发器的一般语法是:CREATE OR REPLACE TRIGGER trigger_nameINSTEAD OFINSERT | DELETE | UPDATE OF column ,

10、 column OR INSERT | DELETE | UPDATE OF column , column .ON schema. view_name 只能定义在视图上REFERENCING OLD AS old | NEW AS new| PARENT as parentFOR EACH ROW 因为 INSTEAD OF 触发器只能在行级上触发,所以没有必要指定WHEN conditionPL/SQL_block | CALL procedure_name;其中:INSTEAD OF 选项使 ORACLE 激活触发器,而不执行触发事件。只能对视图和对象视图建立 INSTEAD OF 触发

11、器,而不能对表、模式和数据库建立 INSTEAD OF 触发器。FOR EACH ROW 选项说明触发器为行触发器。行触发器和语句触发器的区别表现在:行触发器要求当一个 DML 语句操走影响数据库中的多行数据时,对于其中的每个数据行,只要它们符合触发约束条件,均激活一次触发器;而语句触发器将整个语句操作作为触发事件,当它符合约束条件时,激活一次触发器。当省略 FOR EACH ROW 选项时,BEFORE 和 AFTER 触发器为语句触发器,而 INSTEAD OF 触发器则为行触发器。REFERENCING 子句说明相关名称,在行触发器的 PL/SQL 块和 WHEN 子句中可以使用相关名称

12、参照当前的新、旧列值,默认的相关名称分别为 OLD 和 NEW。触发器的PL/SQL 块中应用相关名称时,必须在它们之前加冒号(:),但在 WHEN 子句中则不能加冒号。WHEN 子句说明触发约束条件。Condition 为一个逻辑表达时,其中必须包含相关名称,而不能包含查询语句,也不能调用 PL/SQL 函数。WHEN 子句指定的触发约束条件只能用在 BEFORE 和 AFTER 行触发器中,不能用在 INSTEAD OF 行触发器和其它类型的触发器中。INSTEAD_OF 用于对视图的 DML 触发,由于视图有可能是由多个表进行联结(join)而成,因而并非是所有的联结都是可更新的。但可以

13、按照所需的方式执行更新,例如下面情况:例 1:CREATE OR REPLACE VIEW emp_view ASSELECT deptno, count(*) total_employeer, sum(sal) total_salaryFROM emp GROUP BY deptno;在此视图中直接删除是非法:SQLDELETE FROM emp_view WHERE deptno=10;DELETE FROM emp_view WHERE deptno=10ERROR 位于第 1 行:ORA-01732: 此视图的数据操纵操作非法但是我们可以创建 INSTEAD_OF 触发器来为 DELE

14、TE 操作执行所需的处理,即删除EMP 表中所有基准行:CREATE OR REPLACE TRIGGER emp_view_deleteINSTEAD OF DELETE ON emp_view FOR EACH ROWBEGINDELETE FROM emp WHERE deptno= :old.deptno;END emp_view_delete;DELETE FROM emp_view WHERE deptno=10;DROP TRIGGER emp_view_delete;DROP VIEW emp_view;例 2:创建复杂视图,针对 INSERT 操作创建 INSTEAD OF

15、触发器,向复杂视图插入数据。创建视图:CREATE OR REPLACE FORCE VIEW “HR“.“V_REG_COU“ (“R_ID“, “R_NAME“, “C_ID“, “C_NAME“)ASSELECT r.region_id,r.region_name,c.country_id,c.country_nameFROM regions r,countries cWHERE r.region_id = c.region_id;创建触发器:CREATE OR REPLACE TRIGGER “HR“.“TR_I_O_REG_COU“ INSTEAD OFINSERT ON v_reg

16、_cou FOR EACH ROW DECLARE v_count NUMBER;BEGINSELECT COUNT(*) INTO v_count FROM regions WHERE region_id = :new.r_id;IF v_count = 0 THENINSERT INTO regions(region_id, region_name) VALUES(:new.r_id, :new.r_name);END IF;SELECT COUNT(*) INTO v_count FROM countries WHERE country_id = :new.c_id;IF v_count

17、 = 0 THENINSERTINTO countries(country_id,country_name,region_id)VALUES(:new.c_id,:new.c_name,:new.r_id);END IF;END;创建 INSTEAD OF 触发器需要注意以下几点:只能被创建在视图上,并且该视图没有指定 WITH CHECK OPTION 选项。不能指定 BEFORE 或 AFTER 选项。FOR EACH ROW 子可是可选的,即 INSTEAD OF 触发器只能在行级上触发、或只能是行级触发器,没有必要指定。没有必要在针对一个表的视图上创建 INSTEAD OF 触发器,只

18、要创建 DML 触发器就可以了。8.2.3 创建系统事件触发器ORACLE10G 提供的系统事件触发器可以在 DDL 或数据库系统上被触发。DDL 指的是数据定义语言,如 CREATE 、ALTER 及 DROP 等。而数据库系统事件包括数据库服务器的启动或关闭,用户的登录与退出、数据库服务错误等。创建系统触发器的语法如下:创建触发器的一般语法是:CREATE OR REPLACE TRIGGER sachema.trigger_nameBEFORE|AFTERddl_event_list | database_event_listON DATABASE | schema.SCHEMA WHE

19、N conditionPL/SQL_block | CALL procedure_name;其中: ddl_event_list:一个或多个 DDL 事件,事件间用 OR 分开;database_event_list:一个或多个数据库事件,事件间用 OR 分开;系统事件触发器既可以建立在一个模式上,又可以建立在整个数据库上。当建立在模式(SCHEMA)之上时,只有模式所指定用户的 DDL 操作和它们所导致的错误才激活触发器, 默认时为当前用户模式。当建立在数据库(DATABASE)之上时,该数据库所有用户的 DDL操作和他们所导致的错误,以及数据库的启动和关闭均可激活触发器。要在数据库之上建立

20、触发器时,要求用户具有 ADMINISTER DATABASE TRIGGER 权限。下面给出系统触发器的种类和事件出现的时机(前或后) :8.2.4 系统触发器事件属性除 DML 语句的列属性外,其余事件属性值可通过调用 ORACLE 定义的事件属性函数来读取。例 1:创建触发器,存放有关事件信息。DESC ora_syseventDESC ora_login_user创建用于记录事件用的表CREATE TABLE ddl_event(crt_date timestamp PRIMARY KEY,event_name VARCHAR2(20),user_name VARCHAR2(10),o

21、bj_type VARCHAR2(20),obj_name VARCHAR2(20);创建触犯发器CREATE OR REPLACE TRIGGER tr_ddlAFTER DDL ON SCHEMABEGININSERT INTO ddl_event VALUES(systimestamp,ora_sysevent, ora_login_user,ora_dict_obj_type, ora_dict_obj_name);END tr_ddl;例 2:创建登录、退出触发器。CREATE TABLE log_event(user_name VARCHAR2(10),address VARCHA

22、R2(20),logon_date timestamp,logoff_date timestamp);创建登录触发器CREATE OR REPLACE TRIGGER tr_logonAFTER LOGON ON DATABASEBEGININSERT INTO log_event (user_name, address, logon_date)VALUES (ora_login_user, ora_client_ip_address, systimestamp);END tr_logon;创建退出触发器CREATE OR REPLACE TRIGGER tr_logoffBEFORE LOG

23、OFF ON DATABASEBEGININSERT INTO log_event (user_name, address, logoff_date)VALUES (ora_login_user, ora_client_ip_address, systimestamp);END tr_logoff;8.2.5 使用触发器谓词谓词 行为INSERTING 如果触发语句是 INSERT 语句,则为 TRUE,ORACLE 提供三个参数 INSERTING, UPDATING, DELETING 用于判断触发了哪些操作。8.2.6 重新编译触发器如果在触发器内调用其它函数或过程,当这些函数或过程被删

24、除或修改后,触发器的状态将被标识为无效。当 DML 语句激活一个无效触发器时,ORACLE 将重新编译触发器代码,如果编译时发现错误,这将导致 DML 语句执行失败。在 PL/SQL 程序中可以调用 ALTER TRIGGER 语句重新编译已经创建的触发器,格式为:ALTER TRIGGER schema. trigger_name COMPILE DEBUG 其中:DEBUG 选项要器编译器生成 PL/SQL 程序条使其所使用的调试代码。8.3 删除和使能触发器删除触发器:DROP TRIGGER trigger_name;当删除其他用户模式中的触发器名称,需要具有 DROP ANY TRI

25、GGER 系统权限,当删除建立在数据库上的触发器时,用户需要具有ADMINISTER DATABASE TRIGGER 系统权限。此外,当删除表或视图时,建立在这些对象上的触发器也随之删除。禁用或启用触发器数据库 TRIGGER 的状态:有效状态(ENABLE):当触发事件发生时,处于有效状态的数据库触发器 TRIGGER 将被触发。无效状态(DISABLE) :当触发事件发生时,处于无效状态的数据库触发器 TRIGGER 将不会被触发,此时就跟没有这个数据库触发器(TRIGGER) 一样。数据库 TRIGGER 的这两种状态可以互相转换。格式为:ALTER TIGGER trigger_na

26、me DISABLE | ENABLE ;例:ALTER TRIGGER emp_view_delete DISABLE;ALTER TRIGGER 语句一次只能改变一个触发器的状态,而 ALTER TABLE 语句则一次能够改变与指定表相关的所有触发器的使用状态。格式为:ALTER TABLE schema.table_name ENABLE|DISABLE ALL TRIGGERS;例:使表 EMP 上的所有 TRIGGER 失效:ALTER TABLE emp DISABLE ALL TRIGGERS;8.4 触发器和数据字典相关数据字典:USER_TRIGGERS、ALL_TRIGGE

27、RS、DBA_TRIGGERSSELECT TRIGGER_NAME, TRIGGER_TYPE, TRIGGERING_EVENT,TABLE_OWNER, BASE_OBJECT_TYPE, REFERENCING_NAMES,STATUS, ACTION_TYPEFROM user_triggers;8.5 数据库触发器的应用举例例 1:创建一个 DML 语句级触发器,当对 emp 表执行 INSERT, UPDATE, DELETE 操作时,它自动更新 dept_summary 表中的数据。由于在 PL/SQL 块中不能直接调用 DDL语句,所以,利用 ORACLE 内置包 DBMS_

28、UTILITY 中的 EXEC_DDL_STATEMENT 过程,由它执行 DDL 语句创建触发器。CREATE TABLE dept_summary(Deptno NUMBER(2),Sal_sum NUMBER(9, 2),Emp_count NUMBER);INSERT INTO dept_summary(deptno, sal_sum, emp_count)SELECT deptno, SUM(sal), COUNT(*)FROM empGROUP BY deptno;创建一个 PL/SQL 过程 disp_dept_summary在触发器中调用该过程显示 dept_summary 标

29、中的数据。CREATE OR REPLACE PROCEDURE disp_dept_summaryISRec dept_summary%ROWTYPE;CURSOR c1 IS SELECT * FROM dept_summary;BEGINOPEN c1;FETCH c1 INTO REC;DBMS_OUTPUT.PUT_LINE(“deptno sal_sum emp_count“);DBMS_OUTPUT.PUT_LINE(“-“);WHILE c1%FOUND LOOPDBMS_OUTPUT.PUT_LINE(RPAD(rec.deptno, 6)|To_char(rec.sal_s

30、um, “$999,999.99“)|LPAD(rec.emp_count, 13);FETCH c1 INTO rec;END LOOP;CLOSE c1;END;BEGINDBMS_OUTPUT.PUT_LINE(“插入前“);Disp_dept_summary();DBMS_UTILITY.EXEC_DDL_STATEMENT(“CREATE OR REPLACE TRIGGER trig1AFTER INSERT OR DELETE OR UPDATE OF sal ON empBEGINDBMS_OUTPUT.PUT_LINE(“正在执行 trig1 触发器 “);DELETE FR

31、OM dept_summary;INSERT INTO dept_summary(deptno, sal_sum, emp_count)SELECT deptno, SUM(sal), COUNT(*)FROM emp GROUP BY deptno;END;“);INSERT INTO dept(deptno, dname, loc)VALUES(90, “demo_dept“, “none_loc“);INSERT INTO emp(ename, deptno, empno, sal)VALUES(USER, 90, 9999, 3000);DBMS_OUTPUT.PUT_LINE(“插入

32、后“);Disp_dept_summary();UPDATE emp SET sal=1000 WHERE empno=9999;DBMS_OUTPUT.PUT_LINE(“修改后“);Disp_dept_summary();DELETE FROM emp WHERE empno=9999;DELETE FROM dept WHERE deptno=90;DBMS_OUTPUT.PUT_LINE(“删除后“);Disp_dept_summary();DBMS_UTILITY.EXEC_DDL_STATEMENT(“DROP TRIGGER trig1“);EXCEPTIONWHEN OTHER

33、S THENDBMS_OUTPUT.PUT_LINE(SQLCODE|“|SQLERRM);END;例 2:创建 DML 语句行级触发器。当对 emp 表执行 INSERT, UPDATE, DELETE 操作时,它自动更新 dept_summary 表中的数据。由于在 PL/SQL 块中不能直接调用 DDL 语句,所以,利用 ORACLE 内置包 DBMS_UTILITY 中的 EXEC_DDL_STATEMENT 过程,由它执行 DDL 语句创建触发器。BEGINDBMS_OUTPUT.PUT_LINE(“插入前“);Disp_dept_summary();DBMS_UTILITY.EXE

34、C_DDL_STATEMENT(“CREATE OR REPLACE TRIGGER trig2_updateAFTER UPDATE OF sal ON empREFERENCING OLD AS old_emp NEW AS new_empFOR EACH ROWWHEN (old_emp.sal != new_emp.sal)BEGINDBMS_OUTPUT.PUT_LINE(“正在执行 trig2_update 触发器“);DBMS_OUTPUT.PUT_LINE(“sal 旧值:“| :old_emp.sal);DBMS_OUTPUT.PUT_LINE(“sal 新值:“| :new

35、_emp.sal);UPDATE dept_summarySET sal_sum=sal_sum + :new_emp.sal - :old_emp.salWHERE deptno = :new_emp.deptno;END;“);DBMS_UTILITY.EXEC_DDL_STATEMENT(“CREATE OR REPLACE TRIGGER trig2_insertAFTER INSERT ON empREFERENCING NEW AS new_empFOR EACH ROWDECLAREI NUMBER;BEGINDBMS_OUTPUT.PUT_LINE(“正在执行 trig2_in

36、sert 触发器“);SELECT COUNT(*) INTO IFROM dept_summary WHERE deptno = :new_emp.deptno;IF I 0 THENUPDATE dept_summarySET sal_sum=sal_sum+:new_emp.sal,Emp_count=emp_count+1WHERE deptno = :new_emp.deptno;ELSEINSERT INTO dept_summaryVALUES (:new_emp.deptno, :new_emp.sal, 1);END IF;END;“);DBMS_UTILITY.EXEC_D

37、DL_STATEMENT(“CREATE OR REPLACE TRIGGER trig2_deleteAFTER DELETE ON empREFERENCING OLD AS old_empFOR EACH ROWDECLAREI NUMBER;BEGINDBMS_OUTPUT.PUT_LINE(“正在执行 trig2_delete 触发器“);SELECT emp_count INTO IFROM dept_summary WHERE deptno = :old_emp.deptno;IF I 1 THENUPDATE dept_summarySET sal_sum=sal_sum -

38、:old_emp.sal,Emp_count=emp_count - 1WHERE deptno = :old_emp.deptno;ELSEDELETE FROM dept_summary WHERE deptno = :old_emp.deptno;END IF;END;“);INSERT INTO dept(deptno, dname, loc)VALUES(90, “demo_dept“, “none_loc“);INSERT INTO emp(ename, deptno, empno, sal)VALUES(USER, 90, 9999, 3000);INSERT INTO emp(

39、ename, deptno, empno, sal)VALUES(USER, 90, 9998, 2000);DBMS_OUTPUT.PUT_LINE(“插入后“);Disp_dept_summary();UPDATE emp SET sal = sal*1.1 WHERE deptno=90;DBMS_OUTPUT.PUT_LINE(“修改后“);Disp_dept_summary();DELETE FROM emp WHERE deptno=90;DELETE FROM dept WHERE deptno=90;DBMS_OUTPUT.PUT_LINE(“删除后“);Disp_dept_s

40、ummary();DBMS_UTILITY.EXEC_DDL_STATEMENT(“DROP TRIGGER trig2_update“);DBMS_UTILITY.EXEC_DDL_STATEMENT(“DROP TRIGGER trig2_insert“);DBMS_UTILITY.EXEC_DDL_STATEMENT(“DROP TRIGGER trig2_delete“);EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE(SQLCODE|“|SQLERRM);END;例 3:利用 ORACLE 提供的条件谓词 INSERTING、UPDATIN

41、G 和 DELETING 创建与例 2 具有相同功能的触发器。BEGINDBMS_OUTPUT.PUT_LINE(“插入前“);Disp_dept_summary();DBMS_UTILITY.EXEC_DDL_STATEMENT(“CREATE OR REPLACE TRIGGER trig2AFTER INSERT OR DELETE OR UPDATE OF salON empREFERENCING OLD AS old_emp NEW AS new_empFOR EACH ROWDECLAREI NUMBER;BEGINIF UPDATING AND :old_emp.sal != :

42、new_emp.sal THENDBMS_OUTPUT.PUT_LINE(“正在执行 trig2 触发器 “);DBMS_OUTPUT.PUT_LINE(“sal 旧值:“| :old_emp.sal);DBMS_OUTPUT.PUT_LINE(“sal 新值:“| :new_emp.sal);UPDATE dept_summarySET sal_sum=sal_sum + :new_emp.sal - :old_emp.salWHERE deptno = :new_emp.deptno;ELSIF INSERTING THENDBMS_OUTPUT.PUT_LINE(“正在执行 trig2

43、触发器 “);SELECT COUNT(*) INTO IFROM dept_summaryWHERE deptno = :new_emp.deptno;IF I 0 THENUPDATE dept_summarySET sal_sum=sal_sum+:new_emp.sal,Emp_count=emp_count+1WHERE deptno = :new_emp.deptno;ELSEINSERT INTO dept_summaryVALUES (:new_emp.deptno, :new_emp.sal, 1);END IF;ELSEDBMS_OUTPUT.PUT_LINE(“正在执行

44、trig2 触发器 “);SELECT emp_count INTO IFROM dept_summary WHERE deptno = :old_emp.deptno;IF I 1 THENUPDATE dept_summarySET sal_sum=sal_sum - :old_emp.sal,Emp_count=emp_count - 1WHERE deptno = :old_emp.deptno;ELSEDELETE FROM dept_summaryWHERE deptno = :old_emp.deptno;END IF;END IF;END;“);INSERT INTO dept

45、(deptno, dname, loc)VALUES(90, “demo_dept“, “none_loc“);INSERT INTO emp(ename, deptno, empno, sal)VALUES(USER, 90, 9999, 3000);INSERT INTO emp(ename, deptno, empno, sal)VALUES(USER, 90, 9998, 2000);DBMS_OUTPUT.PUT_LINE(“插入后“);Disp_dept_summary();UPDATE emp SET sal = sal*1.1 WHERE deptno=90;DBMS_OUTP

46、UT.PUT_LINE(“修改后“);Disp_dept_summary();DELETE FROM emp WHERE deptno=90;DELETE FROM dept WHERE deptno=90;DBMS_OUTPUT.PUT_LINE(“删除后“);Disp_dept_summary();DBMS_UTILITY.EXEC_DDL_STATEMENT(“DROP TRIGGER trig2“);EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE(SQLCODE|“|SQLERRM);END;例 4:创建 INSTEAD OF 触发器。首先创

47、建一个视图 myview, 由于该视图是复合查询所产生的视图,所以不能执行 DML 语句。根据用户对视图所插入的数据判断需要将数据插入到哪个视图基表中,然后对该基表执行插入操作。DECLARENo NUMBER;Name VARCHAR2(20);BEGINDBMS_UTILITY.EXEC_DDL_STATEMENT(“CREATE OR REPLACE VIEW myview ASSELECT empno, ename, “E“ type FROM empUNIONSELECT dept.deptno, dname, “D“ FROM dept“);创建 INSTEAD OF 触发器 tr

48、igger3;DBMS_UTILITY.EXEC_DDL_STATEMENT(“CREATE OR REPLACE TRIGGER trig3INSTEAD OF INSERT ON myviewREFERENCING NEW nFOR EACH ROWDECLARERows INTEGER;BEGINDBMS_OUTPUT.PUT_LINE(“正在执行 trig3 触发器 “);IF :n.type = “D“ THENSELECT COUNT(*) INTO rowsFROM dept WHERE deptno = :n.empno;IF rows = 0 THENDBMS_OUTPUT.

49、PUT_LINE(“向 dept 表中插入数据“);INSERT INTO dept(deptno, dname, loc)VALUES (:n.empno, :n.ename, “none“);ELSEDBMS_OUTPUT.PUT_LINE(“编号为“| :n.empno|“ 的部门已存在,插入操作失败!“);END IF;ELSESELECT COUNT(*) INTO rowsFROM emp WHERE empno = :n.empno;IF rows = 0 THENDBMS_OUTPUT.PUT_LINE(“向 emp 表中插入数据“);INSERT INTO emp(empno, ename)VALUES(:n.empno, :n.ename);ELSEDBMS_OUTPUT.PUT_LINE(“编号为“| :n.empno|“ 的人员已存在,插入操作失败!“);END IF;

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报