资源描述:
《plsql基础教程-必看-2012》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
60PL/SQL程序设计-60- 60目录第一章PL/SQL程序设计简介4§1.2SQL与PL/SQL4§1.2.1什么是PL/SQL?4§1.2.1PL/SQL的好处4§1.2.2PL/SQL可用的SQL语句5§1.3运行PL/SQL程序5第二章PL/SQL块结构和组成元素6§2.1PL/SQL块6§2.2PL/SQL结构6§2.3标识符6§2.4PL/SQL变量类型7§2.4.1变量类型7§2.4.2复合类型9§2.4.3使用%ROWTYPE11§2.4.4LOB类型*11§2.4.5Bind变量11§2.4.6INDEXBYTABLES12§2.4.7数据类型的转换*13§2.5运算符和表达式(数据定义)13§2.5.1关系运算符13§2.5.2一般运算符13§2.5.3逻辑运算符13§2.6变量赋值13§2.6.1字符及数字运算特点13§2.6.2BOOLEAN赋值13§2.6.3数据库赋值13§2.6.4可转换的类型赋值13§2.7变量作用范围及可见性13§2.8注释13§2.9简单例子13§2.9.1简单数据插入例子13§2.9.2简单数据删除例子13第三章PL/SQL流程控制语句13§3.1条件语句13§3.2CASE表达式13§3.3循环13§3.3标号和GOTO13§3.4NULL语句13第四章游标的使用13-60- 60§4.1游标概念13§4.1.1处理显式游标13§4.1.2处理隐式游标13§4.1.3游标修改和删除操作13第五章异常错误处理13§5.1异常处理概念13§5.1.1预定义的异常处理13§5.1.2非预定义的异常处理13§5.1.3用户自定义的异常处理13§5.1.4用户定义的异常处理13§5.2异常错误传播13§5.2.1在执行部分引发异常错误13§5.2.2在声明部分引发异常错误13§5.3异常错误处理编程13§5.4在PL/SQL中使用SQLCODE,SQLERRM13第六章存储函数和过程13§6.1引言13§6.2创建函数13§6.3存储过程13§6.3.1创建过程13§6.3.2调用存储过程13§6.3.3开发存储过程步骤13§6.3.4与过程相关数据字典13第七章包的创建和应用13§7.1引言13§7.2包的定义13§7.3包的开发步骤13§7.4包定义的说明13§7.5子程序重载13§7.6删除过程、函数和包13§7.7包的管理13第八章触发器13§8.1触发器类型13§8.1.1DML触发器13§8.1.2替代触发器13§8.1.3系统触发器13§8.2创建触发器13§8.2.1触发器触发次序13§8.2.2创建DML触发器13§8.2.3创建替代(Instead_of)触发器13§8.2.3创建系统事件触发器13-60- 60§8.2.4系统触发器事件属性13§8.2.5使用触发器谓词13§8.2.6重新编译触发器13§8.3删除和使能触发器13§8.4触发器和数据字典13§8.5数据库触发器的应用举例13-60- 60PL/SQL程序设计简介PL/SQL是一种高级数据库程序设计语言,该语言专门用于在各种环境下对ORACLE数据库进行访问。由于该语言集成于数据库服务器中,所以PL/SQL代码可以对数据进行快速高效的处理。除此之外,可以在ORACLE数据库的某些客户端工具中,使用PL/SQL语言也是该语言的一个特点。本章的主要内容是讨论引入PL/SQL语言的必要性和该语言的主要特点,以及了解PL/SQL语言的重要性和数据库版本问题。还要介绍一些贯穿全书的更详细的高级概念,并在本章的最后就我们在本书案例中使用的数据库表的若干约定做一说明。本章主要重点:lPL/SQL概述lPL/SQL块结构lPL/SQL流程l运算符和表达式l游标l异常处理l数据库存储过程和函数l包l触发器§1.2SQL与PL/SQL§1.2.1什么是PL/SQL?PL/SQL是ProcedureLanguage&StructuredQueryLanguage的缩写。ORACLE的SQL是支持ANSI(AmericannationalStandardsInstitute)和ISO92(InternationalStandardsOrganization)标准的产品。PL/SQL是对SQL语言存储过程语言的扩展。从ORACLE6以后,ORACLE的RDBMS附带了PL/SQL。它现在已经成为一种过程处理语言,简称PL/SQL。目前的PL/SQL包括两部分,一部分是数据库引擎部分;另一部分是可嵌入到许多产品(如C语言,JAVA语言等)工具中的独立引擎。可以将这两部分称为:数据库PL/SQL和工具PL/SQL。两者的编程非常相似。都具有编程结构、语法和逻辑机制。工具PL/SQL另外还增加了用于支持工具(如ORACLEForms)的句法,如:在窗体上设置按钮等。本章主要介绍数据库PL/SQL内容。§1.2.1PL/SQL的好处§1.2.1.1有利于客户/服务器环境应用的运行对于客户/服务器环境来说,真正的瓶颈是网络上。无论网络多快,只要客户端与服务器进行大量的数据交换。应用运行的效率自然就回受到影响。如果使用PL/SQL进行编程,将这种具有大量数据处理的应用放在服务器端来执行。自然就省去了数据在网上的传输时间。§1.2.1.2适合于客户环境-60- 60PL/SQL由于分为数据库PL/SQL部分和工具PL/SQL。对于客户端来说,PL/SQL可以嵌套到相应的工具中,客户端程序可以执行本地包含PL/SQL部分,也可以向服务发SQL命令或激活服务器端的PL/SQL程序运行。§1.2.2PL/SQL可用的SQL语句PL/SQL是ORACLE系统的核心语言,现在ORACLE的许多部件都是由PL/SQL写成。在PL/SQL中可以使用的SQL语句有:INSERT,UPDATE,DELETE,SELECTINTO,COMMIT,ROLLBACK,SAVEPOINT。提示:在PL/SQL中只能用SQL语句中的DML部分,不能用DDL部分,如果要在PL/SQL中使用DDL(如CREATEtable等)的话,只能以动态的方式来使用。lORACLE的PL/SQL组件在对PL/SQL程序进行解释时,同时对在其所使用的表名、列名及数据类型进行检查。lPL/SQL可以在SQL*PLUS中使用。lPL/SQL可以在高级语言中使用。lPL/SQL可以在ORACLE的开发工具中使用。l其它开发工具也可以调用PL/SQL编写的过程和函数,如PowerBuilder等都可以调用服务器端的PL/SQL过程。§1.3运行PL/SQL程序PL/SQL程序的运行是通过ORACLE中的一个引擎来进行的。这个引擎可能在ORACLE的服务器端,也可能在ORACLE应用开发的客户端。引擎执行PL/SQL中的过程性语句,然后将SQL语句发送给数据库服务器来执行。再将结果返回给执行端。-60- 60第二章PL/SQL块结构和组成元素§2.1PL/SQL块PL/SQL程序由三个块组成,即声明部分、执行部分、异常处理部分。PL/SQL块的结构如下:DECLARE/*声明部分:在此声明PL/SQL用到的变量,类型及游标,以及局部的存储过程和函数*/BEGIN/*执行部分:过程及SQL语句,即程序的主要部分*/EXCEPTION/*执行异常部分:错误处理*/END;其中执行部分是必须的。PL/SQL块可以分为三类:1.无名块:动态构造,只能执行一次。2.子程序:存储在数据库中的存储过程、函数及包等。当在数据库上建立好后可以在其它程序中调用它们。3.触发器:当数据库发生操作时,会触发一些事件,从而自动执行相应的程序。§2.2PL/SQL结构lPL/SQL块中可以包含子块;l子块可以位于PL/SQL中的任何部分;l子块也即PL/SQL中的一条命令;§2.3标识符PL/SQL程序设计中的标识符定义与SQL的标识符定义的要求相同。要求和限制有:l标识符名不能超过30字符;l第一个字符必须为字母;l不分大小写;l不能用’-‘(减号);l不能是SQL保留字。提示:一般不要把变量名声明与表中字段名完全一样,如果这样可能得到不正确的结果.-60- 60例如:下面的例子将会删除所有的纪录,而不是KING的记录;DECLAREEnamevarchar2(20):=’KING’;BEGINDELETEFROMempWHEREename=ename;END;变量命名在PL/SQL中有特别的讲究,建议在系统的设计阶段就要求所有编程人员共同遵守一定的要求,使得整个系统的文档在规范上达到要求。下面是建议的命名方法:标识符命名规则例子程序变量V_nameV_name程序常量C_NameC_company_name游标变量Name_cursorEmp_cursor异常标识E_nameE_too_many表类型Name_table_typeEmp_record_type表Name_tableEmp记录类型Name_recordEmp_recordSQL*Plus替代变量P_nameP_sal绑定变量G_nameG_year_sal§2.4PL/SQL变量类型在前面的介绍中,有系统的数据类型,也可以自定义数据类型。下表是ORACLE类型和PL/SQL中的变量类型的合法使用列表:§2.4.1变量类型在ORACLE8i中可以使用的变量类型有:类型子类说明范围ORACLE限制CHARCharacterStringRowidNchar定长字符串民族语言字符集0à32767可选,确省=12000VARCHAR2Varchar,StringNVARCHAR2可变字符串民族语言字符集0à3276740004000BINARY_INTEGER带符号整数,为整数计算优化性能NUMBER(p,s)DecDoubleprecisionIntegerIntNumericRealSmallint小数,NUMBER的子类型高精度实数整数,NUMBER的子类型整数,NUMBER的子类型与NUMBER等价与NUMBER等价整数,比integer小-60- 60LONG变长字符串0->214748364732,767字节DATE日期型公元前4712年1月1日至公元后4712年12月31日BOOLEAN布尔型TRUE,FALSE,NULL不使用ROWID存放数据库行号UROWID通用行标识符,字符类型例1.插入一条记录并显示;DECLARERow_idUROWID;infoVARCHAR2(40);BEGININSERTINTOdeptVALUES(90,‘SERVICE’,‘BEIJING’)RETURNINGrowid,dname||’:’||to_char(deptno)||’:’||locINTOrow_id,info;DBMS_OUTPUT.PUT_LINE(‘ROWID:’||row_id);DBMS_OUTPUT.PUT_LINE(info);END;其中:RETURNING子句用于检索INSERT语句中所影响的数据行数,当INSERT语句使用VALUES子句插入数据时,RETURNING字句还可将列表达式、ROWID和REF值返回到输出变量中。在使用RETURNING子句是应注意以下几点限制:1.不能并行DML语句和远程对象一起使用;2.不能检索LONG类型信息;3.当通过视图向基表中插入数据时,只能与单基表视图一起使用。例2.修改一条记录并显示DECLARERow_idUROWID;infoVARCHAR2(40);BEGINUPDATEdeptSETdeptno=80WHEREDNAME=‘SERVICE’RETURNINGrowid,dname||’:’||to_char(deptno)||’:’||locINTOrow_id,info;DBMS_OUTPUT.PUT_LINE(‘ROWID:’||row_id);DBMS_OUTPUT.PUT_LINE(info);END;其中:RETURNING子句用于检索被修改行信息:当UPDATE语句修改单行数据时,RETURNING-60- 60子句可以检索被修改行的ROWID和REF值,以及行中被修改列的列表达式,并可将他们存储到PL/SQL变量或复合变量中;当UPDATE语句修改多行数据时,RETURNING子句可以将被修改行的ROWID和REF值,以及列表达式值返回到复合变量数组中。在UPDATE中使用RETURNING子句的限制与INSERT语句中对RETURNING子句的限制相同。例3.删除一条记录并显示DECLARERow_idUROWID;infoVARCHAR2(40);BEGINDELETEdeptWHEREDNAME=‘SERVICE’RETURNINGrowid,dname||’:’||to_char(deptno)||’:’||locINTOrow_id,info;DBMS_OUTPUT.PUT_LINE(‘ROWID:’||row_id);DBMS_OUTPUT.PUT_LINE(info);END;其中:RETURNING子句用于检索被修改行信息:当UPDATE语句修改单行数据时,RETURNING子句可以检索被修改行的ROWID和REF值,以及行中被修改列的列表达式,并可将他们存储到PL/SQL变量或复合变量中;当UPDATE语句修改多行数据时,RETURNING子句可以将被修改行的ROWID和REF值,以及列表达式值返回到复合变量数组中。在UPDATE中使用RETURNING子句的限制与INSERT语句中对RETURNING子句的限制相同。§2.4.2复合类型ORACLE在PL/SQL中除了提供象前面介绍的各种类型外,还提供一种称为复合类型的类型---记录和表.§2.4.2.1记录类型记录类型是把逻辑相关的数据作为一个单元存储起来,它必须包括至少一个标量型或RECORD数据类型的成员,称作PL/SQLRECORD的域(FIELD),其作用是存放互不相同但逻辑相关的信息。定义记录类型语法如下:TYPErecord_typeISRECORD(Field1type1[NOTNULL][:=exp1],Field2type2[NOTNULL][:=exp2],......Fieldntypen[NOTNULL][:=expn]);例4:-60- 60DECLARETYPEtest_recISRECORD(CodeVARCHAR2(10),NameVARCHAR2(30)NOTNULL:=’abook’);V_booktest_rec;BEGINV_book.code:=’123’;V_book.name:=’C++Programming’;DBMS_OUTPUT.PUT_LINE(v_book.code||v_book.name);END;可以用SELECT语句对记录变量进行赋值,只要保证记录字段与查询结果列表中的字段相配即可。§2.4.2.2使用%TYPE定义一个变量,其数据类型与已经定义的某个数据变量的类型相同,或者与数据库表的某个列的数据类型相同,这时可以使用%TYPE。使用%TYPE特性的优点在于:l所引用的数据库列的数据类型可以不必知道;l所引用的数据库列的数据类型可以实时改变。例5:DECLARE--用%TYPE类型定义与表相配的字段TYPEt_RecordISRECORD(T_noemp.empno%TYPE,T_nameemp.ename%TYPE,T_salemp.sal%TYPE);--声明接收数据的变量v_empt_Record;BEGINSELECTempno,ename,salINTOv_empFROMempWHEREempno=7788;DBMS_OUTPUT.PUT_LINE(TO_CHAR(v_emp.t_no)||v_emp.t_name||TO_CHAR(v_emp.t_sal));END;例6:DECLAREv_empnoemp.empno%TYPE:=&empno;Typer_recordisrecord(v_nameemp.ename%TYPE,v_salemp.sal%TYPE,v_dateemp.hiredate%TYPE);Recr_record;-60- 60BEGINSELECTename,sal,hiredateINTORecFROMempWHEREempno=v_empno;DBMS_OUTPUT.PUT_LINE(Rec.v_name||'---'||Rec.v_sal||'--'||Rec.v_date);END;§2.4.3使用%ROWTYPEPL/SQL提供%ROWTYPE操作符,返回一个记录类型,其数据类型和数据库表的数据结构相一致。使用%ROWTYPE特性的优点在于:l所引用的数据库中列的个数和数据类型可以不必知道;l所引用的数据库中列的个数和数据类型可以实时改变。例7:DECLAREv_empnoemp.empno%TYPE:=&empno;recemp%ROWTYPE;BEGINSELECT*INTOrecFROMempWHEREempno=v_empno;DBMS_OUTPUT.PUT_LINE('姓名:'||rec.ename||'工资:'||rec.sal||'工作时间:'||rec.hiredate);END;§2.4.4LOB类型*ORACLE提供了LOB(LargeOBject)类型,用于存储大的数据对象的类型。ORACLE目前主要支持BFILE,BLOB,CLOB及NCLOB类型。BFILE(Movie)存放大的二进制数据对象,这些数据文件不放在数据库里,而是放在操作系统的某个目录里,数据库的表里只存放文件的目录。BLOB(Photo)存储大的二进制数据类型。变量存储大的二进制对象的位置。大二进制对象的大小<=4GB。CLOB(Book)存储大的字符数据类型。每个变量存储大字符对象的位置,该位置指到大字符数据块。大字符对象的大小<=4GB。NCLOB存储大的NCHAR字符数据类型。每个变量存储大字符对象的位置,该位置指到大字符数据块。大字符对象的大小<=4GB。§2.4.5Bind变量绑定变量是在主机环境中定义的变量。在PL/SQL程序中可以使用绑定变量作为他们将要使用的其它变量。为了在PL/SQL环境中声明绑定变量,使用命令VARIABLE。例如:VARIABLEreturn_codeNUMBER-60- 60VARIABLEreturn_msgVARCHAR2(20)可以通过SQL*Plus命令中的PRINT显示绑定变量的值。例如:PRINTreturn_codePRINTreturn_msg例7:VARIABLEresultNUMBERBEGINSELECT(sal*12)+nvl(comm,0)INTO:resultFROMempWHEREempno=7788;END;PRINTresult§2.4.6INDEXBYTABLES包括两个基本成分:.数据处理类型为BINARY_INTEGER主键;.标量或记录数据类型的列.TYPEtype_nameISTABLEOF{column_type|variable%TYPE|table.column%TYPE}[NOTNULL]|table%ROWTYPE[INDEXBYBINARY_INTEGER];方法描述EXISTS(n)ReturnTRUEifthenthelementinaPL/SQLtableexists;COUNTReturnsthenumberofelementsthataPL/SQLtablecurrentlycontains;FIRSTLASTReturnthefirstandlast(smallestandlastest)indexnumbersinaPL/SQLtable.ReturnsNULLifthePL/SQLtableisempty.PRIOR(n)ReturnstheindexnumberthatprecedesindexninaPL/SQLtable;NEXT(N)ReturnstheindexnumberthatsucceedsindexninaPL/SQLtable;TRIMTRIMremovesoneelementfromtheendofaPL/SQLtable.TRIM(n)removesnelementfromtheendofaPL/SQLtable.DELETEDELETEremovesallelementsfromaPL/SQLtable.DELETE(n)removesthenthelementsfromaPL/SQLtable.DELETE(m,n)removesallelementsintherangemtonfromaPL/SQLtable.例8:DECLARETYPEdept_table_typeISTABLEOFdept%ROWTYPEINDEXBYBINARY_INTEGER;my_dname_tabledept_table_type;-60- 60v_countnumber(2):=4;BEGINFORintIN1..v_countLOOPSELECT*INTOmy_dname_table(int)FROMdeptWHEREdeptno=int*10;ENDLOOP;FORintINmy_dname_table.FIRST..my_dname_table.LASTLOOPDBMS_OUTPUT.PUT_LINE(‘Departmentnumber:‘||my_dname_table(int).deptno);DBMS_OUTPUT.PUT_LINE(‘Departmentname:‘||my_dname_table(int).dname);ENDLOOP;END;§2.4.7数据类型的转换*隐式类型转换BIN_INTCHARDATELONGNUMBERPLS_INTUROWIDVARCHAR2BIN_INT üüüCHAR üDATEüüüüüLONGüüüüüüNUMBERüüüRAWüüüüüUROWIDüüüüüüVARCHAR2ü§2.5运算符和表达式(数据定义)§2.5.1关系运算符运算符意义=等于<>,!=,~=,^=不等于<小于>大于<=小于或等于>=大于或等于§2.5.2一般运算符运算符意义+加号-减号*乘号/除号:=赋值号-60- 60=>关系号..范围运算符||字符连接符§2.5.3逻辑运算符运算符意义ISNULL是空值 BETWEEN介于两者之间IN在一列值中间 AND逻辑与OR逻辑或NOT取返,如ISNOTNULL,NOTIN§2.6变量赋值在PL/SQL编程中,变量赋值是一个值得注意的地方,它的语法如下:variable:=expression;variable是一个PL/SQL变量,expression是一个PL/SQL表达式.§2.6.1字符及数字运算特点空值加数字仍是空值:NULL+<数字>=NULL空值加(连接)字符,结果为字符:NULL||<字符串>=<字符串>§2.6.2BOOLEAN赋值布尔值只有TRUE,FALSE及NULL三个值。如:DECLAREdoneBOOLEAN;/*thefollowingstatementsarelegal:*/BEGINdone:=FALSE;WHILENOTdoneLOOPNull;ENDLOOP;END;§2.6.3数据库赋值数据库赋值是通过SELECT语句来完成的,每次执行SELECT语句就赋值一次,一般要求被赋值的变量与SELECT中的列名要一一对应。如:-60- 60例9:DECLAREemp_idemp.empno%TYPE:=7788;emp_nameemp.ename%TYPE;wagesemp.sal%TYPE;BEGINSELECTename,NVL(sal,0)+NVL(comm,0)INTOemp_name,wagesFROMempWHEREempno=emp_id;Dbms_output.put_line(emp_name||’----‘||to_char(wages));END;提示:不能将SELECT语句中的列赋值给布尔变量。§2.6.4可转换的类型赋值lCHAR转换为NUMBER:使用TO_NUMBER函数来完成字符到数字的转换,如:v_total:=TO_NUMBER(‘100.0’)+sal;lNUMBER转换为CHAR:使用TO_CHAR函数可以实现数字到字符的转换,如:v_comm:=TO_CHAR(‘123.45’)||’元’;l字符转换为日期:使用TO_DATE函数可以实现字符到日期的转换,如:v_date:=TO_DATE('2001.07.03','yyyy.mm.dd');l日期转换为字符使用TO_CHAR函数可以实现日期到字符的转换,如:v_to_day:=TO_CHAR(SYSDATE,'yyyy.mm.ddhh24:mi:ss');§2.7变量作用范围及可见性在PL/SQL编程中,如果在变量的定义上没有做到统一的话,可能会隐藏一些危险的错误,这样的原因主要是变量的作用范围所致。与其它高级语言类似,PL/SQL的变量作用范围特点是:l变量的作用范围是在你所引用的程序单元(块、子程序、包)内。即从声明变量开始到该块的结束。l一个变量(标识)只能在你所引用的块内是可见的。l当一个变量超出了作用范围,PL/SQL引擎就释放用来存放该变量的空间(因为它可能不用了)。l在子块中重新定义该变量后,它的作用仅在该块内。-60- 60例10:DECLAREEmesschar(80);BEGINDECLAREV1NUMBER(4);BEGINSELECTempnoINTOv1FROMempWHERELOWER(job)=’president’;DBMS_OUTPUT.PUT_LINE(V1);EXCEPTIONWhenTOO_MANY_ROWSTHENDBMS_OUTPUT.PUT_LINE(‘Morethanonepresident’);END;DECLAREV1NUMBER(4);BEGINSELECTempnoINTOv1FROMempWHERELOWER(job)=’manager’;EXCEPTIONWhenTOO_MANY_ROWSTHENDBMS_OUTPUT.PUT_LINE(‘Morethanonemanager’);END;EXCEPTIONWhenothersTHENEmess:=substr(SQLERRM,1,80);DBMS_OUTPUT.PUT_LINE(emess);END;§2.8注释在PL/SQL里,可以使用两种符号来写注释,即:l使用双‘-‘(减号)加注释PL/SQL允许用–来写注释,它的作用范围是只能在一行有效。如:V_SalNUMBER(12,2);--工资变量。l使用/**/来加一行或多行注释,如:/***********************************************//*文件名:statistcs_sal.sql*//***********************************************/提示:被解释存放在数据库中的PL/SQL-60- 60程序,一般系统自动将程序头部的注释去掉。只有在PROCEDURE之后的注释才被保留;另外程序中的空行也自动被去掉。§2.9简单例子§2.9.1简单数据插入例子例11:/*本例子仅是一个简单的插入,不是实际应用。*/DECLAREv_enameVARCHAR2(20):=‘Bill’;v_salNUMBER(7,2):=1234.56;v_deptnoNUMBER(2):=10;v_empnoNUMBER(4):=8888;BEGININSERTINTOemp(empno,ename,JOB,sal,deptno,hiredate)VALUES(v_empno,v_ename,‘Manager’,v_sal,v_deptno,TO_DATE(’1954.06.09’,’yyyy.mm.dd’));COMMIT;END;§2.9.2简单数据删除例子例12:/*本例子仅是一个简单的删除例子,不是实际应用。*/DECLAREv_empnonumber(4):=8888;BEGINDELETEFROMempWHEREempno=v_empno;COMMIT;END;-60- 60第三章PL/SQL流程控制语句介绍PL/SQL的流程控制语句,包括如下三类:l控制语句:IF语句l循环语句:LOOP语句,EXIT语句l顺序语句:GOTO语句,NULL语句§3.1条件语句IF<布尔表达式>THENPL/SQL和SQL语句ENDIF;IF<布尔表达式>THENPL/SQL和SQL语句ELSE其它语句ENDIF;IF<布尔表达式>THENPL/SQL和SQL语句ELSIF<其它布尔表达式>THEN其它语句ELSIF<其它布尔表达式>THEN其它语句ELSE其它语句ENDIF;提示:ELSIF不能写成ELSEIF例1:DECLAREv_empnoemp.empno%TYPE:=&empno;V_salaryemp.sal%TYPE;V_commentVARCHAR2(35);BEGINSELECTsalINTOv_salaryFROMempWHEREempno=v_empno;IFv_salary<1500THENV_comment:=‘Fairlyless’;ELSIFv_salary<3000THENV_comment:=‘Alittlemore’;-60- 60ELSEV_comment:=‘Lotsofsalary’;ENDIF;DBMS_OUTPUT.PUT_LINE(V_comment);END;§3.2CASE表达式CASEselectorWHENexpression1THENresult1WHENexpression2THENresult2WHENexpressionNTHENresultN[ELSEresultN+1]END;例2:DECLAREV_gradechar(1):=UPPER(‘&p_grade’);V_appraisalVARCHAR2(20);BEGINV_appraisal:=CASEv_gradeWHEN‘A’THEN‘Excellent’WHEN‘B’THEN‘VeryGood’WHEN‘C’THEN‘Good’ELSE‘Nosuchgrade’END;DBMS_OUTPUT.PUT_LINE(‘Grade:‘||v_grade||’Appraisal:‘||v_appraisal);END;§3.3循环1.简单循环LOOP要执行的语句;EXITWHEN<条件语句>/*条件满足,退出循环语句*/ENDLOOP;-60- 60例3.DECLAREintNUMBER(2):=0;BEGINLOOPint:=int+1;DBMS_OUTPUT.PUT_LINE('int的当前值为:'||int);EXITWHENint=10;ENDLOOP;END;2.WHILE循环WHILE<布尔表达式>LOOP要执行的语句;ENDLOOP;例4.DECLARExNUMBER;BEGINx:=1;WHILEx<10LOOPDBMS_OUTPUT.PUT_LINE('X的当前值为:'||x);x:=x+1;ENDLOOP;END;3.数字式循环FOR循环计数器IN[REVERSE]下限..上限LOOP要执行的语句;ENDLOOP;每循环一次,循环变量自动加1;使用关键字REVERSE,循环变量自动减1。跟在INREVERSE后面的数字必须是从小到大的顺序,而且必须是整数,不能是变量或表达式。可以使用EXIT退出循环。例5.BEGINFORintin1..10LOOPDBMS_OUTPUT.PUT_LINE('int的当前值为:'||int);ENDLOOP;END;例6.-60- 60CREATETABLEtemp_table(num_colNUMBER);DECLAREV_counterNUMBER:=10;BEGININSERTINTOtemp_table(num_col)VALUES(v_counter);FORv_counterIN20..25LOOPINSERTINTOtemp_table(num_col)VALUES(v_counter);ENDLOOP;INSERTINTOtemp_table(num_col)VALUES(v_counter);FORv_counterINREVERSE20..25LOOPINSERTINTOtemp_table(num_col)VALUES(v_counter);ENDLOOP;END;DROPTABLEtemp_table;§3.3标号和GOTOPL/SQL中GOTO语句是无条件跳转到指定的标号去的意思。语法如下:GOTOlabel;......<