oracle 触发器的种类和触发事件,dml触发器,ddl事件触发器,替代触发器,查看触发.pdf

上传人:赵** 文档编号:60675083 上传时间:2022-11-17 格式:PDF 页数:72 大小:2.92MB
返回 下载 相关 举报
oracle 触发器的种类和触发事件,dml触发器,ddl事件触发器,替代触发器,查看触发.pdf_第1页
第1页 / 共72页
oracle 触发器的种类和触发事件,dml触发器,ddl事件触发器,替代触发器,查看触发.pdf_第2页
第2页 / 共72页
点击查看更多>>
资源描述

《oracle 触发器的种类和触发事件,dml触发器,ddl事件触发器,替代触发器,查看触发.pdf》由会员分享,可在线阅读,更多相关《oracle 触发器的种类和触发事件,dml触发器,ddl事件触发器,替代触发器,查看触发.pdf(72页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、oracle 触发器的种类和触发事件,DML 触发器,DDL 事件触发器,替代触发器,查看触发.oracle 数据库开发应用实例,招生录取系统.|oracle创建,删除存储过程,参数传递,创.2009-04-14oracle 触发器的种类和触发事件,DML 触发器,DDL 事件触发器,替代触发器,查看触发器,关键字:oracle 触发器 种类 触发 事件 dml ddl 事件 替代查看触发器的种类和触发事件触发器必须由事件才能触发。触发器的触发事件分可为 3 类,分别是 DML 事件、DDL 事件和数据库事件。每类事件包含若干个事件,如下所示。数据库的事件是具体的,在创建触发器时要指明触发的事

2、件。种类 关 键 字 含义 Sql 代码DML 事件(3 种)INSERT在表或视图中插入数据时触发UPDATE修改表或视图中的数据时触发DELETE在删除表或视图中的数据时触发DDL 事件(3 种)CREATE在创建新对象时触发ALTER修改数据库或数据库对象时触发DROP删除对象时触发数据库事件(5 种)STARTUP 数据打开时触发SHUTDOWN在使用 NORMAL 或 IMMEDIATE 选项关闭数据库时触发LOGON当用户连接到数据库并建立会话时触发LOGOFF当一个会话从数据库中断开时触发SERVERERROR 发生服务器错误时触发DML 事件(3 种)INSERT 在表或视图中

3、插入数据时触发UPDATE修改表或视图中的数据时触发DELETE在删除表或视图中的数据时触发DDL 事件(3 种)CREATE在创建新对象时触发ALTER 修改数据库或数据库对象时触发DROP删除对象时触发数据库事件(5 种)STARTUP 数据打开时触发SHUTDOWN 在使用NORMAL或IMMEDIATE选项关闭数据库时触发LOGON 当用户连接到数据库并建立会话时触发LOGOFF当一个会话从数据库中断开时触发SERVERERROR发生服务器错误时触发触发器的类型可划分为 4 种:数据操纵语言(DML)触发器、替代(INSTEAD OF)触发器、数据定义语言(DDL)触发器和数据库事件触

4、发器。各类触发器的作用如下所示。Sql 代码种类简称作用数据操纵语言触发器DML 触发器创建在表上,由 DML事件引发的触发器替代触发器INSTEAD OF 触发器创建在视图上,用来替换对视图进行的插入、删除和修改操作数据定义语言触发器DDL 触发器定义在模式上,触发事件是数据库对象的创建和修改数据库事件触发器定义在整个数据库或模式上,触发事件是数据库事件种类简称作用数据操纵语言触发器 DML触发器创建在表上,由 DML事件引发的触发器替代触发器 INSTEAD OF 触发器创建在视图上,用来替换对视图进行的插入、删除和修改操作数据定义语言触发器 DDL触发器件是数据库对象的创建和修改数据库事

5、件触发器 定义在整个数据库或模式上,触发事件是数据库事件DML 触发器的要点DML 触发器是定义在表上的触发器,由 DML 事件引发。编写 DML 触发器的要素是:*确定触发的表,即在其上定义触发器的表。*确定触发的事件,DML 触发器的触发事件有 INSERT、UPDATE 和 DELETE 三种,说明见下。*确定触发时间。触发的时间有 BEFORE 和 AFTER 两种,分别表示触发动作发生在 DML 语句执行之前和语句执行之后。*确定触发级别,有语句级触发器和行级触发器两种。语句级触发器表示 SQL 语句只触发一次触发器,行级触发器表示 SQL 语句影响的每一行都要触发一次。由于在同一个

6、表上可以定义多个 DML 触发器,因此触发器本身和引发触发器的 SQL 语句在执行的顺序上有先后的关定义在模式上,触发事系。它们的顺序是:*如果存在语句级 BEFORE 触发器,则先执行一次语句级BEFORE 触发器。*在 SQL 语句的执行过程中,如果存在行级 BEFORE 触发器,则 SQL 语句在对每一行操作之前,都要先执行一次行级 BEFORE 触发器,然后才对行进行操作。如果存在行级AFTER 触发器,则 SQL 语句在对每一行操作之后,都要再执行一次行级 AFTER 触发器。*如果存在语句级 AFTER 触发器,则在 SQL 语句执行完毕后,要最后执行一次语句级 AFTER 触发器

7、。DML 触发器还有一些具体的问题,说明如下:*如果有多个触发器被定义成为相同时间、相同事件触发,且最后定义的触发器是有效的,则最后定义的触发器被触发,其他触发器不执行。*一个触发器可由多个不同的 DML 操作触发。在触发器中,可用 INSERTING、DELETING、UPDATING 谓词来区别不同的 DML 操作。这些谓词可以在 IF 分支条件语句中作为判断条件来使用。*在行级触发器中,用:new 和:old(称为伪记录)来访问数据变更前后的值。但要注意,INSERT 语句插入一条新记录,所以没有:old 记录,而 DELETE 语句删除掉一条已经存在的记录,所以没有:new 记录。UP

8、DATE 语句既有:old 记录,也有:new 记录,分别代表修改前后的记录。引用具体的某一列的值的方法是:ld.字段名或:new.字段名*触发器体内禁止使用 COMMIT、ROLLBACK、SAVEPOINT 语句,也禁止直接或间接地调用含有上述语句的存储过程。定义一个触发器时要考虑上述多种情况,并根据具体的需要来决定触发器的种类。DML 触发器的创建创建 DML 触发器需要 CREATE TRIGGER 系统权限。创建DML 触发器的语法如下:CREATE OR REPLACE TRIGGER 触发器名BEFORE|AFTER|INSTEAD OF 触发事件 1 OR 触发事件 2.ON

9、表名WHEN 触发条件FOR EACH ROWDECLARE声明部分BEGIN主体部分END;其中:OR REPLACE:表示如果存在同名触发器,则覆盖原有同名触发器。BEFORE、AFTER 和 INSTEAD OF:说明触发器的类型。WHEN 触发条件:表示当该条件满足时,触发器才能执行。触发事件:指 INSERT、DELETE 或 UPDATE 事件,事件可以并行出现,中间用 OR 连接。对于 UPDATE 事件,还可以用以下形式表示对某些列的修改会引起触发器的动作:UPDATE OF 列名 1,列名 2.ON 表名:表示为哪一个表创建触发器。FOR EACH ROW:表示触发器为行级触

10、发器,省略则为语句级触发器。触发器的创建者或具有 DROP ANY TIRGGER 系统权限的人才能删除触发器。删除触发器的语法如下:DROP TIRGGER 触发器名可以通过命令设置触发器的可用状态,使其暂时关闭或重新打开,即当触发器暂时不用时,可以将其置成无效状态,在使用时重新打开。该命令语法如下:ALTER TRIGGER 触发器名 DISABLE|ENABLE其中,DISABLE 表示使触发器失效,ENABLE 表示使触发器生效。同存储过程类似,触发器可以用 SHOW ERRORS 检查编译错误。行级触发器的应用在行级触发器中,SQL 语句影响的每一行都会触发一次触发器,所以行级触发器

11、往往用在对表的每一行的操作进行控制的场合。若在触发器定义中出现 FOR EACH ROW 子句,则为语句级触发器。【训练 1】创建包含插入、删除、修改多种触发事件的触发器DML_LOG,对EMP表的操作进行记录。用INSERTING、DELETING、UPDATING 谓词来区别不同的 DML 操作。在创建触发器之前,需要先创建事件记录表 LOGS,该表用来对操作进行记录。该表的字段含义解释如下:LOG_ID:操作记录的编号,数值型,它是该表的主键,由序列自动生成。LOG_TABLE:进行操作的表名,字符型,非空,该表设计成可以由多个触发器共享使用。比如我们可以为 dept 表创建类似的触发器

12、,同样将操作记录到该表。LOG_DML:操作的动作,即 INSERT、DELETE 或 UPDATE三种之一。LOG_KEY_ID:操作时表的主键值,数值型。之所以记录表的主键,是因为主键是表的记录的惟一标识,可以识别是对哪一条记录进行了操作。对于 emp 表,主键是 empno。LOG_DATE:操作的日期,日期型,取当前的系统时间。LOG_USER:操作者,字符型,取当时的操作者账户名。比如登录 SCOTT 账户进行操作,在该字段中,记录账户名为SCOTT。步骤 1:在 SQL*Plus 中登录 STUDENT 账户,创建如下的记录表 LOGS:Sql 代码CREATE TABLE log

13、s(LOG_ID NUMBER(10)PRIMARY KEY,LOG_TABLE VARCHAR2(10)NOT NULL,LOG_DML VARCHAR2(10),LOG_KEY_ID NUMBER(10),LOG_DATE DATE,LOG_USER VARCHAR2(15);CREATE TABLE logs(LOG_ID NUMBER(10)PRIMARY KEY,LOG_TABLE VARCHAR2(10)NOT NULL,LOG_DML VARCHAR2(10),LOG_KEY_ID NUMBER(10),LOG_DATE DATE,LOG_USER VARCHAR2(15);执行

14、结果:Sql 代码表已创建。表已创建。步骤2:创建一个 LOGS 表的主键序列 LOGS_ID_SEQ:Sql代码CREATE SEQUENCE logs_id_squ INCREMENT BY 1START WITH 1 MAXVALUE 9999999 NOCYCLENOCACHE;CREATE SEQUENCE logs_id_squ INCREMENT BY 1START WITH 1 MAXVALUE 9999999 NOCYCLENOCACHE;执行结果:Sql 代码序列已创建。序列已创建。步骤 3:创建和编译以下触发器:Sql 代码CREATE OR REPLACE TRIGGE

15、R DML_LOGBEFORE-触发时间为操作前DELETE OR INSERT OR UPDATE-件触发ON empFOR EACH ROW-行级触发器BEGIN由三种事IF INSERTING THENINSERT INTO logsVALUES(logs_id_squ.NEXTVAL,EMP,INSERT,:new.empno,SYSDATE,USER);ELSIF DELETING THENINSERT INTO logsVALUES(logs_id_squ.NEXTVAL,EMP,DELETE,:old.empno,SYSDATE,USER);ELSEINSERT INTO log

16、sVALUES(logs_id_squ.NEXTVAL,EMP,UPDATE,:new.empno,SYSDATE,USER);END IF;END;CREATE OR REPLACE TRIGGER DML_LOGBEFORE-触发时间为操作前DELETE OR INSERT OR UPDATE-由三种事件触发ON empFOR EACH ROW-行级触发器BEGINIF INSERTING THENINSERT INTO logsVALUES(logs_id_squ.NEXTVAL,EMP,INSERT,:new.empno,SYSDATE,USER);ELSIF DELETING THE

17、NINSERT INTO logsVALUES(logs_id_squ.NEXTVAL,EMP,DELETE,:old.empno,SYSDATE,USER);ELSEINSERT INTO logsVALUES(logs_id_squ.NEXTVAL,EMP,UPDATE,:new.empno,SYSDATE,USER);END IF;END;执行结果:触发器已创建步骤 4:在 EMP 表中插入记录:Sql 代码INSERT INTO emp(empno,ename,job,sal)VALUES(8001,MARY,CLERK,1000);COMMIT;INSERT INTO emp(emp

18、no,ename,job,sal)VALUES(8001,MARY,CLERK,1000);COMMIT;执行结果:Sql 代码已创建 1 行。提交完成。已创建 1 行。提交完成。步骤 5:检查 LOGS 表中记录的信息:Sql 代码SELECT*FROM LOGS;SELECT*FROM LOGS;执行结果为:Sql 代码LOG_ID LOG_TABLELOG_DMLLOG_KEY_IDLOG_DATELOG_USER-1 EMPINSERT800129-3 月-04STUDENT已选择 1 行。LOG_ID LOG_TABLELOG_DMLLOG_KEY_IDLOG_DATELOG_USE

19、R-1 EMPINSERT800129-3 月-04STUDENT已选择 1 行。说明:本例中在emp表上创建了一个由 INSERT 或DELETE或 UPDATE 事件触发的行级触发器,触发器的名称是LOG_EMP。对于不同的操作,记录的内容不同。本例中只插入了一条记录,如果用一条不带 WHERE 条件的 UPDATE语句来修改所有雇员的工资,则将逐行触发触发器。INSERT、DELETE 和 UPDATE 都能引发触发器动作,在分支语句中使用 INSERTING、DELETING 和 UPDATING 来区别是由哪种操作引发的触发器动作。在本例的插入动作中,LOG_ID 字段由序列 LOG

20、_ID_SQU自动填充为 1;LOGS 表 LOG_KEY_ID 字段记录的是新插入记录的主键 8001;LOD_DML 字段记录的是插入动作INSERT;LOG_TABLE 字段记录当前表名 EMP;LOG_DATE 字段记录插入的时间 04 年 3 月 1 日;LOG_USER 字段记录插入者 STUDENT。【练习 1】修改、删除刚刚插入的雇员记录,提交后检查LOGS 表的结果。【练习 2】为 DEPT 表创建同样的触发器,使用 LOGS 表进行记录,并检验结果。【训练 2】创建一个行级触发器 LOG_SAL,记录对职务为 CLERK 的雇员工资的修改,且当修改幅度超过 200 时才进行

21、记录。用 WHEN 条件限定触发器。在创建触发器之前,需要先创建事件记录表 LOGERR,该表用来对操作进行记录。该表的字段含义解释如下:NUM:数值型,用于记录序号。MESSAGE:字符型,用于记录错误信息。步骤 1:在 SQL*Plus 中登录 STUDENT 账户,创建如下的记录表 LOGERR:Sql 代码CREATE TABLE logerr(NUM NUMBER(10)NOT NULL,MESSAGE VARCHAR2(50)NOT NULL);CREATE TABLE logerr(NUM NUMBER(10)NOT NULL,MESSAGE VARCHAR2(50)NOT NU

22、LL);执行结果:Sql 代码表已创建。表已创建。步骤 2:创建和编译以下触发器:Sql 代码CREATE OR REPLACE TRIGGER log_salBEFOREUPDATE OF salON empFOR EACH ROWWHEN(new.job=CLERK AND(ABS(new.sal-old.sal)>200)DECLAREv_no NUMBER;BEGINSELECT COUNT(*)INTO v_no FROM logerr;INSERT INTO logerr VALUES(v_no+1,雇员|:new.ename|的原工资:|:old.sal|新工资:|:new

23、.sal);END;CREATE OR REPLACE TRIGGER log_salBEFOREUPDATE OF salON empFOR EACH ROWWHEN(new.job=CLERK AND(ABS(new.sal-old.sal)>200)DECLAREv_no NUMBER;BEGINSELECT COUNT(*)INTO v_no FROM logerr;INSERT INTO logerr VALUES(v_no+1,雇员|:new.ename|的原工资:|:old.sal|新工资:|:new.sal);END;执行结果:Sql 代码触发器已创建。触发器已创建。步骤

24、 3:在 EMP 表中更新记录:Sql 代码UPDATE emp SET sal=sal+550 WHERE empno=7788;UPDATE emp SET sal=sal+500 WHEREempno=7369;UPDATE emp SET sal=sal+50 WHEREempno=7876;COMMIT;UPDATE emp SET sal=sal+550 WHERE empno=7788;UPDATE emp SET sal=sal+500 WHERE empno=7369;UPDATE emp SET sal=sal+50 WHERE empno=7876;COMMIT;执行结果

25、:Sql 代码已更新 1 行。已更新 1 行。已更新 1 行。提交完成。已更新 1 行。已更新 1 行。已更新 1 行。提交完成。步骤 4:检查 LOGSAL 表中记录的信息:SELECT*FROM logerr;SELECT*FROM logerr;Sql 代码执行结果为:Sql 代码NUM MESSAGE-1 雇员 SMITH 的原工资:800 新工资:1300已选择 1 行。NUM MESSAGE-1 雇员 SMITH 的原工资:800 新工资:1300已选择 1 行。说明:本例中,在emp表的sal列上创建了一个由UPDATE事件触发的行级触发器,触发器的名称是 LOG_SAL。该触发

26、器由 WHEN 语句限定,只有当被修改工资的雇员职务为CLERK,且修改的工资超过 200 时才进行触发,否则不进行触发。所以在验证过程中,虽然修改了 3 条记录,但通过查询语句发现:第一条修改语句修改编号为 7788 的 SCOTT 记录,因为 SCOTT 的职务是 ANALYST,不符合 WHEN 条件,没有引起触发器动作;第二条修改语句修改编号为 7369 的SMITH 的记录,职务为 CLERK,因为增加的工资(500)超过了 200,所以引起触发器动作,并在 LOGERR 表中进行了记录;第三条修改语句修改编号为 7876 的雇员 ADAMS 的记录,虽然 ADAMS 的职务为 CL

27、ERK,但修改的工资(50)没有超过 200,所以没有引起触发器动作。注意:在 WHEN 条件中引用 new 和 old 不需要在前面加“:”。在以上实例中,记录了对工资的修改超出范围的信息,但没有限制对工资的修改。那么当对雇员工资的修改幅度不满足条件时,能否直接限制对工资的修改呢?答案是肯定的。【训练 3】创建触发器 CHECK_SAL,当对职务为 CLERK的雇员的工资修改超出 500 至 2000 的范围时,进行限制。步骤 1:创建和编译以下触发器:Sql 代码CREATE OR REPLACE TRIGGER CHECK_SALBEFOREUPDATEON em

28、pFOR EACH ROWBEGINIF:new.job=CLERK AND(:new.sal<500OR:new.sal>2000)THENRAISE_APPLICATION_ERROR(-20001,工资修改超出范围,操作取消!);END IF;END;CREATE OR REPLACE TRIGGER CHECK_SALBEFOREUPDATEON empFOR EACH ROWBEGINIF:new.job=CLERK AND(:new.sal<500OR:new.sal>2000)THENRAISE_APPLICATION_ERROR(-20001,工资修改超

29、出范围,操作取消!);END IF;END;执行结果:Sql 代码触发器已创建。触发器已创建。步骤 2:在 EMP 表中插入记录:Sql 代码UPDATE emp SET sal=800 WHERE empno=7876;UPDATE emp SET sal=450 WHEREempno=7876;COMMIT;UPDATE emp SET sal=800 WHERE empno=7876;UPDATE emp SET sal=450 WHERE empno=7876;COMMIT;执行结果:Sql 代码UPDATE emp SET sal=450 WHERE empno=7876*ERROR

30、 位于第 1 行:ORA-20001:工资修改超出范围,操作取消!ORA-06512:在STUDENT.CHECK_SAL,line 3ORA-04088:触发器 STUDENT.CHECK_SAL执行过程中出错提交完成。UPDATE emp SET sal=450 WHERE empno=7876*ERROR 位于第 1 行:ORA-20001:工资修改超出范围,操作取消!ORA-06512:在STUDENT.CHECK_SAL,line 3ORA-04088:触发器 STUDENT.CHECK_SAL 执行过程中出错提交完成。步骤 3:检查工资的修改结果:Sql 代码SELECT empn

31、o,ename,job,sal FROM emp WHEREempno=7876;SELECT empno,ename,job,sal FROM emp WHEREempno=7876;执行结果为:Sql 代码EMPNO ENAMEJOBSAL-7876ADAMSCLERK800EMPNO ENAMEJOBSAL-7876ADAMSCLERK800说明:在触发器中,当 IF 语句的条件满足时,即对职务为CLERK 的雇员工资的修改超出指定范围时,用RAISE_APPLICATION_ERROR 语句来定义一个临时定义的异常,并立即引发异常。由于触发器是 BEFORE 类型,因此触发器先执行,触

32、发器因异常而终止,SQL 语句的执行就会取消。通过步骤 2 的执行信息可以看到,第一条语句修改编号为7876 的雇员 ADAMS 的工资为 800,成功执行。第二条语句修改雇员 ADAMS 的工资为 450,发生异常,执行失败。这样就阻止了不符合条件的工资的修改。通过步骤3 的查询可以看到,雇员 ADAMS 最后的工资是 800,即发生异常之前的修改结果。【练习 3】限定对 emp 表的修改,只能修改部门 10 的雇员工资。【训练 4】创建一个行级触发器 CASCADE_UPDATE,当修改部门编号时,EMP 表的相关行的部门编号也自动修改。该触发器称为级联修改触发器。步骤 1:创建和编译以下

33、触发器:Sql 代码CREATE TRIGGER CASCADE_UPDATEAFTERUPDATE OF deptnoON DEPTFOR EACH ROWBEGINUPDATEEMP SET EMP.DEPTNO=:NEW.DEPTNOWHERE EMP.DEPTNO=:OLD.DEPTNO;END;CREATE TRIGGER CASCADE_UPDATEAFTERUPDATE OF deptnoON DEPTFOR EACH ROWBEGINUPDATEEMP SET EMP.DEPTNO=:NEW.DEPTNOWHERE EMP.DEPTNO=:OLD.DEPTNO;END;执行结果

34、:Sql 代码触发器已创建触发器已创建步骤 2:验证触发器:Sql 代码UPDATE dept SET deptno=11 WHERE deptno=10;COMMIT;UPDATE dept SET deptno=11 WHERE deptno=10;COMMIT;执行结果:Sql 代码已更新 1 行。已更新 1 行。执行查询:Sql 代码SELECT empno,ename,deptno FROM emp;SELECT empno,ename,deptno FROM emp;执行结果:Sql 代码EMPNO ENAMEDEPTNO-7369 SMITH207499 ALLEN307521

35、WARD307566 JONES207654 MARTIN307698 BLAKE307782 CLARK117839 KING117844 TURNER307876 ADAMS207900 JAMES307902 FORD207934 MILLER117788 SCOTT20EMPNO ENAMEDEPTNO-7369 SMITH207499 ALLEN307521 WARD307566 JONES 207654 MARTIN 307698 BLAKE307782 CLARK 117839 KING117844 TURNER307876 ADAMS207900 JAMES 307902 FO

36、RD 207934 MILLER117788 SCOTT 20说明:通过检查雇员的部门编号,发现原来编号为 10 的部门编号被修改为 11。本例中的 UPDATE OF deptno 表示只有在修改表的DEPTNO 列时才引发触发器,对其他列的修改不会引起触发器的动作。在触发器中,对雇员表的部门编号与修改之前的部门编号一样的雇员,修改其部门编号为新的部门编号。注意,在语句中同时用到了:new 和:old 来引用修改部门编号前后的部门编号。【练习 4】建立级联删除触发器 CASCADE_DELETE,当删除部门时,级联删除 EMP 表的雇员记录。利用触发器还可以修改数据。【训练 5】将插入的雇员

37、的名字变成以大写字母开头。步骤 1:创建和编译以下触发器:Sql 代码CREATE OR REPLACE TRIGGER INITCAPBEFORE INSERTON EMPFOR EACH ROWBEGIN:new.ename:=INITCAP(:new.ename);END;CREATE OR REPLACE TRIGGER INITCAPBEFORE INSERTON EMPFOR EACH ROWBEGIN:new.ename:=INITCAP(:new.ename);END;执行结果:Sql 代码触发器已创建。触发器已创建。步骤 2:验证运行结果:Sql 代码INSERT INTO

38、emp(empno,ename,job,sal)VALUES(1000,BILL,CLERK,1500);INSERT INTO emp(empno,ename,job,sal)VALUES(1000,BILL,CLERK,1500);执行结果:Sql 代码已创建 1 行。已创建 1 行。执行查询:Sql 代码SELECT ename,job,sal FROM emp WHEREempno=1000;SELECT ename,job,sal FROM emp WHEREempno=1000;执行结果:Sql 代码ENAMEJOBSAL-BillCLERK1500ENAMEJOBSAL-Bill

39、CLERK1500说明:在本例中,通过直接为:new.ename 进行赋值,修改了插入的值,但是这种用法只能在 BEFORE 型触发器中使用。验证结果为,在插入语句中雇员名称为大写的BILL,查询结果中雇员名称已经转换成以大写开头的 Bill。【练习 5】限定一次对雇员的工资修改不超过原工资的 10%。语句级触发器的应用同行级触发器不同,语句级触发器的每个操作语句不管操作的行数是多少,只触发一次触发器,所以语句级触发器适合于对整个表的操作权限等进行控制。在触发器定义中若省略FOR EACH ROW 子句,则为语句级触发器。【训练 1】创建一个语句级触发器 CHECK_TIME,限定对表 EMP

40、 的修改时间为周一至周五的早 8 点至晚 5 点。步骤 1:创建和编译以下触发器:Sql 代码CREATE OR REPLACE TRIGGER CHECK_TIMEBEFOREUPDATE OR INSERT OR DELETEON EMPBEGINIF(TO_CHAR(SYSDATE,DY)IN(SAT,SUN)OR TO_CHAR(SYSDATE,HH24)<08OR TO_CHAR(SYSDATE,HH24)>=17 THENRAISE_APPLICATION_ERROR(-20500,非法时间修改表错误!);END IF;END;CREATE OR REPLACE TRI

41、GGER CHECK_TIMEBEFOREUPDATE OR INSERT OR DELETEON EMPBEGINIF(TO_CHAR(SYSDATE,DY)IN(SAT,SUN)OR TO_CHAR(SYSDATE,HH24)<08OR TO_CHAR(SYSDATE,HH24)>=17 THENRAISE_APPLICATION_ERROR(-20500,非法时间修改表错误!);END IF;END;执行结果:Sql 代码触发器已创建。触发器已创建。步骤 2:当前时间为 18 点 50 分,在 EMP 表中插入记录:Sql代码UPDATE EMP SET SAL=3000 W

42、HERE EMPNO=7369;UPDATE EMP SET SAL=3000 WHERE EMPNO=7369;显示结果为:Sql 代码UPDATE EMP SET SAL=3000 WHERE EMPNO=7369*ERROR 位于第 1 行:ORA-20500:非法时间修改表错误!ORA-06512:在STUDENT.CHECK_TIME,line5ORA-04088:触发器 STUDENT.CHECK_TIME执行过程中出错UPDATE EMP SET SAL=3000 WHERE EMPNO=7369*ERROR 位于第 1 行:ORA-20500:非法时间修改表错误!ORA-065

43、12:在STUDENT.CHECK_TIME,line 5ORA-04088:触发器 STUDENT.CHECK_TIME 执行过程中出错说明:通过引发异常限制对数据库进行的插入、删除和修改操作的时间。SYSDATE 用来获取系统当前时间,并按不同的格式字符串进行转换。“DY”表示获取英文表示的星期简写,“HH24”表示获取 24 小时制时间的小时。当在 18 点 50 分修改表中的数据时,由于时间在 8 点至 17点(晚 5 点)之外,所以产生“非法时间修改表错误”的用户自定义错误,修改操作终止。【练习 1】设计一个语句

44、级触发器,限定只能对数据库进行修改操作,不能对数据库进行插入和删除操作。在需要进行插入和删除时,将触发器设置为无效状态,完成后重新设置为生效状态。数据库事件触发器数据库事件触发器有数据库级和模式级两种。前者定义在整个数据库上,触发事件是数据库事件,如数据库的启动、关闭,对数据库的登录或退出。后者定义在模式上,触发事件包括模式用户的登录或退出,或对数据库对象的创建和修改(DDL 事件)。数据库事件触发器的触发事件的种类和级别如表 9-3 所示。Sql 代码种类关 键 字说明模式级 CREATE在创建新对象时触发ALTER修改数据库或数据库对象时触发DROP删除对象时触发数据库级STARTUP 数

45、据库打开时触发SHUTDOWN在使用 NORMAL 或 IMMEDIATE 选项关闭数据库时触发SERVERERROR发生服务器错误时触发数据库级与模式级LOGON当用户连接到数据库,建立会话时触发LOGOFF当会话从数据库中断开时触发种类关 键 字说明模式级CREATE在创建新对象时触发ALTER 修改数据库或数据库对象时触发DROP删除对象时触发数据库级STARTUP 数据库打开时触发SHUTDOWN 在使用NORMAL或IMMEDIATE选项关闭数据库时触发SERVERERROR发生服务器错误时触发数据库级与模式级LOGON当用户连接到数据库,建立会话时触发LOGOFF当会话从数据库中断

46、开时触发定义数据库事件和模式事件触发器创建数据库级触发器需要 ADMINISTER DATABASETRIGGER 系统权限,一般只有系统管理员拥有该权限。对于模式级触发器,为自己的模式创建触发器需要 CREATETRIGGER 权限,如果是为其他模式创建触发器,需要CREATE ANY TRIGGER 权限。数据库事件和模式事件触发器的创建语法与 DML 触发器的创建语法类似。数据库事件或模式事件触发器的创建语法如下:CREATE OR REPLACE TRIGGER 触发器名BEFORE|AFTER DDL事件1 DDL事件2.|数据库事件1 数据库事件2.ON DATABASE|模式名.

47、SCHEMA WHEN(条件)DECLARE声明部分BEGIN主体部分END;其中:DATABASE 表示创建数据库级触发器,数据库级要给出数据库事件;SCHEMA 表示创建模式级触发器,模式级要给出模式事件或 DDL 事件。在数据库事件触发器中,可以使用如表 9-4 所示的一些事件属性。不同类型的触发器可以使用的事件属性有所不同。Sql代码属性适用触发器类型 说明Sys.sysevent所有类型返回触发器触发事件字符串Sys.instance_num所有类型返回 Oracle 实例号Sys.database_name所有类型返回数据库名字Sys.server_error(stack_posi

48、tion)SERVERERROR 从错误堆栈指定位置返回错误号,参数为 1 表示最近的错误Is_servererror(error_number)SERVERERROR 判断堆栈中是否有参数指定的错误号Sys.login_user所有类型返回导致触发器触发的用户名Sys.dictionary_obj_type CREATE、ALTER、DROP返回DDL 触发器触发时涉及的对象类型Sys.dictionary_obj_nameCREATE、ALTER、DROP返回 DDL 触发器触发时涉及的对象名称Sys.des_encrypted_passwordCREATE、ALTER、DROP创建或修改

49、用户时,返回加密后的用户密码属性适用触发器类型说明Sys.sysevent 所有类型返回触发器触发事件字符串Sys.instance_num所有类型返回 Oracle 实例号Sys.database_name所有类型返回数据库名字Sys.server_error(stack_position)SERVERERROR从错误堆栈指定位置返回错误号,参数为 1 表示最近的错误Is_servererror(error_number)SERVERERROR 判断堆栈中是否有参数指定的错误号Sys.login_user所有类型返回导致触发器触发的用户名Sys.dictionary_obj_typeCREA

50、TE、ALTER、DROP返回DDL 触发器触发时涉及的对象类型Sys.dictionary_obj_name CREATE、ALTER、DROP返回 DDL 触发器触发时涉及的对象名称Sys.des_encrypted_passwordCREATE、ALTER、DROP数据库事件触发器下面是一个综合的数据库事件触发器练习。先为 STUDENT账户授予创建数据库事件触发器的权限,ADMINISTERDATABASE TRIGGER,然后创建有关的表和触发器,最后予以验证。【训练 1】创建触发器,对本次数据库启动以来的用户创建或修改用户时,返回加密后的用户密码登录时间进行记录,每次数据库启动后,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 高考资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁