oracle异常及触发器

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

0oracle异常及触发器1异常处理什么是异常情态–异常处理处理的是运行时错误,异常分为预定义异常和用户自定义异常。–声明异常情态–异常情态在块的声明部分进行声明,在块的执行部分进行触发,在块的异常部分进行处理。用户定义类型异常情态,需要程序员自己定义代码,对异常情况进行处理。–例:–Declare–e_toomanystudentsexception;2–e_toomanystudents的作用域和本块的其他变量相同。预定义型异常情态–预定义型异常情态可以直接使用,没有必要声明。–Invalid_cursor:当执行非法的游标操作时,会引发这个错误,如试图关闭已关闭的游标。–Cursor_already_open:试图打开已经打开的游标,会引发这个错误。–No_data_found:当selectinto语句没有返回行时,和引用没有赋值过的pl/sql表的元素时会引发这个错误。–Too_may_rows:当selectinto语句返回多个行时,会引发这个错误。–Invalid_number:当试图从字符串转换为数值失败时,会引发这个错误,在过程性语句中会引发value_error错误。–如:下面的语句引发invalid_number错误,因为‘x’不是数值。–Insertintostudents(id,first_name,last_name)–values(‘x’,’scott’,’smith’);3–Storage_error和program_error:是内部的异常情态,通常不会引发他们。–Value_error:当在过程性语句中发生了算术、转换、截尾或限制性错误时会引发这个情态。如果在sql语句中发生错误,会引发invalid_number错误。这个错误可能是一条赋值语句或selectinto语句的执行结果。下面的两个例子都引发value_error错误。–Declare–v_tempvarvarchar2(3);–Begin–v_tempvar:='ABCD';–End;–Declare–v_tempvarnumber(2);–Begin–selectidintov_tempvarfromstudents–wherelast_name='smith';–End;4–触发异常情态当预定义的异常情态错误发生时,就会触发该异常情态。用户定义的异常情态由raise语句触发。例:–Declare–e_toomanystudentsexception–v_currentstudentsnumber(3);–v_maxstudentsnumber(3);–Begin–selectcurrent_students,max_students–intov_currentstudents,v_maxstudents–fromclasses–wheredepartment=‘HIS’andcourse=‘101’;5–ifv_currentstudentsv_maxstudentsthen–raisee_toomanystudents–Endif;–End;–当引发异常情态时,控制转给该块的异常处理部分。如果没有异常处理部分,该异常处理部分将传给包含该块的块。一旦将控制转给异常处理部分,没有办法再将控制返回给该块的执行部分。–处理异常情态异常部分的语法如下:–Exception–whenexception_namethen–处理错误语句序列–whenexception_namethen–处理错误语句序列–whenothersthen–处理错误语句序列–end;6–一个处理器可以对多个异常情态进行处理,用or连接–例:–Exceptionwhenno_data_foundortoo_many_rowsthen–insertintolog_table(info)values(‘aselecterroroccurred’);–End;Others异常处理器将对所有语法的异常情态进行处理,一般放在异常处理的最后,可以保证所有的错误都被检测到。–Declare–e_toomanystudentsexception–v_currentstudentsnumber(3);–v_maxstudentsnumber(3);–v_errorcodenumber;–v_errortextvarchar2(200);–Begin–selectcurrent_students,max_students–intov_currentstudents,v_maxstudents–fromclasses–wheredepartment=‘HIS’andcourse=‘101’;7–ifv_currentstudentsv_maxstudentsthen–raisee_toomanystudents–Endif;–Exception–whene_toomanystudentsthen–insertintolog_table(info)–values(‘history101has’||v_currentstudents||–‘students:maxallowedis‘||v_maxstudents);–whenothersthen–v_errorcode:=sqlcode;–v_errortext:=substr(sqlerrm,1,200);–insertintolog_table(info)–values(‘anothererroroccurred’);–end;–*sqlcode和sqlerrm先被赋值给本地变量,然后这些变量在sql语句中被使用,sqlcode和sqlerrm不能直接在sql语句中使用,因为他们是过程性的函数。sqlcode返回当前的错误号,sqlerrm返回当前的错误信息正文。––8代码消息使用的sqlerrm函数0ora-0000:normal,successfulcompletionsqlerrm(0)+100Ora-1403:nodatafoundsqlerrm(100)+10User-definedexceptionSqlerrm(10)nullora-0000:normal,successfulcompletionsqlerrm-1Ora-0001:uniqueconstraint(.)violatedSqlerrm(-1)-54Ora-00054:resourcebusyandacquirebynowaitspecifiedSqlerrm(-54)9–Exception_init–可以将一个经过命名的异常情态与一个特别的oracle错误相联系。这样可以用when扑获此错误,不用others扑获。通过exception_initpragma实现的。其语法如下:–Pragmaexception_init(exception_name,oracle_error_number)–Pragma必须在声明部分–例:下面的例子在运行时刻如遇到“ora-1400:mandatorynot–nullcolumnmissingornullduringinsert”错误时,将引发e_missingnull异常情态。–Declare–e_missingnullexception;–pragmaexception_init(e_missingnull,-1400);–Begin–insertintostudents(id)values(null);–Exception–whene_missingnullthen–insertintolog_table(info)values(‘ora-1400occurred’);–End;10–每次发生pragmaexception_init时,一个oracle错误只能和一个用户定义的异常情态相关联。在异常处理器内部,sqlcode和sqlerrm将返回发生oracle错误的代码和错误信息,而不会返回用户定义的消息。–例:–Declare–ex_hfyexception;–Pragmaexception_init(ex_hfy,-1400);–Begin–insertintostudentsvalues(null);–Exception–whenex_hfythen–dbms_output.put_line('不能把空值插入到非空列');–End;–注意,这里-1400不能为别的,因为把空值插入到非空列的错误号就是这个。可以单独执行insert语句查看错误号。11使用raise_application_error可以用raise_application_error创建自己的错误消息,这比命名的异常情态更具有说明性。其语法如下:Raise_application_error(error_number,error_message,[keep-errors]);这里error_number是从-20,000到-20,999之间的数,error_message是与此错误相关的错误正文。Keep_errors为布尔值,如果他为true,则新的错误被添加到已经引发的错误列表中(如果有的话)。如果为false(为缺省值),则新的错误将替换错误的当前列表。例:下面的过程为一个新的学生注册以前,检查是否在班级中有足够的地方容纳他。12––Createorreplaceprocedureregister(–p_studentidinstudents.id%type,–p_departmentinclasses.department%type,–p_courseinclasses.course%type)as–v_currentstudentsnumber;–v_maxstudentsnumber;–Begin–selectcurrent_students,max_students–intov_currentstudent,v_maxstudents–fromclasses–wheredepartment=p_department–andcourse=p_course;–13–ifv_currentstudents+1v_maxstudentsthen–raise_application_error(-20000,–‘can’’taddmorestudentsto’||–p_department||‘‘||p_course);–endif;–classpackage.addstudent(p_studentid,–p_department,p_course);–Exception–whenno_data_foundthen–raise_application_error(-20001,p_department||–‘‘||p_course||‘doesn’’texist!’);–Endregister;–以上程序运行时,当没有足够的空间容纳新的学生时,返回ora-20000:can’taddmorestudentstohis101错误消息。14触发器综述–触发器可以理解为特殊的存储过程。当应用程序用一条满足触发器条件的SQLDML语句指向与触发器相连接的表时,Oracle将自动执行该触发器以执行任务。–DML触发器,定义在对数据库表的操纵行为(insert,delete,update)上的触发器。–前触发器、后触发器。–语句触发、行触发15触发器使用数据库触发器的主要好处:1。触发器能够进行复杂的有效性检验。2。审计3。一个表中的触发器可以修改另一个表的内容。触发事件是通过对数据库表进行插入、删除和修改操作而引发的。16触发器在触发器内,行级触发器可以引用触发器触发时已存在行中各列的值。1)对于INSERT语句,要被插入的新行中各列的新值包含在:new.column_name其中column_name是表中的列名。2)对于UPDATE语句,将要被修改的行中各列的原来值包含在:old.column_name列

1 / 23
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功