




下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Oracle 存储过程总结1、创建存储过程createorreplaceproceduretest(var_name_1intype,var_name_2outtype)as-声明变量(变量名变量类型)begin-存储过程的执行体endtest;打印出输入的时间信息E.g:createorreplaceproceduretest(workDateinDate)isbegindbms_output.putline(Theinputdateis:|to_date(workDate,yyyy-mm-dd);endtest;2、变量赋值变量名:=值;E.g:createorreplaceprocedu
2、retest(workDateinDate)isxnumber(4,2);beginx:=1;endtest;3、判断语句:if 比较式 thenbeginend;endif;E.gcreateorreplaceproceduretest(xinnumber)isbeginifx0thenbeginx:=0-x;end;endif;ifx=0thenbeginx:=1;end;endif;endtest;4、For 循环For.in.LOOP-执行语句endLOOP;(1)循环遍历游标createorreplaceproceduretest()asCursorcursorisselectnam
3、efromstudent;namevarchar(20);beginfornameincursorLOOPbegindbms_output.putline(name);end;endLOOP;endtest;(2)循环遍历数组createorreplaceproceduretest(varArrayinmyPackage.TestArray)as-(输入参数 varArray 是自定义的数组类型,定义方式见标题 6)1number;begini:=1;-存储过程数组是起始位置是从 1 开始的,与 java、GC+埸语言不同。因为在 Oracle 中本是没有数组的概念的,数组其实就是一张-表(T
4、able),每个数组元素就是表中的一个记录,所以遍历数组时就相当于从表中的第一条记录开始遍历foriin1.varArray.countLOOPdbms_output.putline(TheNo.|i|recordinvarArrayis:|varArray(i);endLOOP;endtest;5、While 循环while 条件语句 LOOPbeginend;endLOOP;E.gcreateorreplaceproceduretest(iinnumber)asbeginwhilei10LOOPbegini:=i+1;end;endLOOP;endtest;6、数组首先明确一个概念:Ora
5、cle 中本是没有数组的概念的,数组其实就是一张表(Table),每个数组元素就是表中的一个记录。使用数组时,用户可以使用 Oracle 已经定义好的数组类型,或可根据自己的需要定义数组类型。使用 Oracle 自带的数组类型xarray;-使用时需要需要进行初始化e.g:createorreplaceproceduretest(youtarray)isxarray;beginx:=newarray();y:=x;endtest;(2)自定义的数组类型(自定义数据类型时,建议通过创建 Package 的方式实现,以便于管理)E.g(自定义使用参见标题 4.2)createorreplacepa
6、ckagemyPackageis-Publictypedeclarationstypeinfoisrecord(namevarchar(20),ynumber);typeTestArrayistableofinfoindexbybinary_integer;-止匕处声明了一个 TestArray 的类型数据,其实其为一张存储 Info 数据类型的 Table 而已,及TestArray 就是一张表,有两个字段,一个是name 一个是 y。 需要注意的是此处使用了 Indexbybinary_integer 编制该 Table 的索引项,也可以不写,直接写成:typeTestArrayistab
7、leofinfo,如果不写的话使用数组时就需要进行初始化:varArraymyPackage.TestArray;varArray:=newmyPackage.TestArray();endTestArray;7.游标的使用 Oracle 中 Cursor 是非常有用的,用于遍历临时表中的查询结果。其相关方法和属性也很多,现仅就常用的用法做一二介绍:(1)Cursor 型游标(不能用于参数传递)createorreplaceproceduretest()iscusor_1Cursorisselectstd_namefromstudentwhere.;-Cursor的使用方式 1cursor_2
8、Cursor;beginselectclass_nameintocursor_2fromclasswhere.;-Cursor 的使用方式 2可使用 ForxincursorLOOP.endLOOP;来实现对 Cursor 的遍历endtest;(2)SYS_REFCURSOR 游标,该游标是 Oracle 以预先定义的游标,可作出参数进行传递createorreplaceproceduretest(rsCursoroutSYS_REFCURSOR)iscursorSYS_REFCURSOR;namevarhcar(20);beginOPENcursorFORselectnamefromstu
9、dentwhere.-SYS_REFCURSOR 只能通过OPENt 法来打开和赋值LOOPfetchcursorintoname-SYS_REFCURSOR 只能通过 fetchinto 来打开和遍历exitwhencursor%NOTFOUND;-SYS_REFCURSOR 中可使用三个状态属性:-%NOTFOUND(未找到记录信息)%FOUN 坐到记录信息)-%ROWCOUNT(然后当前游标所指向的行位置)dbms_output.putline(name);endLOOP;rsCursor:=cursor;endtest;下面写一个简单的例子来对以上所说的存储过程的用法做一个应用:现假设
10、存在两张表,一张是学生成绩表(studnet),字段为:stdId,math,article,language,music,sport,total,average,step 一张是学生课外成绩表(out_school),字段为:stdId,parctice,comment通过存储过程自动计算出每位学生的总成绩和平均成绩,同时,如果学生在课外课程中获得的评价为 A,就在总成绩上加 20 分。createorreplaceprocedureautocomputer(stepinnumber)isrsCursorSYS_REFCURSOR;commentArraymyPackage.myArray;
11、mathnumber;articlenumber;languagenumber;musicnumber;sportnumber;totalnumber;averagenumber;stdIdvarchar(30);recordmyPackage.stdInfo;inumber;begini:=1;get_comment(commentArray);-调用名为 get_comment()的存储过程获取学生课外评分信息OPENrsCursorforselectstdId,math,article,language,music,sportfromstudenttwheret.step=step;LO
12、OPfetchrsCursorintostdId,math,article,language,music,sport;exitwhenrsCursor%NOTFOUND;total:=math+article+language+music+sport;mentArray.countLOOPrecord:=commentArray(i);ifstdId=record.stdIment='A'thenbegintotal:=total+20;gotonext;-使用 goto 跳出 for 循环end;endif;end;endif;endLOOP;averag
13、e:=total/5;updatestudenttsett.total=totalandt.average=averagewheret.stdId=stdId;endLOOP;end;endautocomputer;-取得学生评论信息的存储过程createorreplaceprocedureget_comment(commentArrayoutmyPackage.myArray)isrsSYS_REFCURSORrecordmyPackage.stdInfo;stdIdvarchar(30);commentvarchar(1);inumber;beginopenrsforselectstdId
14、,commentfromout_schooli:=1;LOOPfetchrsintostdId,comment;exitwhenrs%NOTFOUND;record.stdId:=stdId;ment:=comment;recommentArray(i):=record;i:=i+1;endLOOP;endget_comment;-定义数组类型 myArraycreateorreplacepackagemyPackageisbegintypestdInfoisrecord(stdIdvarchar(30),commentvarchar(1);typemyArrayistableofstdInf
15、oindexbybinary_integer;endmyPackage;项目中有涉及存储过程对字符串的处理,所以就将在网上查找到的资料汇总,做一个信息拼接式的总结。以下信息均来自互联网,贴出来一则自己保存以待以后使用,一则供大家分享。字符函数一一返回字符值这些函数全都接收的是字符族类型的参数(CHR除外)并且返回字符值.除了特别说明的之外,这些函数大部分返回VARCHAR2型的数值.字符函数的返回类型所受的限制和基本数据库类型所受的限制是相同的。字符型变量存储的最大值:VARCHAR数值被PM制为2000字符(ORACLE8中为4000字符)CHAR数值被PM制为255字符(在ORACLE即是
16、2000)long类型为2GBClob类型为4GB1、CHR语法:chr(x)功能:返回在数据库字符集中与X拥有等价数值的字符。CH济口ASCII是一对反函数。经过CHR专换后的字符再经过ASCII转换又得到了原来的字符。使用位置:过程性语句和SQL语句。2、CONCAT语法:CONCAT(string1,string2)功能:返回stringl,并且在后面连接string2。使用位置:过程性语句和SQL语句。3、INITCAP语法:INITCAP(string)功能:返回字符串的每个单词的第一个字母大写而单词中的其他字母小写的string。单词是用.空格或给字母数字字符进行分隔。不是字母的字
17、符不变动。使用位置:过程性语句和SQL语句。4、LTRIM语法:LTRIMI(string1,string2)功能:返回删除从左边算起出现在string2中的字符的string1。String2被缺省设置为单个的空格。数据库将扫描string1,从最左边开始。当遇到不在string2中的第一个字符,结果就被返回了。LTRIM的行为方式与RTRIMB相似。使用位置:过程性语句和SQL语句。5、NLS_INITCAP语法:NLS_INITCAP(string,nlsparams)功能:返回字符串每个单词第一个字母大写而单词中的其他字母小写的string,nlsparams指定了不同于该会话缺省值的
18、不同排序序列。如果不指定参数,则功能和INITCAP相同。Nlsparams可以使用的形式是:NLS_SORT=sort这里sort制订了一个语言排序序列。使用位置:过程性语句和SQL语句。6、NLS_LOWER语法:NLS_LOWERstring,nlsparams)功能:返回字符串中的所有字母都是小写形式的string。不是字母的字符不变。Nlsparams参数的形式与用途和NLS_INITCAP中的nlsparams参数是相同的。如果nlsparams没有被包含,那么NLS_LOWER作的处理和LOWERI同。使用位置;过程性语句和SQL语句。7、NLS_UPPER语法:nls_uppe
19、r(string,nlsparams)功能:返回字符串中的所有字母都是大写的形式的string。不是字母的字符不变。nlsparams参数的形式与用途和NLS_INITCAP中的相同。如果没有设定参数,贝UNLS_UPPE功能和UPPE充目同。使用位置:过程性语句和SQL语句。8、REPLACE语法:REPLACEstring,search_str,replace_str)功能:把string中的所有的子字符串search_str用可选的replace_str替换,如果没有指定replace_str,所有的string中的子字符串search_str都将被删除。REPLAC思TRANSLAT所
20、提供的功能的一个子集。使用位置:过程性语句和SQL语句。9、RPAD语法:RPAD(string1,x,string2)功能:返回在X字符长度的位置上插入一个string2中的字符的string1。如果string2的长度要比X字符少,就按照需要进行复制。如果string2多于X字符,则仅string1前面的X各字符被使用。如果没有指定string2,那么使用空格进行填充。X是使用显示长度可以比字符串的实际长度要长。RPAD勺行为方式与LPADf艮相似,除了它是在右边而不是在左边进行填充。使用位置:过程性语句和SQL语句。10、RTRIM语法:RTRIM(string1,string2)功能:
21、返回删除从右边算起出现在string1中出现的字符string2.string2被缺省设置为单个的空格.数据库将扫描string1,从右边开始.当遇到不在string2中的第一个字符,结果就被返回了RTRIM的行为方式与LTRIM很相似.使用位置:过程性语句和SQL语句。11、SOUNDEX语法:SOUNDEX(string)功能:返回string的声音表示形式.这对于比较两个拼写不同但是发音类似的单词而言很有帮助.使用位置:过程性语句和SQL语句。12、SUBSTR语法:SUBSTR(string,a,b)功能:返回从字母为值a开始b个字符长的string的一个子字符串.如果a是0,那么它就
22、被认为从第一个字符开始.如果是正数,返回字符是从左边向右边进行计算的.如果b是负数,那么返回的字符是从string的末尾开始从右向左进行计算的.如果b不存在,那么它将缺省的设置为整个字符串.如果b小于1,那么将返回NULL.如果a或b使用了浮点数,那么该数值将在处理进行以前首先被却为一个整数.使用位置:过程性语句和SQL语句。13、TRANSLATE语法:TRANSLATE(string,from_str,to_str)功能:返回将所出现的from_str中的每个字符替换为to_str中的相应字符以后的string.TRANSLATE是REPLAC所提供的功能的一个超集.如果from_str比
23、to_str长,那么在from_str中而不在to_str中而外的字符将从string中被删除,因为它们没有相应的替换字符.to_str不能为空.Oracle把空字符串认为是NULL,并且如果TRANSLATE的任何参数为NULL,那么结果也是NULL.使用位置:过程性语句和SQL语句。14、UPPER语法:UPPER(string)功能:返回大写的string.不是字母的字符不变.如果string是CHA嘤据类型的,那么结果也是CHA戏型的.如果string是VARCHAR2型的,那么结果也是VARCHAR2型的.使用位置:过程性语句和SQL语句。字符函数一一返回数字这些函数接受字符参数回数
24、字结果.参数可以是CHA臧者是VARCHAR2型的.尽管实际下许多结果都是整数值,但是返回结果都是简单的NUMBER类型的,没有定义任何的精度或刻度范围.16、ASCII语法:ASCII(string)功能:数据库字符集返回string的第一个字节的十进制表示.请注意该函数仍然称作为ASCII.尽管许多字符集不是7位ASCII.CHR和ASCII是互为相反的函数.CHR得到给定字符编码的响应字符.ASCII得到给定字符的字符编码.使用位置:过程性语句和SQL语句。17、INSTR语法:INSTR(stringl,string2a,b)功能:得到在string1中包含string2的位置.str
25、ing1时从左边开始检查的,开始的位置为a,如果a是一个负数,那么string1是从右边开始进行扫描的.第b次出现的位置将被返回.a和b都缺省设置为1,这将会返回在string1中第一次出现string2的位置.如果string2在a和b的规定下没有找到,那么返回0.位置的计算是相对于string1的开始位置的,不管a和b的取值是多少.使用位置:过程性语句和SQL语句。18、INSTRB语法:INSTRB(string1,string2a,b)功能:和INSTR相同,只是操作的对参数字符使用的位置的是字节使用位置:过程性语句和SQL语句。19、LENGTH语法:LENGTH(string)功能
26、:返回string的字节单位的长度.CHAR数值是填充空格类型的,如果string由数据类型CHAR它的结尾的空格都被计算到字符串长度中间如果string是NULL,返回结果是NULL,而不是0.使用位置:过程性语句和SQL语句。20、LENGTHB语法:LENGTHB(string)功能:返回以字节为单位的string的长度.对于单字节字符集LENGTHB口LENGTH1一样的.使用位置:过程性语句和SQL语句。21、NLSSORT语法:NLSSORT(string,nlsparams)功能:得到用于排序string的字符串字节.所有的数值都被转换为字节字符串,这样在不同数据库之间就保持了一
27、致性.Nlsparams的作用和NLS_INITCAP中的相同.如果忽略参数,会话使用缺省排序.使用位置:过程性语句和SQL语句。oracle 存储过程的基本语法1.基本结构CREATEORREPLACEPROCEDURE 存储过程名字(参数 1INNUMBER,参数 2INNUMBER)IS变量 1INTEGER:=0;变量 2DATE;BEGINEND 存储过程名字2.SELECTINTOSTATEMENT将 select 查询的结果存入到变量中,可以同时将多个列存储多个变量中,必须有一条记录,否则抛出异常(如果没有记录抛出 NO_DATA_FOUND)例子:BEGINSELECTcol1
28、,col2into 变量 1,变量 2FROMtypestructwherexxx;EXCEPTIONWHENNO_DATA_FOUNDTHENxxxx;END;.1.1 F 判断IFV_TEST=1THENBEGINdosomethingEND;ENDIF;1、.while 循环WHILEV_TEST=1LOOPBEGINXXXXEND;ENDLOOP;2、.变量赋值V_TEST:=123;3、.用 forin 使用 cursorISCURSORcurISSELECT*FROMxxx;BEGINFORcur_resultincurLOOPBEGINV_SUM:=cur_result.歹 U
29、名 1+cur_result.歹 U 名 2END;ENDLOOP;END;4、.带参数的 cursorCURSORC_USER(C_IDNUMBER)ISSELECTNAMEFROMUSERWHERETYPEID=C_ID;OPENC_USER(变量值);LOOPFETCHC_USERINTOV_NAME;EXITFETCHC_USER%NOTFOUND;dosomethingENDLOOP;CLOSEC_USER;5、.用 pl/sqldeveloperdebug连接数据库后建立一个 TestWINDOW在窗口输入调用 SP 的代码,F9 开始 debug,CTRL+N 单步调试关于 or
30、acle 存储过程的若干问题备忘.在 oracle 中,数据表别名不能加 as,如:selecta.appnamefromappinfoa;-正确selecta.appnamefromappinfoasa;-错误也许,是怕和 oracle 中的存储过程中的关键字 as 冲突的问题吧.在存储过程中,select 某一字段时,后面必须紧跟 into,如果 select 整个记录,利用游标的话就另当别论了。selectaf.keynodeintoknfromAPPFOUNDATIONafwhereaf.appid=aidandaf.foundationid=fid;-有 into,正确编译一 sel
31、ectaf.keynodefromAPPFOUNDATIONafwhereaf.appid=aidandaf.foundationid=fid;-没有 into,编译报错,提示:Compilation一Error:PLS-00428:anINTOclauseisexpectedinthisSELECTstatement.在利用 o.语法时,必须先确保数据库中有该条记录,否则会报出nodatafound异常。可以在该语法之前,先利用 selectcount(*)from 查看数据库中是否存在该记录,如果存在,再利用 o.在存储过程中,别名不能和字段名称相同
32、,否则虽然编译可以通过,但在运行阶段会报错selectkeynodeintoknfromAPPFOUNDATIONwhereappid=aidandfoundationid=fid;-正确运行selectaf.keynodeintoknfromAPPFOUNDATIONafwhereaf.appid=appidandaf.foundationid=foundationid;-运行阶段报错,提示ORA-01422:exactfetchreturnsmorethanrequestednumberofrows.在存储过程中,关于出现 null 的问题假设有一个表 A,定义如下:createtable
33、A(idvarchar2(50)primarykeynotnull,_vcountnumber(8)notnull,bidvarchar2(50)notnull 一外键);如果在存储过程中,使用如下语句:selectsum(vcount)intofcountfromAwherebid=xxxxxx;如果 A 表中不存在 bid=xxxxxx的记录,则 fcount=null(即使 fcount 定义时设置了默认值,如:fcountnumber(8):=0 依然无效,fcount 还是会变成 null),这样以后使用 fcount 时就可能有问题,所以在这里最好先判断一下:iffcountisn
34、ullthenfcount:=0;endif;这样就一切 ok 了。.Hibernate 调用 oracle 存储过程this.pnumberManager.getHibernateTemplate().execute(newHibernateCallback()publicObjectdoInHibernate(Sessionsession)throwsHibernateException,SQLExceptionCallableStatementcs=session.connection。.prepareCall(callmodifyapppnumber_remain(?);cs.setS
35、tring(1,foundationid);cs.execute();returnnull;);oracle 存储过程语法总结及练习-1.存储过程之ifclear;createorreplaceproceduremydel(in_aininteger)asbeginifin_a100thendbms_output.put_line(elsifin_a301;endloop;end;/setserveroutputon;beginmydel(2);end;/-1.存储过程之100P2clear;createorreplaceproceduremydel(in_aininteger)asainte
36、ger;begina:=0;whilea300loopdbms_output.put_line(a);a:=a+1;endloop;end;/setserveroutputon;beginmydel(2);end;-1.存储过程之100P3clear;createorreplaceproceduremydel(in_aininteger)asainteger;beginforain0.300loopdbms_output.put_line(a);endloop;end;/setserveroutputon;beginmydel(2);end;/clear;selectename,cc:=(ca
37、sewhencomm=nullthensal*12;else(sal+comm)*12;endcasefromemporderbysalpersal;clear;createorreplaceproceduregetstudentcomments(i_studentidinint,o_commentsoutvarchar)asexams_satint;avg_markint;tmp_commentsvarchar(100);beginselectcount(examid)intoexams_satfromstudentexamwherestudentid=i_studentid;ifexams
38、_sat=0thentmp_comments:=n/a-thisstudentdidnotattendtheexam!;elseselectavg(mark)intoavg_markfromstudentexamwherestudentid=i_studentid;casewhenavg_mark50thentmp_comments:=verybad;whenavg_mark60thentmp_comments:=bad;whenavg_mark70thentmp_comments:=good;endcase;endif;o_comments:=tmp_comments;end;/setser
39、veroutputon;ments%type;begingetstudentcomments(8,pp);dbms_output.put_line(pp);end;/deletefromempwhereempno6000;clear;createorreplaceprocedureinsertdata(in_numininteger)asmyNumintdefault0;emp_noemp.empno%type:=1000;beginwhilemyNumin_numloopinsertintoempvalues(emp_no,hui|myNum,coder,7555,current_date,
40、8000,6258,30);emp_no:=emp_no+1;myNum:=myNum+1;endloop;end;/setserveroutputon;begininsertdata(10);end;/select*fromemp;clear;selectstudentname,averageMark,casewhenaverageMark60then不及格whenaverageMark70then考得好whenaverageMark(selectsalfromempwhereename=SMITH);3selecta.ename,(selectenamefromempbwhereb.emp
41、no=a.mgr)asbossnamefromempa;4selecta.enamefromempawherea.hiredate1500;8selectenamefromempwheredeptno=(selectdeptnofromdeptwheredname=SALES);9selectenamefromempwheresal(selectavg(sal)fromemp);10selectenamefromempwherejob=(selectjobfromempwhereename=SCOTT);11selecta.ename,a.salfromempawherea.salin(sel
42、ectb.salfromempbwhereb.deptno=30)anda.deptno30;12selectename,salfromempwheresal(selectmax(sal)fromempwheredeptno=30);13select(selectb.dnamefromdeptbwherea.deptno=b.deptno)asdeptname,count(deptno)asdeptcount,avg(sal)asdeptavgsalfromempagroupbydeptno;14selecta.ename,(selectb.dnamefromdeptbwhereb.deptn
43、o=a.deptno)asdeptname,salfromempa;15selecta.deptno,a.dname,a.loc,(selectcount(deptno)fromempbwhereb.deptno=a.deptnogroupbyb.deptno)asdeptcountfromdepta;16selectjob,avg(sal)fromempgroupbyjob;17selectdeptno,min(sal)fromempwherejob=MANAGERgroupbydeptno;18selectename,(sal+nvl(comm,0)*12assalpersalfromem
44、porderbysalpersal;ORACLE 旬查询,分组等A.同表子查询作为条件a.给出人口多于Russia(俄国)的国家名称SELECTnameFROMbbcWHEREpopulation(SELECTpopulationFROMbbcWHEREname=Russia)b.给出India(印度),Iran(伊朗)所在地区的所有国家的所有信息SELECT*FROMbbcWHEREregionIN(SELECTregionFROMbbcWHEREnameIN(India,Iran)c.给出人均GD刚过UnitedKingdom(英国)的欧洲国家.SELECTnameFROMbbcWHERE
45、region=EuropeANDgdp/population(SELECTgdp/populationFROMbbcWHEREname=UnitedKingdom)d.这个查询实际上等同于以下这个:selecte1.enamefromempe1,(selectempnofromempwhereename=KING)e2wheree1.mgr=e2.empno;你可以用EXISTS写同样的查询,你只要把外部查询一栏移到一个像下面这样的子查询环境中就可以了:selectenamefromempewhereexists(select0fromempwheree.mgr=empnoandename=K
46、ING);当你在一个WHERETO中写EXISTS时,又等于向最优化传达了这样一条信息,即你想让外部查询先运行,使用每一个值来从内部查询(假定:EXISTS=由外而内)中得到一个值。B.异表子查询作为条件a.select*fromstudentExamwherestudentid=(selectstudentidfromstudentwherename=吴丽丽);b.select*fromstudentexamwherestudentidin(selectstudentidfromstudent)orderbystudentid;c.select*fromstudentwherestudent
47、idin(selectstudentidfromstudentexamwheremark80);3.selectstudentexam.mark,studentexam.studentidasseid,student.studentid,fromstudentexam,studentwherestudent.studentid=studentexam.studentid;过滤分组:顺序为先分组,再过滤,最后进行统计(实际值).selectstudentid,count(*)ashighpassesfromstudentexamwheremark70groupbystud
48、entid;假使我们不想通过数据表中的实际值,而是通过聚合函数的结果来过过滤查询的结果.selectstudentid,avg(mark)asaveragemarkfromstudentexamwhereavg(mark)70groupbystudentid;(此句错误,where句子是不能用聚合函数作条件的)此时要用having.selectstudentid,avg(mark)fromstudentexamgroupbystudentidhavingavg(mark)70oravg(mark)70;(先分组,再过滤,再having聚合,最后再统计).selectstudentid,avg(
49、mark)asaveragemarkfromstudentexamwhereexamidin(5,8,11)groupbystudentidhavingavg(mark)70;返回限定行数查询:selectnamefromstudentwhererownum=10;oracle中使用rownum关键字指定,但该关键字必须在where子句中与一个比较运算符一起指定,而不能与orderby一起配合便用,因为rownum维护的是原始行号.如果需要用groupbyorderby就用子句查询作表使用的方法:selectstudentid,averagemarkfrom(selectstudentid,a
50、vg(mark)asaveragemarkfromstudentexamgroupbystudentidorderbyaveragemarkdesc)whererownum=10;oracle 存储过程语法:Oracle 存储过程入门学习基本语法.基本结构createORREPLACEPROCEDURE 存储过程名字(参数 1INNUMBER,参数 2INNUMBER)IS变量 1INTEGER:=0;变量 2DATE;BEGINEND 存储过程名字.selectINTOSTATEMENT将 select 查询的结果存入到变量中,可以同时将多个列存储多个变量中,必须有一条记录,否则抛出异常(如
51、果没有记录抛出 NO_DATA_FOUND)例子:BEGINselectcol1,col2into 变量 1,变量 2FROMtypestructwherexxx;EXCEPTIONWHENNO_DATA_FOUNDTHENxxxx;END;.3.IF 判断 IFV_TEST=1THENBEGINdosomethingEND;ENDIF;.while 循环WHILEV_TEST=1LOOPBEGINXXXXEND;ENDLOOP;.变量赋值V_TEST:=123;.用 forin 使用 cursor.ISCURSORcurISselect*FROMxxx;BEGINFORcur_resulti
52、ncurLOOPBEGINV_SUM:=cur_result.列名 1+cur_result.列名 2END;ENDLOOP;END;.带参数的 cursorCURSORC_USER(C_IDNUMBER)ISselectNAMEFROMUSERwhereTYPEID=C_ID;OPENC_USER(变量值);LOOPFETCHC_USERINTOV_NAME;EXITFETCHC_USER%NOTFOUND;dosomethingENDLOOP;CLOSEC_USER;.用 pl/sqldeveloperdebug连接数据库后建立一个 TestWINDOW在窗口输入调用 SP 的代码,F9
53、开始 debug,CTRL+N 单步调试oracle 语法:Oracle 触发器语法及实例基础知识(一)一 Oracle 触发器语法触发器是特定事件出现的时候,自动执行的代码块类似于存储过程,触发器和存储过程的区别在于:存储过程是由用户或应用程序显式调用的,而触发器是不能被直接调用的功能:1、允许/限制对表的修改2、自动生成派生列,比如自增字段3、强制数据一致性4、提供审计和日志记录5、防止无效的事务处理6、启用复杂的业务逻辑触发器触发时间有两种:after 和 before1、触发器的语法:CREATEORREPLACETIGGER 触发器名触发时间触发事件ON 表名FOREACHROWBE
54、GINpl/sql 语句END其中:触发器名:触发器对象的名称由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途触发时间:指明触发器何时执行,该值可取:before-表示在数据库动作的前触发器执行;after-表示在数据库动作的后出发器执行触发事件:指明哪些数据库动作会触发此触发器:insert:数据库插入会触发此触发器;update:数据库修改会触发此触发器delete:数据库删除会触发此触发器表名:数据库触发器所在的表foreachrow:对表的每一行触发器执行一次如果没有这一选项,则只对整个表执行一次2、举例:下面的触发器在更新表 auths 的前触发,目的是不允许在周
55、末修改表:createtriggerauth_securebeforeinsertorupdateordelete/对整表更新前触发onauthsbeginif(to_char(sysdate,DY)=SUNRAISE_APPLICATION_ERROR(-20600,不能在周末修改表 auths);endif;end例子:CREATEORREPLACETRIGGERCRM.T_SUB_USERINFO_AUR_NAMEAFTERUPDATEOFSTAFF_NAMEONCRM.T_SUB_USERINFOREFERENCINGOLDASOLDNEWASNEWFOREACHROWdeclareb
56、eginif:NEW.STAFF_NAME!=:OLD.STAFF_NAMEthenbegin客户投诉updateT_COMPLAINT_MANAGEsetSERVE_NAME=:NEW.STAFF_NAMEwhereSERVE_SEED=:OLD.SEED;客户关怀updateT_CUSTOMER_CAREsetEXECUTOR_NAME=:NEW.STAFF_NAMEwhereEXECUTOR_SEED=:OLD.SEED;客户服务updateT_CUSTOMER_SERVICEsetEXECUTOR_NAME=:NEW.STAFF_NAMEwhereEXECUTOR_SEED=:OLD.
57、SEED;end;endif;endT_sub_userinfo_aur_name;/2Oracle 触发器详解开始:createtriggerbiufer_employees_department_idbeforeinsertorupdateofdepartment_idonemployeesreferencingoldasold_valuenewasnew_valueforeachrowwhen(new_value.department_id80)begin:new_mission_pct:=0;end;/1、触发器的组成部分:1、触发器名称2、触发语句3、触发器限制4、触发操作触发器名称
58、createtriggerbiufer_employees_department_id命名习惯:employees 表名department_id 歹 U 名触发语句比如:表或视图上的 DML 语句DDL 语句数据库关闭或启动,startupshutdown 等等beforeinsertorupdateofdepartment_idonemployeesreferencingoldasold_valuenewasnew_valueforeachrow介绍说明:是否规定了 department_id,对 employees 表进行 insert 的时候employees 表的 departmen
59、t_id 列进行 update 的时候触发器限制when(new_value.department_id80)限制不是必须的此例表示如果列 department_id 不等于 80 的时候,触发器就会执行其中的 new_value 是代表更新的后的值触发操作是触发器的主体begin:new_mission_pct:=0;end;主体很简单,就是将更新后的 commission_pct 列置为 0触发:insertintoemployees(employee_id,last_name,first_name,hire_date,job_id,email,department_id,salary,c
60、ommission_pct)values(12345,Cherf,Donny,sysdate,12,60,10000,.25);selectcommission_pctfromemployeeswhereemployee_id=12345;2、触发器的类型有:触发器类型:触发器发器STEADOF 触发件触发器件触发器2.1、语句级触发器.(语句级触发器对每个 DML 语句执彳 f 一次)是在表上或者某些情况下的视图上执行的特定语句或者语句组上的触发器能够和 INSERT、UPDATE、DELETE 或者组合上进行关联但是无论使用什么样的组合,各个语句触发器都只会针对指定语句激活一次比如,无论 update
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 生产安全管理规定制定
- 真皮微环境中的表皮-基质间信号通路-洞察及研究
- 2025年氢能基础设施项目可行性研究报告
- 环保设备制造业2025年市场发展趋势与产品创新方向研究报告
- 林木出口贸易趋势-洞察及研究
- 互联网广告精准投放算法在电商平台的用户留存率提升效果评估与优化研究
- 工程索赔管理合同条款范本
- 非正式领导与团队合作
- 消防安全考核规定
- 规范网络信息安全防护规定
- 2025年人保车险考试题及答案
- 中外航海文化知到课后答案智慧树章节测试答案2025年春中国人民解放军海军大连舰艇学院
- 《茉莉花》音乐课件
- 2025年云南省职教高考电工技术类《电工基础理论知识》考试复习题库(含答案)
- 工厂交叉作业安全管理协议书(2篇)
- 外墙真石漆工程安全文明施工保证措施及环境保护体系和保证措施
- 品管圈PDCA改善案例-产科联合多部门降低阴道分娩产后出血发生率
- 矿井火灾防治理论与技术课件
- 【MOOC】生命的教育-浙江大学 中国大学慕课MOOC答案
- 中国非遗文化鱼灯介绍介绍2
- NB/T 11127-2023在用钢丝绳芯输送带报废检测技术规范
评论
0/150
提交评论