- 2.62 MB
- 2022-04-29 14:23:38 发布
- 1、本文档共5页,可阅读全部内容。
- 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
- 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
- 文档侵权举报电话:19940600175。
'木桶理论在教育教学实际运用中的启示_图文.
Oracle数据库技术触发器
教学目标掌握触发器的概念掌握触发器的定义和使用方法了解在触发器中如何抛出用户自定义异常信息
重点及难点触发器定义触发器应用(难点)
触发器触发器类似于过程或函数,因为它们都是拥有声明、执行和异常处理过程的带名PL/SQL块。与包类似,触发器必须存储在数据库中并且不能被块进行本地化声明。但是,对于过程而言.可以从另一个块中通过过程调用显式地执行一个过程。同时在调用时可以传递参数。对于触发器而言,当触发事件发生时就会显式地执行该触发器。并且触发器不接受参数。执行触发器的操作就是“点火”(firing)触发器。触发器事件是在数据库表上执行的DML(INSERT、UPDATE或DELETE)操作。
触发器可以使用触发器做许多事情,包括1。维护不可能在表创建时刻通过声明性约束进行的复杂的完整性约束限制。2。通过记录所进行的修改以及谁进行了修改来审计表中的信息。3。当表被修改的时候,自动给其他需要执行操作的程序发信号。
触发器触发器不可缺少的部件是触发器名、触发事件和触发器主体。1.触发器名触发器名的名字空间不同于其他子程序的名字空间。“名字空间”是可以用作对象名字的合法标识符的集合。过程、包和表的名字空间相同。这就是说,为过程和包赋予相同的名字将是非法的。但是,触发器却使用的是单独的名字空间。这意味着触发器可以使用和表或过程相同的名字。但是,在一个数据模式中,一个名字仅能用于一个触发器。
触发器触发器事件决定了触发器的类型。触发器可以按照INSERT、UPDATE或DELETE操作进行定义,并且它们也可以点火进行行操作或语句操作。触发器也可以对多种类型的触发语句点火。
触发器的语法结构完整的过程结构如下:createorreplacetrigger触发器名[before|after|insteadof]trigger_event[foreachrow]begin执行语句段;exception异常处理语句段;end;
注意事项(1)一个FOREACHROW执行指定操作的触发器为操作修改的每一行都调用一次(行级触发器)。若不带该参数则表示该触发器为语句级触发器,语句级触发器只在插入,修改或删除时执行一次,无论插入,修改,删除影响的是单行还是多行。(2)SELECT并不更改任何行,因此不能创建SELECT触发器。(3)触发器和某一指定的表格有关,当该表格被删除时,任何与该表有关的触发器同样会被删除。(4)在一个表上的每一个动作只能有一个触发器与之关联。
Instead-of触发器PL/SQL提供了另外一种触发器。Instead-of触发器仅可以定义在视图上,并且它们可以替代点火它们的DML语句进行点火。Instead-of触发器必须是行级的。Instead-of触发器是必要的,因为定义触发器的视图可能基基于联结(join)并且并非所有的联结都是可更新的。该触发器便可以按照所需的方式执行更新。例如:
Instead-of触发器定义下面的视图:createorreplaceviewstu_avgasselectsno,avg(grade)stu_avgfromscgroupbysno;若执行下面语句:deletefromstu_avgwheresno="001";则报错:ORA-01732:此视图的数据操纵操作非法
Instead-of触发器创建触发器:createorreplacetriggerstu_avg_deleteinsteadofdeleteonstu_bforeachrowbegindeletefromscwheresno=:old.sno;end;再执行删除语句,则删除成功。
对触发器的限制触发器的主体是一个PL/SQL块。在PL/SQL块中可以使用的所有语句在触发器主体中都是合法的,但是要受到下面限制的约束:1.触发器不应该使用事务控制语句-COMMIT,ROLLBACK或SAVEPOINT。触发器作为触发语句执行的一部分被点火,它和触发语句在同一个事务中。当触发语句被提交或撤回提交时,触发器的上作也相应被提交或撤回提交。2.由触发器主体调用的任何过程或函数都不能使用事务控制语句。3.触发器主体不能声明任何LONG或LONGRAW变量。而且,:new和:old不能指向定义触发器的表中的LONLONG或LONGRAW列。4.触发器主体可以访问的表有所限制。根据触发器类型以及在表上的约束限制的不同,表可能也会变化。
查询,删除和禁止触发器在user_triggers视图中可以查询触发器:select*fromuser_triggerswheretrigger_name=upper("stu_avg_delete");删除触发器:Droptriggerstu_avg_delete;禁止和打开触发器:altertriggerstu_avg_deletedisable|enable;
查询,删除和禁止触发器禁止和打开一个表的所有触发器:altertablerenable|disablealltriggers;当包或者子程序存储在数据字典中时,存储的除了该对象的源代码还有经过编译的p-coad。但是对于触发器就不是这样的。在数据字典中唯一存储的是触发器的源代码,而不是p-code。结果,每次当从数据字典中重新读出触发器时,必须要进行编译。
触发器点火次序当DML语句被执行时就会点火触发器。下面给出了执行DML语句的算法:1)执行EEFORE语句级触发器(如果有的话)2)对于受语句影响的每一行:a.执行BEFORE行级触发器(如果有的话)b.执行DML语句。c.执行AFTER行级触发器(如果有的话)3)执行AFTER语句级触发器(如果有的话)
在行级触发器中使用:new和:old触发语句所处理的每一行都点火一次行级触发器。在触发器的内部,可以访问当前正在被处理的行。这是通过“伪记录”—:old和:new实现的。:old和:new不是真实的记录。尽管从语法上讲,它们的处理方式和记录是一样的,但实际上它们不是,所以它们就被称为伪记录。它们的类型是:Triggering_table%rowtype
在行级触发器中使用:new和:oldINSERT语句没有对:old进行定义,DELETE语句也没有对:new进行定义。如果在INSERT中使用了:old或者在DELETE中使用:new,PL/SQL编译器将不会产生错误。但是它们的取值都将是NuLL。注意:尽管:new和:old在语法上被作为R0WTYPE的记录进行处理,但是实际上它们并不是记录。结果,许多通常对记录是有效的操作对于:new和:old是无效的。
触发器实例CREATEORREPLACETRIGGERai_org_trigAFTERINSERTONorg_tabFOREACHROWBEGINUPDATEsec_hrc_auditSETnum_rows=num_rows+1WHEREhrc_code=:NEW.hrc_code;IF(SQL%NOTFOUND)THENINSERTINTOsec_hrc_auditVALUES(:NEW.hrc_code,1);ENDIF;END;
CREATEORREPLACETRIGGERai_org_trig_statementAFTERINSERTONorg_tabBEGINFORidxIN(SELECThrc_code,COUNT(*)cntFROMorg_tabGROUPBYhrc_code)LOOPUPDATEsec_hrc_auditSETnum_rows=idx.cntWHEREhrc_code=idx.hrc_code;IF(SQL%NOTFOUND)THENINSERTINTOsec_hrc_auditVALUES(idx.hrc_code,idx.cnt);ENDIF;ENDLOOP;END;触发器实例
变化表触发器主体可以访问的表和列上有一些限制。在定义这些限制以前,必须先要认识变化表和限制表。“变化表”是被DML语句正在修改的表。对于触发器而言,它就是定义触发器的表。需要作为DELETECASADE参考完整性限制的结果进行更新的表也是变化的。“限制表”是可能需要对参考完整性限制执行读操作的表。比如,对于SC表上的操作进行触发器定义时,SC为变化表,Student和Course表为限制表。(假设SC表上定义了两个外建)
触发器主体中的SQL语句不允许进行:1。读取或修改触发语句的任何变化表。这些表也包括触发表自己。2。读取或修改触发表的限制表中的主键、唯一值列或外键列。但是如果需要的话,可以修改其他的列。这些限制法则适用于所有的行级触发器。仅当在执行DELETECASCADE操作时启动语句触发器时,它们才适用于语句触发器。
触发器主体中的SQL语句不允许进行:如果INSERT语句仅影响一个行,那么该行的BEFORE行触发器将不会将触发表作为变化表进行处理。这是行级触发器可以从触发表中执行读或修改操作的唯一可能的情况。象下面这样的语句:INSERTINTOT1SELECT…将始终将触发表作为变化表处理,甚至尽管子查询仅返回一行。
消除变化表错误sc表仅仅对于行级触发器是变化的。这就是说,我们不能在行级触发器中查询它,但是可以在语句级触发器中查询它。但是,我们不能简单地将行级触发器转换为语句触发器.因为我们需要在触发器主体中使用:new,:old的取值。解这个问题的方法是创建两个触发器——一个行级触发器,另一个是语句级触发器。在行级触发器中,我们记录:new,:old的取值,但是不对该表进行查询。在语句级触发器中执行查询并使用行级触发器记录下的数值。我们如何记录这个数值呢?最好的方法是使用包。
思考Oracle提供了执行“级联删除”(deletecascade)的功能。进行级联删除时.当从一个父表(Parenttable)中删除了一个行,那么通过外键依赖于父表的子表(childtable)中的相关的行也会被删除。但是,没有缺省实现的级联更新(updatecascade)。通过生成支持级联更新所需要的包和触发器同时又不违反声明的参考完整性限制,可以完成该功能。如何实现?
约束约束的检查功能立即执行的约束(Immediateconstraints)语句执行完后立即检查是否违背完整性约束延迟执行的约束(Deferredconstrainsts)完整性检查延迟到整个事务执行结束后进行
创建和删除约束示例Altertablescaddconstraintfk_sc_snoforeignkey(sno)referencesstudent(sno)deferrable;--定义该约束为可延迟约束并设置为延迟约束当定义约束时使用了Deferrable选项后,就可以设置该约束为立即执行约束还是延迟约束,若定义约束时没有Deferrable选项,则不能将其设置为延迟约束。Setconstraintfk_sc_snoimmediateSetconstraintfk_sc_snodeferred
RAISE_APPLICATlON_ERROR可以使用内置函数RAISE_APPLICATlON_ERROR创建自己的错误消息,这可能要比已命名的异常情态更具说明性。用户定义消息从块中传递到调用环境中的方式和Oracle错误是一样的。RAISE_APPLICATlON_ERROR的语法如下:RAISE_APPLICATlON_ERROR(ErrorNumber,ErrorMessage,[keep_errors])
RAISE_APPLICATlON_ERROR这里ErrNumber是从-20,000到-20,999之间的参数,ErrorMessage是与此错误相关的正文,而keep_errors是一个布尔值。ErrorMessage必须是不多于512个字节。布尔值参数keep_errors是可选曲。如果keep_errors是TRUE,那么新的错误将被添加到已经引发的错误列表中(如果有的话)。如果它是FALSE(这是缺省的设置),那么新的错误将替换错误的当前列表。
小结触发器是一种特殊的过程,他不能被显式的调用,而是自动触发有三类触发器:分别为插入触发器,删除触发器和修改触发器;对于视图有INSTEADOF触发器。触发器分为行级触发器和语句级触发器变化表不能在行级触发器中读或写触发器中可以自行抛出异常,使用的语句为:RAISE_APPLICATlON_ERROR
在Student表中添加列:sum_Grade(总成绩),avg_grade(平均成绩)。在SC表中作一触发器,当添加,删除或修改一行之后,将该学生在Student表中的总成绩和平均成绩相应改变。练习1
在Student和Course表中作一修改触发器,当修改Student表的sno或修改Course表中的cno时,SC表的相应字段要跟着变化。在Student和Course表中作一删除触发器,当删除这两个表的记录时SC表中相应记录一起删除。练习2'
您可能关注的文档
- 最新望海潮赏析方法课件PPT.ppt
- 最新望海潮王珍解析课件PPT.ppt
- 最新望海潮公开课一等奖课件解析课件PPT.ppt
- 最新望海潮ppt课件PPT.ppt
- 最新期末复习Unit8概要1课件PPT.ppt
- 最新期末主题班会课件PPT.ppt
- 最新期货入门知识-实战操作篇课件PPT.ppt
- 最新木偶的故事课件PPT.ppt
- 最新木材的化学性质1课件PPT.ppt
- 最新未来的家乡作文指导课件PPT.ppt
- 最新未注公差课件PPT.ppt
- 最新本章学习目的与提要35课件PPT.ppt
- 最新本科胆疾病幻灯(2学时)课件PPT.ppt
- 最新本葡萄膜病a 课件PPT课件.ppt
- 最新术中中心供氧停止的应急预案课件PPT.ppt
- 最新术前访视、术中观察、术后随访PPT课件PPT课件.ppt
- 最新术前抗胆碱药物和麻醉诱导插管课件PPT.ppt
- 最新术后子宫内膜异位超声诊断---课件PPT.ppt