




已阅读5页,还剩95页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
数据库应用技术第五章面向过程的SQL扩展,内容概要,服务器端程序PL/SQL的基本结构控制流过程与函数游标错误与异常处理触发器,服务器端程序,存储过程:用户创建,用SQL和其他语言(如PL/SQL)编写的过程或函数,存储在数据库内部,用来完成一个特定的任务。Oracle:PL/SQLMSSQL:Transaction-SQLPL/SQL:ORACLE对SQL进行扩展的过程式语言,具有通用程序设计语言的绝大部分特性,能够完成较为复杂和完整的功能可以用来编写存储过程。,服务器端程序,存储过程的优点安全:使用创建者权限、调用者不需要了解内部结构,不需要内部权限。性能:网络开销小,不传送中间结果节约SQL代码分析时间代码可重用完整性和一致性特性:可以使用变量、游标、控制结构,具有模块化、数据抽象、信息隐藏、错误处理等特性。,内容概要,服务器端程序PL/SQL的基本结构控制流过程与函数游标错误与异常处理触发器,PL/SQL的基本结构-块结构,块结构一个块的语法地位等价于一条语句块的整体构成DECLARE声明部分BEGIN执行部分EXCEPTION错误处理部分END;,PL/SQL的基本规则,每条语句可以写在多行每条语句都以;结尾。语句保留字和变量不区分大小写一般不要把变量名声明与表中字段名完全一样,如果这样可能得到不正确的结果,变量的定义与使用,变量类型简单变量类型和字段的变量类型相同记录变量类型一组具有不同类型的变量的集合,类似C中的STRUCT或PASCAL中的RECORD集合变量类型,变量的定义与使用,变量声明声明定义:变量名、变量类型缺省值必须先声明,后使用在declare段声明不允许前向引用一行中只能定义一个变量大小写不敏感,变量的定义与使用,简单示例emp_countNUMBER(4);(缺省值为NULL)缺省值blood_typeCHAR:=0;blood_typeCHARDEFAULT0;NOTNULL,必须有缺省值emp_countNUMBER(3)NOTNULL:=0;,变量的定义与使用,%TYPE使用其它变量或列的数据类型,但不继承NOTNULL属性语法:Variable_nametable.column%TYPEcreditNUMBER(7,2);debitcredit%TYPE;经常用于表中字段的数据类型my_dnamesales.sname%TYPE;优点:不需要知道精确类型;在表定义发生变化时,不用修改程序,变量的定义与使用,%ROWTYPE:用户用来定义单一的变量,包含对应于数据库表的每一列的多个变量。DECLAREemp_recemp%ROWTYPE;(表)CURSORc1ISSELECTdeptno,dname,locFROMdept;dept_recc1%ROWTYPE;(视图),变量的定义与使用,赋值与计算、比较使用:=作为赋值运算符通过SQLSELECTINTO或FETCHINTO给变量赋值SELECTSUM(SALARY),SUM(SALARY*0.1)INTOOTAL_SALARY,TATAL_COMMISSIONFROMEMPLOYEEWHEREDEPT=10;其他计算、比较方法类似于普通语言,比较中的短路赋值IF(on_hand=0)OR(on_order/on_handLOOP.LOOP.EXITWHENENDLOOP;.ENDLOOP;,控制流语句,WHILELOOPENDLOOP;FORIN.REVERSELOOPENDLOOP;,SQLcreatetabletest_loop(date1VARCHAR2(8),date2DATE);Tablecreated.Elapsed:00:00:00.15SQLDECLARE2v_datedate;3BEGIN4EXECUTEIMMEDIATEtruncatetabletest_loop;5forv_datein20100401.20100421LOOP6INSERTINTOtest_loop7(date1,date2)8SELECTv_date,to_date(v_date,YYYY-MM-DD)FROMdual;9ENDLOOP;10COMMIT;11END;,DECLARESUMXNUMBER;XNUMBER;BEGINSUMX:=0;X:=1;LOOPSUMX:=SUMX+X;X:=X+1;EXITWHENX100;ENDLOOP;X从1每次加1至100END;,控制流语句,定义标号:在PL/SQL中使用标号(也称做标签)来命名一段不能命名的代码,可以给循环定义一个标号,弥补了循环语句不能命名的缺陷,通过标号来直接引用这段代码。用“”来定义标号。跳转:GOTO标号;在使用GOTO语句时要注意以下规则:不能GOTO到嵌套块内部的标号;IF子句外部执行的语句,不能GOTO到IF子句内部的标号;IF子句内部执行的语句,不能GOTO到另一个IF子句内部的标号;不能从异常处理部分GOTO到代码其他部分(执行部分和声明部分)。GOTO语句降低了程序的可读性,破坏了程序的模块结构,所以应尽量避免使用无条件转移语句。,控制流语句,空语句NULL:空语句是一个占位语句,不执行任何操作。当不用实现具体功能时就用到了空语句,临时占位,以后需要具体的处理时直接替换即可。语法格式为:NULL;例:IF条件THENNULL;-占位符,否则编译不通过ELSE语句ENDIF;返回RETURN:控制返回调用环境,同时返回一个值。,内容概要,服务器端程序PL/SQL的基本结构控制流语句过程与函数游标错误与异常处理触发器,过程与函数-维护,过程(存储过程)在创建的时候都有独一无二的名字,执行的时候,可以有返回值也可以不返回值,但是必须返回执行成功或者失败的标志。一般都归创建的用户所有(除非在创建它们的脚本中专门进行了其他的描述)。函数与过程的不同在于前者必须返回值,它们的结构非常相似,最大的区别就是函数必须要带一个return语句。,过程与函数-维护,过程和函数有很多相同的功能特性:都可以使用OUT参数返回多个值;都可以有声明、执行和异常处理三个部分组成;都可以接收默认值;都可以使用位置表示法和名称表示法来进行调用;都可以接收NOCOPY参数。,过程与函数-维护,过程(procedure)CREATEORREPLACEPROCEDURE()AS|IS;:=IN|OUT|INOUTDEFAULT:无长度和精度ALTERPROCEDURECOMPILE;DROPPROCEDURE;,例、输出为HelloWorld的过程(无参过程)。Setserveroutputon;SQLcreateorreplaceprocedureoutput2is3begin4dbms_output.put_line(HelloWorld);5end;6/Procedurecreated.注:setserveroutputon;在控制台上显示输出信息,只在当前会话下有效。,例、向书库增加新图书(带有输入参数的过程)createorreplaceprocedureadd_books(bidbooks.bid%TYPE,statusbooks.status%TYPE,isbnbooks.isbn%TYPE,titlebooks.title%TYPE,classbooks.class%TYPE,pidbooks.pid%TYPE,authorsbooks.authors%TYPE,date_pubbooks.date_pub%TYPE,date_buybooks.date_buy%TYPE,pricebooks.price%TYPE,qty_allbooks.qty_all%TYPE,qty_availbooks.qty_avail%TYPE)isbegininsertintobooksvalues(bid,status,isbn,title,class,pid,authors,date_pub,date_buy,price,qty_all,qty_avail);end;/注:%TYPE的好处,当原表对应字段类型改变后,不会对过程产生影响。,例、更新指定作者写的图书价格且返回对应的书名(带有输出的参数过程)SQLcreateorreplaceprocedurebook_name2(new_pricenumber,namevarchar2,tnameoutvarchar2)3is4begin5updatebookssetprice=new_pricewhereauthors=name6returningtitleintotname;7end;8/注:变量名后加out表示可输出变量,例、求两个整数的和与差(创建带输入输出的参数过程)。SQLcreateorreplaceprocedureplusmin2(var1inoutnumber,var2inoutnumber)3is4v1number;5v2number;6begin7v1:=var1+var2;8v2:=var1-var2;9var1:=v1;10var2:=v2;11end;12/注:inout表示变量可以作为输入与输出变量使用。,过程与函数-维护,函数(function)CREATEORREPLACEFUNCTION()RETURNAS|IS;ALTERFUNCTIONCOMPILE;DROPFUNCTION;,例、建立和调用无参数的函数下面还是以建立输出HelloWorld为例。SQLcreateorreplacefunctionfun_output2returnvarchar23is4begin5returnHelloWorld;6end;7/调用:SQLbegin2dbms_output.put_line(fun_output);3end;4/HelloWorld,例、创建和调用带有输入参数的函数使用输入参数,可以得到表中相关数据。下面以返回书价的函数get_price为例,说明创建带有输入参数函数的方法。SQLcreateorreplacefunctionget_price(namevarchar2)2returnnumber3as4v_pricebooks.price%TYPE;5begin6selectpriceintov_pricefrombooks7whereupper(title)=upper(name);8returnv_price;9end;10/,调用:SQLbegin2dbms_output.put_line(书价:|get_price(Entervalueforname:EssentialC+old1:selectget_price(5begin6selectauthors,titleintoname,e_titlefrombooks7wherebid=e_bid;8returnname;9end;10/,调用get_book函数,得到对应的作者及书名。SQLdeclare2v_namebooks.authors%TYPE;3v_titlebooks.title%TYPE;4begin5v_name:=get_book(作者:StanleyB.Lippman,书名:EssentialC+,例、创建和调用带有输入输出参数的函数使用带有输入输出参数的函数,把输入书名的书价打8.5折,然后返回更新后书名对应的价格。SQLcreateorreplacefunctionup_price2(e_titlevarchar2,e_priceinoutvarchar2)returnvarchar23as4namebooks.authors%TYPE;5begin6updatebookssetprice=price*e_pricewheretitle=e_title7returntitle,priceintoname,e_price;8end;9/,过程与函数举例,计算某顾客在给定时间前一年的总购买金额,CREATEPROCEDUREp_1(v_cidINCHAR,v_sumOUTNUMBER,v_dateINDATEDEFAULTSYSDATE)ASBEGINSELECTSUM(dollars)INTOv_sumFROMordersWHEREcid=v_cidANDbuy_dateBETWEENv_date-365ANDv_date;END;,过程与函数,CREATEFUNCTIONf_1(v_cidINCHAR,v_dateINDATE)RETURNNUMBERASDECLAREv_sumNUMBER;BEGINSELECTSUM(dollars)INTOv_sumFROMordersWHEREcid=v_cidANDbuy_dateBETWEENv_date-365ANDv_date;RETURNv_sum;END;,创建与维护过程和函数,过程与函数,内部子过程在过程或函数的DECLARE部分定义,只供该过程或函数调用不能被外部使用声明时不使用关键字CREATE放在DECLARE中的最后部分先声明后使用,可前向声明。不单独存放在数据库中,创建与维护过程和函数,过程与函数,CREATEPROCEDUREp_3ASBEGINDECLAREv1NUMBER;PRODECURElp_1ASBEGINEND;PROCEDURElp_2ASBEGINlp_1;END;BEGINlp_1;lp_2;END;END;,内部子过程,过程与函数,位置表示:即在调用时按形参的排列顺序,依次写出实参的名称,而将形参与实参关联起来进行传递。用这种方法进行调用,形参与实参的名称是相互独立,没有关系,强调次序才是重要的。格式为:argument_value1,argument_value2DECLAREV_numNUMBER;V_sumNUMBER;BEGINV_sum:=get_salary(10,v_num);DBMS_OUTPUT.PUT_LINE(部门号为:10的工资总和:|v_sum|,人数为:|v_num);END;计算某部门的工资总和。,调用过程和函数,名称表示:即在调用时按形参的名称与实参的名称,写出实参对应的形参,而将形参与实参关联起来进行传递。这种方法,形参与实参的名称是相互独立的,没有关系,名称的对应关系才是最重要的,次序并不重要。格式为:argument=parameter,DECLAREV_numNUMBER;V_sumNUMBER;BEGINV_sum:=get_salary(emp_count=v_num,dept_no=10);DBMS_OUTPUT.PUT_LINE(部门号为:10的工资总和:|v_sum|,人数为:|v_num);END;,混和表示即在调用一个函数时,同时使用位置表示法和名称表示法为函数传递参数。采用这种参数传递方法时,使用位置表示法所传递的参数必须放在名称表示法所传递的参数前面。也就是说,无论函数具有多少个参数,只要其中有一个参数使用名称表示法,其后所有的参数都必须使用名称表示法。credit_acct(acct,amount=amt);,CREATEORREPLACEFUNCTIONdemo_fun(NameVARCHAR2AgeINTEGER,SexVARCHAR2)RETURNVARCHAR2ASV_varVARCHAR2(32);BEGINV_var:=name|:|TO_CHAR(age)|岁.|sex;RETURNv_var;END;DECLAREVarVARCHAR(32);BEGINVar:=demo_fun(user1,30,sex=男);DBMS_OUTPUT.PUT_LINE(var);Var:=demo_fun(user2,age=40,sex=男);DBMS_OUTPUT.PUT_LINE(var);Var:=demo_fun(user3,sex=女,age=20);DBMS_OUTPUT.PUT_LINE(var);END;,无论采用哪一种参数传递方法,实际参数和形式参数之间的数据传递只有两种方法:传址法和传值法。传址法是指在调用函数时,将实际参数的地址指针传递给形式参数,使形式参数和实际参数指向内存中的同一区域,从而实现参数数据的传递。这种方法又称作参照法,即形式参数参照实际参数数据。输入参数均采用传址法传递数据。传值法是指将实际参数的数据拷贝到形式参数,而不是传递实际参数的地址。默认时,输出参数和输入/输出参数均采用传值法。在函数调用时,ORACLE将实际参数数据拷贝到输入/输出参数,而当函数正常运行退出时,又将输出形式参数和输入/输出形式参数数据拷贝到实际参数变量中。,过程与函数,SQL*PLUS中,使用EXECUTE命令。在其他PL/SQL程序中,直接写出过程及参数CREATEPROCEDUREp_2ASBEGINDECLAREv1NUMBER(10);BEGINp_1(A01,v1,SYSDATE);/全局过程p_1END;END;,调用过程和函数,过程与函数,调用过程和函数,使用过程与函数具有如下优点,1、共同使用的代码可以只需要被编写和测试一次,而被需要该代码的任何应用程序(如:.NET、C+、JAVA、VB程序,也可以是DLL库)调用。2、这种集中编写、集中维护更新、大家共享(或重用)的方法,简化了应用程序的开发和维护,提高了效率与性能。3、这种模块化的方法,使得可以将一个复杂的问题、大的程序逐步简化成几个简单的、小的程序部分,进行分别编写、调试。因此使程序的结构清晰、简单,也容易实现。4、可以在各个开发者之间提供处理数据、控制流程、提示信息等方面的一致性。5、节省内存空间。它们以一种压缩的形式被存储在外存中,当被调用时才被放入内存进行处理。并且,如果多个用户要执行相同的过程或函数时,就只需要在内存中加载一个该过程或函数。6、提高数据的安全性与完整性。通过把一些对数据的操作放到过程或函数中,就可以通过是否授予用户有执行该过程或的权限,来限制某些用户对数据进行这些操作。,过程与函数的相同功能有:1、都使用IN模式的参数传入数据、OUT模式的参数返回数据。2、输入参数都可以接受默认值,都可以传值或传引导。3、调用时的实际参数都可以使用位置表示法、名称表示法或组合方法。4、都有声明部分、执行部分和异常处理部分。5、其管理过程都有创建、编译、授权、删除、显示依赖关系等。使用过程与函数的原则:1、如果需要返回多个值和不返回值,就使用过程;如果只需要返回一个值,就使用函数。2、过程一般用于执行一个指定的动作,函数一般用于计算和返回一个值。3、可以SQL语句内部(如表达式)调用函数来完成复杂的计算问题,但不能调用过程。所以这是函数的特色。,过程与函数,由多个过程可以组成包DBMS_OUTPUT.PUT_LINE();DBMS_OUTPUT:包名PUT_LINE:过程名,包(package),内容概要,服务器端程序PL/SQL的基本结构控制流过程与函数游标错误与异常处理触发器,作业,作业1:针对图书馆管理系统,写出以下过程:a.借一本书,b.还一本书。注:需要考虑到一些问题,例如书是否存在、书的数量是否够、借阅人是否存在、是否有罚款未交、借的过程如何记录下来。借阅人是否存在?作业2:针对示例数据库的Orders表,找出每种产品的销售总价,以及该产品最高的三笔交易,求其平均值,将其结果存在HIGH_DOLL表中。HIGH_DOLL(PID,HDOLLER),游标的作用,用来处理从数据库中查询出来的一组数据的机制。游标查询返回的数据称为结果集(resultset)。游标的使用类似文件操作,包括OPEN、FETCH、CLOSE等操作。游标的类型显式游标隐含游标PL/SQL为每一个DML语句隐含定义了一个游标包游标,使用游标,声明在DECLARE段打开循环读取读取当前行的数据到变量中判断是否读到末尾关闭关闭后才可以重新打开,使用游标,声明CURSOR()RETURNIS;:IN:=|DEFAULT参数只能是基本类型、必须是IN类型,可以有缺省值。,游标的声明,DECLARECURSORc1ISSELECTaid,aname,salaryFROMagentsWHEREsalary2000;CURSORc2RETURNagents%ROWTYPEISSELECT*FROMagentsWHEREsalary2000;CURSORc3(v_salary)ISSELECTaid,aname,salaryFROMagentsWHEREsalaryv_salary;,使用游标,打开OPENcur_name();可以使用位置表示法和名称表示法。不能打开已经打开的游标。打开游标时带入的参数已经在打开时被固定。读取数据FETCHINTO|;,使用游标,循环读LOOPFETCHc1INTOmy_record;EXITWHENc1%NOTFOUND;ENDLOOP;关闭CLOSE;,举例:计算方差,CREATEFUNCTION(P_LIDCHAR)ISBEGINDECLARECURSORC1(V_LIDCHAR)ISSELECTSALARYFROMSALESWHERECID=V_LIDV_AVGNUMBER;V_SUMNUMBERDEFAULT0;VINUMBER;BEGINSELECTAVG(SALVARY)INTOV_AVGFROMSALESWHERELID=P_LIDOPENC1(P_LID);LOOPFETCHC1INTOVI;EXITWHENC1%NOTFOUND;V_SUM:=V_SUM+(VI-V_AVG)*(VI-V_AVG);ENDLOOPCLOSEC1;RETURNV_SUM;END;END,游标FOR循环,自动声明一个和游标返回值相同类型的循环变量、自动打开游标,在每一次循环中读取一行数据,在出错或没有数据时结束循环,关闭游标。同时,当在循环中使用EXIT、GOTO语句或发生错误而跳出循环时,自动关闭游标。语法FORIN()LOOPENDLOOP;,举例:计算方差,CREATEFUNCTION(P_LIDCHAR)ISBEGINDECLARECURSORC1(V_LIDCHAR)ISSELECTSALARYFROMSALESWHERECID=V_LIDV_AVGNUMBER;V_SUMNUMBERDEFAULT0;VINUMBER;BEGINSELECTAVG(SALVARY)INTOV_AVGFROMSALESWHERELID=P_LIDIFV_AVGISNULLTHENRETURNNULLENDIFFORREC_1INC1(P_LID)LOOPV_SUM:=V_SUM+(VI-V_AVG)*(VI-V_AVG);ENDLOOPRETURNV_SUM;END;END,游标属性,对于显式游标,只有%ISOPEN可以在游标未打开时使用。否则产生错误。,修改游标中数据,在定义时使用FORUPDATE子句。FORUPDATEOFNOWAITFORUPDATE子句锁住查询出来的行,这样,其他用户在这个事务期间就不能修改内容了。这个子句提示用户想要修改查询出来的行,但并不一定执行这个操作。如果没有这个子句,只能在每次修改时加锁。在UPDATE和DELETE中使用WHERECURRENTOF子句。,作业,1、对于ORDERS表,统计每一个顾客的最高3笔销售额,并取平均,结果放入HIGH3表中。HIGH3(CID,DOLLARS3)。2、对于给定的CID,求总销售额。,内容概要,服务器端程序PL/SQL的基本结构控制流语句过程与函数游标错误与异常处理触发器,错误与异常处理,各种非正常的状态称为错误。异常是错误处理的一种机制。在PL/SQL中,一个警告或错误称之为异常(exception)。内部定义用户定义一些异常有预定义的名字,其他的可以给出名字。,错误与异常处理,处理错误的方式通常有两类,一类是C语言等的实现方式,包括:返回值发生错误的程序段不一定能够解决问题,它可以通过返回值或者全局标志将错误的状态传递给调用者,但调用者完全可能忽视错误。全局状态标志错误处理的代码混杂在正常的程序处理流程中,使得程序结构显得比较混乱。,错误与异常处理,另外一种方式,是在PL/1语言中提出的,并在PL/SQL中应用,而且在C+和Java语言中得到采用的“结构化异常处理”的方法。try/*正常流程*/catch()/*根据不同错误原因进行处理*/,错误与异常处理,优点发生错误的程序段只负责把错误抛出,而由有能力的高层调用者(包括最终用户)来解决问题。程序流程清晰。缺点需要对错误进行分类,有一个明确的分类体系。在C+语言中,内存释放是一个问题。可能被滥用。,异常的定义与使用,一些预定义异常,用户自定义错误,自定义的错误,不需要声明。Raise_application_error(,TRUE|FALSE);BETWEEN-20000,-20999CHAR(2048);-20000应用于一般性错误。如果第三个参数为假(缺省值),替换现有的错误。如果为真,加在现有错误之上。这种错误也可以被捕捉。,异常处理语法结构,EXCEPTION段WHENORTHENWHENOTHERSTHEN,异常处理过程,执行体内出现异常,转到本块的异常处理程序。在声明段和错误处理段发生异常时,转到上一层的异常处理程序。如果在这个位置没有找到异常处理程序,和处理程序中没有找到对应的错误号,且没有OTHERS段,则继续向上传播。如直到最外层都没有找到,则结束当前程序,返回用户。执行完异常处理程序后,控制权转移到异常处理程序的外层块的下一条语句执行。如异常处理在最外层,则结束程序。,异常处理过程,DECLAREpe_ratioNUMBER(3,1);BEGINDELETEFROMstatsWHEREsymbol=XYZ;BEGIN-子块开始SELECTprice/earningsINTOpe_ratioFROMstocksWHEREsymbol=XYZ;EXCEPTIONWHENZERO_DIVIDETHENpe_ratio:=0;END;-子块结束INSERTINTOstats(symbol,ratio)VALUES(XYZ,pe_ratio);EXCEPTIONWHENNO_DATA_FOUNDRaise_application_error(-20010,数据不存在);-不进行插入,报告错误END;,内容概要,服务器端程序PL/SQL的基本结构控制流过程与函数游标错误与异常处理触发器,触发器,触发器是一种特殊的存储过程。它不是由用户显式调用的,而适当满足某个触发事件时自动执行的。触发器包括:触发事件,触发器约束和触发器动作。触发事件:DML语句,DDL语句,数据库系统事件和用户事件。触发约束:在何种条件下触发。动作:一个PL/SQL程序。,触发器的基本概念,触发器,高级的存取限制(如在特定时间修改),根据需要限制用户的数据处理操作和创建对象操作。可以根据情况更改原本要操作的SQL语句:触发器可以修改原本要操作的SQL语句,例如原本的SQL语句是要删除数据表里的记录,但该数据表里的记录是重要记录,不允许删除的,那么触发器可以不执行该语句。检查所做的SQL是否允许:触发器可以检查SQL所做的操作是否被允许。例如:在产品库存表里,如果要删除一条产品记录,在删除记录时,触发器可以检查该产品库存数量是否为零,如果不为零则取消该删除操作。防止数据表构结更改或数据表被删除:为了保护已经建好的数据表,触发器可以在接收到Drop和Alter开头的SQL语句里,不进行对数据表的操作。复杂的数据一致性检查,比数据库声明的完整性约束还要复杂。,触发器的优点,自动产生关联的数据,修改其它数据表里的数据:当一个SQL语句对数据表进行操作的时候,触发器可以根据该SQL语句的操作情况来对另一个数据表进行操作。例如:一个订单取消的时候,那么触发器可以自动修改产品库存表,在订购量的字段上减去被取消订单的订购数量。返回自定义的错误信息:约束是不能返回信息的,而触发器可以。例如插入一条重复记录时,可以返回一个具体的友好的错误信息给前台应用程序。自动建立事件日志。调用更多的存储过程:约束的本身是不能调用存储过程的,但是触发器本身就是一种存储过程,而存储过程是可以嵌套使用的,所以触发器也可以调用一个或多过存储过程。,触发器,限制为全局性的操作定义触发器尽量使用完整性约束尽量不使用多重触发器、不要产生递归不要过长(60行),触发器的限制,触发器,CREATEORREPLACETRIGGERBEFOREDELETEAFTERINSERTORINSTEADOFUPDATEOFON|REFERENCINGOLDAS|NEWASFOREACHROWSTATEMENTWHEN();,创建和维护触发器,触发器,BEFORE和AFTER。BEFORE用于可能修改语句带来的数值的情况。条件谓词:INSERTING,DELETING,UPDATING,UPDATING()缺省为FOREACHSTATEMENT:new和:old。可以在BEFORE触发器中向:new记录中赋值,但不能在AFTER触发器中赋值。如果表名和new,old冲突,可以使用REFERENCE子句指定其他名称。,创建和维护触发器,触发器,创建和维护触发器,触发器,在触发器中出现异常时,所有工作被卷回。不能读取、修改正在变化的表。不能修改完整性约束引用的表的主键、外键和唯一值。ALTERTRIGGERENABLE|DISABLE|COMPILE;DROPTRIGGER;,创建和维护触发器,触发器,CREATEORREPLACETRIGGERaudit_empAFTERINSERTORUPDATEORDELETEONempFOREACHROWDECLAREtime_nowDATE;terminalCHAR(10);BEGINtime_now:=SYSDATE;-得到当前时间IFINSERTINGTHEN-记录新的主键INSERTINTOaudit_tableVALUES(audit_seq.NEXTVAL,user,time_now,EMP,INSERT,:new.empno);ELSIFDELETINGTHEN-记录删除行的主键INSERTINTOaudit_tableVALUES(audit_seq.NEXTVAL,user,time_now,EMP,DELETE,:old.empno);ELSE-记录更新行的主键INSERTINTOaudit_tableVALUES(audit_seq.NEXTVAL,user,time_now,EMP,UPDATE,:old.empno);,创建和维护触发器,触发器,IFUPDATING(SAL)THEN-记录sal的新旧值INSERTINTOaudit_table_valuesVALUES(audit_seq.CURRVAL,SAL,:old.sal,:new.sal);ELSIFUPDATING(DEPTNO)THEN-记录deptno的新旧值INSERTINTOaudit_table_valuesVALUES(audit_seq.CURRVAL,DEPTNO,:old.deptno,:new.deptno);ENDIF;ENDIF;END;,创建和维护触发器,触发器,对视图进行DML时触发,可以完成替代性的DML操作。不检查视图的CHECK约束。无需指定BEFORE或AFTER,对于修改,无需指定列。一定是FOREACHROW。,视图触发器,触发器,1、DML触发器:建立在基本表上的触发器,响应基本表的INSERT、UPDATE、DELETE操作。2、INSTEADOF触发器:建立在视图上的触发器,响应视图上的INSERT、UPDATE、DELETE操作。3、系统触发器:建立在系统或者模式上的触发器,响应系统事件和DDL(CREATE、ALTER、DROP)操作。,触发器的种类,触发器,触发器由触发器头部和触发器体组成,主要包括以下参数:作用对象:触发器作用的对象,包括表、视图、数据库和模式。触发事件:激发触发器执行的事件。如DML、DDL、数据库系统事件等。触发时间:指定触发器在触发事件完成之前还是之后执行。触发级别:指定触发器响应触发事件的方式。默认为语句级,即触发事件发生后,触发器只执行一次。如果指定为FOREACHROW,即为行触发器,则触发事件每作用于一个记录,触发器执行一次。触发条件:由when子句指定一个逻辑表达式,当触发事件发生且when条件为TRUE,触发器才执行。触发操作:触发器执行时的操作。,触发器的组成,触发器,DML触发器:建立在基本表上的触发器,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论