1、Oracle 数据库基础教程20071本章内容本章内容pPL/SQL概述pPL/SQL基础p控制结构p游标p异常处理p存储子程序p包p触发器Oracle 数据库基础教程20072本章要求本章要求p掌握PL/SQL程序设计基础知识p掌握存储过程、函数、包、触发器的应用Oracle 数据库基础教程2007315.1 PL/SQL概述概述pPL/SQL特点pPL/SQL功能特性pPL/SQL执行过程与开发工具Oracle 数据库基础教程2007415.1.1PL/SQL特点特点p与SQL语言紧密集成。p减小网络流量,提高应用程序的运行性能。p模块化的程序设计功能,提高了系统可靠性。p服务器端程序设计
2、,可移植性好。Oracle 数据库基础教程2007515.1.2PL/SQL功能特性功能特性p语句块结构p异常处理p变量和类型p条件语句p循环结构p游标p过程、函数和触发器p包p集合p动态SQLp对象特性Oracle 数据库基础教程2007615.1.3PL/SQL执行过程与开发工具执行过程与开发工具PL/SQL块SQL语句客户端应用程序PL/SQL引擎数据库服务器过程化语句执行器SQL执行器块中SQL语句pPL/SQL执行过程 Oracle 数据库基础教程20077pPL/SQL开发工具nSQL*PLUSnProcedure BuildernOracle Form、Oracle Report
3、snPL/SQL DeveloperOracle 数据库基础教程2007815.2 PL/SQL基础基础pPL/SQL程序结构 p词法单元 p数据类型p变量与常量p编译指示pPL/SQL中的SQL语句Oracle 数据库基础教程20079PL/SQL程序结构程序结构pPL/SQL块的组成pPL/SQL块分类 Oracle 数据库基础教程200710pPL/SQL块的组成nPL/SQL语言以块为单位,块中可以嵌套子块。语言以块为单位,块中可以嵌套子块。n一个基本的一个基本的PL/SQL块由块由3部分组成:部分组成:p声明(DECLARE),p可执行部分(BEGIN),p异常处理部分EXCEPTI
4、ON)。n Oracle 数据库基础教程200711p声明部分n声明部分以关键字DECLARE开始,BEGIN结束。主要用于声明变量、常量、数据类型、游标、异常处理名称以及本地(局部)子程序定义等。p可执行部分n执行部分是PL/SQL块的功能实现部分,以关键字BEGIN开始,EXCEPTION或END结束(如果PL/SQL块中没有异常处理部分,则以END结束)。该部分通过变量赋值、流程控制、数据查询、数据操纵、数据定义、事务控制、游标处理等实现块的功能。p异常处理部分n异常处理部分以关键字异常处理部分以关键字EXCEPTION开始,开始,END结束。该部分用结束。该部分用于处理该块执行过程中产
5、生的异常。于处理该块执行过程中产生的异常。Oracle 数据库基础教程200712p注意:n执行部分是必需的,而声明部分和异常部分是执行部分是必需的,而声明部分和异常部分是可选的;可选的;n可以在一个块的执行部分或异常处理部分嵌套可以在一个块的执行部分或异常处理部分嵌套其他的其他的PL/SQL块;块;n所有的所有的PL/SQL块都是以块都是以“END;”结束结束 Oracle 数据库基础教程200713pPL/SQL块分类n匿名块匿名块n命名块命名块p函数p存储过程p包p触发器Oracle 数据库基础教程20071415.5.215.5.2词法单元词法单元p字符集p标识符p分隔符p常量值p注释
6、Oracle 数据库基础教程200715p字符集n大小写字母:大小写字母:AZAZ,azazn数字:数字:0909n空白:制表符、空格和回车空白:制表符、空格和回车n数字符号:数字符号:+-*/+-*/=n标点符号:标点符号:!#$%&*()()_|?;:,.“Oracle 数据库基础教程200716p标识符n标标识识符符以以字字母母开开头头,后后边边可可以以跟跟字字母母、数数字字、货币符号、下划线和货币符号、下划线和”#”n标标识识符符的的最最大大长长度度为为3030字字符符,并并且且所所有有字字符符都都是有效的。是有效的。p合法:X v_studentID TempVarp非法:X+y _
7、temp Oracle 数据库基础教程200717p+p-p*p/p=p:=pp=pp!=p=p=p(p)p/*p*/pp%p;p:p.pp“p.pp|p=p*p-p分隔符分隔符Oracle 数据库基础教程200718p常量值n字符型常量字符型常量n数字型常量数字型常量 n布尔型常量:布尔型常量:TURE、FALSE、NULLn日期型常量日期型常量Oracle 数据库基础教程20071915.2.3数据类型数据类型p数字类型p字符类型p日期/区间类型p行标识类型p布尔类型p原始类型pLOB类型p记录类型p集合类型Oracle 数据库基础教程200720PL/SQL中常用的基本数据类型分类数据类
8、型数字类型NUMBER、BINARY_NUMBER PLS_NUMBER字符类型VARCHAR2、CHAR、LONG、NCHAR、NVARCHAR日期/区间类型 DATE、TIMESTAMP、INTERVAL行标识类型ROWID、UROWID布尔类型BOOLEAN(TRUE、FALSE、NULL)原始类型RAW、LONG RAWLOB类型CLOB、BLOB、NCLOB、BFILE记录类型RECORD集合类型TABLE、VARRAYOracle 数据库基础教程200721p记录类型的定义nTYPE record_type IS RECORD(nfield1 datatype1 NOT NULLD
9、EFAULT|:=expr1,nfield2 datatype2 NOT NULL DEFAULT|:=expr2,nnfieldn datatypen NOT NULL DEFAULT|:=exprn);Oracle 数据库基础教程20072215.2.415.2.4变量与常量变量与常量p变量与常量的定义p变量的作用域Oracle 数据库基础教程200723变量声明变量与常量的定义变量与常量的定义p变量定义的一般格式:n CONSTANT NOT NULL DEFAULT|:=;p说明n每行只能定义一个标识符。n如果加上关键字CONSTANT,则表示所定义的标识符为一个常量,必须为它赋初值。
10、n如果定义的标识符不能为空,则必须加上关键字NOT NULL,并赋初值。n为标识符赋值时,使用赋值符号:=,默认值为空。Oracle 数据库基础教程200724pDECLAREp v1 NUMBER(4);p v2 NUMBER(4)NOT NULL:=10;p v3 CONSTANT NUMBER(4)DEFAULT 100;pBEGINp IF v1 IS NULL THEN p DBMS_OUTPUT.PUT_LINE(V1 IS NULL!);p END IF;p DBMS_OUTPUT.PUT_LINE(v2|v3);pEND;Oracle 数据库基础教程200725p声明一个变量,
11、使它的类型与某个变量或声明一个变量,使它的类型与某个变量或数据库基本表中某个列的数据类型一致,数据库基本表中某个列的数据类型一致,可以使用可以使用%TYPE。p示例示例nv_empno1 emp.empno%TYPE;nv_empno2 v_empno1%TYPE;Oracle 数据库基础教程200726变量的作用域变量的作用域p变量的作用域是指变量的有效作用范围,从变量声明开始,直到块结束。p如果PL/SQL块相互嵌套,则在内部块中声明的变量是局部的,只能在内部块中引用,而在外部块中声明的变量是全局的,既可以在外部块中引用,也可以在内部块中引用。p如果内部块与外部块中定义了同名变量,则在内部
12、块中引用外部块的全局变量时需要使用外部块名进行标识。Oracle 数据库基础教程200727ppDECLAREp v_ename CHAR(15);p v_outer NUMBER(5);pBEGINp v_outer:=10;p DECLAREp v_ename CHAR(20);p v_inner DATE;p BEGINp v_inner:=sysdate;p v_ename:=INNER V_ENAME;p OUTER.v_ename:=OUTER V_ENAME;p END;p DBMS_OUTPUT.PUT_LINE(v_ename);pEND;Oracle 数据库基础教程2007
13、2815.2.5编译指示编译指示p编译指示是对编译程序发出的特殊指令,也称伪指令。n关键字:关键字:PRAGMApPL/SQL提供以下四种编译指示:nEXCEPTION_INITp告诉编译程序将一个特定的错误号与程序中所声明的异常标识符关联起来。nRESTRICT_REFERENCESp告诉编译程序打包程序的纯度,即对函数中可以使用的SQL语句和包变量进行限制。Oracle 数据库基础教程200729nSERIALLY_REUSEABLEp告诉PL/SQL运行时引擎,在数据引用之间不要保持包级数据。nAUTONOMOUS_TRANSACTIONp告诉编译程序,该程序块为自治事务,即该事务的提交
14、和回滚是独立进行的。Oracle 数据库基础教程20073015.2.6PL/SQL中中SQL语句语句p可以在PL/SQL中执行的SQL语句包括nSELECT nDML(UPDATE、DELETE、INSERT)n事务控制语句(事务控制语句(COMMIT、ROLLBACK、SAVEPOINT)p注意DDL语句不可以直接使用Oracle 数据库基础教程200731pSELECTINTOnSELECTINTO语句只能查询一个记录的信语句只能查询一个记录的信息,如果没有查询到任何数据,则会产生息,如果没有查询到任何数据,则会产生NO_DATA_FOUND异常;如果查询到多个异常;如果查询到多个记录,
15、则会产生记录,则会产生TOO_MANY_ROW异常。异常。nINTO句子后的变量用于接收查询的结果,变句子后的变量用于接收查询的结果,变量的个数、顺序应该与查询的目标数据相匹配,量的个数、顺序应该与查询的目标数据相匹配,也可以是记录类型的变量。也可以是记录类型的变量。DML语句语句Oracle 数据库基础教程200732pDECLAREpv_emp emp%ROWTYPE;p v_ename emp.ename%type;p v_sal emp.sal%type;pBEGINpSELECT*INTO v_emp FROM emp WHERE ename=SMITH;p DBMS_OUTPUT.
16、PUT_LINE(v_emp.empno|v_emp.sal);p select ename,sal INTO v_ename,v_sal FROM emp WHERE empno=7900;p DBMS_OUTPUT.PUT_LINE(v_ename|v_sal);pEND;Oracle 数据库基础教程200733pDML语句nPL/SQL中中DML语句对标准语句对标准SQL语句中的语句中的DML语句语句进行了扩展,允许使用变量。进行了扩展,允许使用变量。p 示例nDECLAREn v_empno emp.empno%TYPE:=7500;nBEGINn INSERT INTO emp(em
17、pno,ename,sal,deptno)VALUES(v_empno,JOAN,2300,20);n UPDATE emp SET sal=sal+100 WHERE empno=v_empno;n DELETE FROM emp WHERE empno=v_empno;nEND;Oracle 数据库基础教程200734pWHEREn标识符的区分标识符的区分p系统首先查看WHERE子句中的标识符是否与表中的列名相同,如果相同,则该标识符被解释为列名;如果没有同名列,系统检查该标识符是不是PL/SQL语句块的变量。n字符串比较字符串比较p填充比较:通过在短字符串后添加空格,使两个字符串达到相同
18、长度,然后根据每个字符的ASCII码进行比较。p非填充比较:根据每个字符的ASCII码进行比较,最先结束的字符串为小。nPL/SQL中规定,对定长的字符串(中规定,对定长的字符串(CHAR类型的字类型的字符串和字符串常量)采用填充比较;如果比较的字符符串和字符串常量)采用填充比较;如果比较的字符串中有一个是变长字符串(串中有一个是变长字符串(VARCHAR2类型的字符类型的字符串),则采用非填充比较。串),则采用非填充比较。Oracle 数据库基础教程200735pRETURNINGn如果要查询当前如果要查询当前DML语句操作的记录的信息,语句操作的记录的信息,可以在可以在DML语句末尾使用语
19、句末尾使用RETURNING语语句返回该记录的信息。句返回该记录的信息。nRETURNING语句的基本语法:语句的基本语法:pRETURNING select_list_item INTO variable_list|record_variable;Oracle 数据库基础教程200736nDECLAREn v_sal emp.sal%TYPE;nBEGINn UPDATE emp SET sal=sal+100 WHERE empno=7844 RETURNING sal INTO v_sal;n DBMS_OUTPUT.PUT_LINE(v_sal);nEND;Oracle 数据库基础教程
20、20073715.3 15.3 控制结构控制结构 p选择结构p循环结构p跳转结构Oracle 数据库基础教程20073815.3.1选择结构选择结构pIF语句语句nIF condition1 THEN statements1;nELSIF condition2 THEN statements2;nnELSE else_statements;nEND IF;p注意注意n条件是一个布尔型变量或表达式,取值只能是TRUE,FALSE,NULL。Oracle 数据库基础教程200739p例如,输入一个员工号,修改该员工的工资,如果该员工为10号部门,工资增加100;若为20号部门,工资增加150;若为
21、30号部门,工资增加200;否则增加300。Oracle 数据库基础教程200740pDECLAREpv_deptno emp.deptno%type;p v_increment NUMBER(4);p v_empno emp.empno%type;pBEGINp v_empno:=&x;p SELECT deptno INTO v_deptno FROM emp WHERE empno=v_empno;p IF v_deptno=10 THEN v_increment:=100;p ELSIF v_deptno=20 THEN v_increment:=150;p ELSIF v_deptn
22、o=30 THEN v_increment:=200;p ELSE v_increment:=300;p END IF;p UPDATE emp SET sal=sal+v_increment WHERE empno=v_empno;pEND;Oracle 数据库基础教程200741搜索式搜索式CASE语句语句p基本语法基本语法nCASEn WHEN condition1 THEN statements1;n WHEN condition2 THEN statements2;n n WHEN conditionn THEN statementsn;n ELSE else_statements;
23、nEND CASE;Oracle 数据库基础教程200742等值比较的等值比较的CASE语句语句p基本语法基本语法nCASE test_valuen WHEN value1 THEN statements1;n WHEN value2 THEN statements2;n n WHEN valuen THEN statementsn;n ELSE else_ statements;nEND CASE;Oracle 数据库基础教程200743pDECLAREp v_deptno emp.deptno%type;p v_increment NUMBER(4);p v_empno emp.empno
24、%type;pBEGINp v_empno:=&x;p SELECT deptno INTO v_deptno FROM emp WHERE empno=v_empno;p CASE v_deptno p WHEN 10 THEN v_increment:=100;p WHEN 20 THEN v_increment:=150;p WHEN 30 THEN v_increment:=200;p ELSE v_increment:=300;pEND CASE;pUPDATE emp SET sal=sal+v_increment WHERE empno=v_empno;pEND;Oracle 数
25、据库基础教程200744p根据输入的员工号,修改该员工工资。如果该员工工资低于1000,则工资增加200;如果工资在1000-2000之间,则增加150;如果工资在2000-3000之间,则增加100;否则增加50。Oracle 数据库基础教程200745pDECLAREpv_sal emp.sal%type;pv_increment NUMBER(4);pv_empno emp.empno%type;pBEGINpv_empno:=&x;pSELECT sal INTO v_sal FROM emp WHERE empno=v_empno;pCASE p WHEN v_sal1000 THE
26、N v_increment:=200;p WHEN v_sal2000 THEN v_increment:=150;p WHEN v_sal 50;p END LOOP;pEND;Oracle 数据库基础教程200749WHILE循环循环p基本语法 WHILE condition LOOP sequence_of_statement;END LOOP;Oracle 数据库基础教程200750p例如,利用WHILE循环向temp_table表中插入50条记录。程序为:pDECLAREp v_counter BINARY_INTEGER:=1;pBEGINp WHILE v_counter=50
27、LOOPp INSERT INTO temp_table VALUES(v_counter,Loop index);p v_counter:=v_counter+1;p END LOOP;pEND;Oracle 数据库基础教程200751FOR循环循环p基本语法 FOR loop_counter IN REVERSE low_bound.high_bound LOOP sequence_of_statement;END LOOP;p注意:n循环变量不需要显式定义,系统隐含地将它声明为循环变量不需要显式定义,系统隐含地将它声明为BINARY_INTEGERBINARY_INTEGER变量;变量;
28、n系统默认时,循环变量从下界往上界递增计数,如果系统默认时,循环变量从下界往上界递增计数,如果使用使用REVERSEREVERSE关键字,则表示循环变量从上界向下界递关键字,则表示循环变量从上界向下界递减计数;减计数;n循环变量只能在循环体中使用,不能在循环体外使用。循环变量只能在循环体中使用,不能在循环体外使用。Oracle 数据库基础教程200752p例如,利用FOR循环向temp_table表中插入50条记录。程序为:pBEGINp FOR v_counter IN 1.50 LOOPp INSERT INTO temp_table VALUES(v_counter,Loop Index
29、);p END LOOP;pEND;Oracle 数据库基础教程20075315.3.3跳转结构跳转结构n语法格式:标号标号GOTO 标号;标号;n说明:p块内可以跳转,内层块可以跳到外层块,但外层块不块内可以跳转,内层块可以跳到外层块,但外层块不能跳到内层。能跳到内层。pIF语句不能跳入。不能从循环体外跳入循环体内。语句不能跳入。不能从循环体外跳入循环体内。不能从子程序外部跳到子程序中。不能从子程序外部跳到子程序中。p由于由于goto语句的缺点,建议尽量少用甚至不用语句的缺点,建议尽量少用甚至不用goto语句。语句。Oracle 数据库基础教程20075415.4 15.4 游标游标p游标的
30、概念及类型 p显式游标 p隐式游标Oracle 数据库基础教程200755pDECLAREp v_counter BINARY_INTEGER:=1;pBEGINp p INSERT INTO temp_table p VALUES(v_counter,Loop index);p v_counter:=v_Counter+1;p IF v_counter6000 THEN p RAISE e_highlimit;p END IF;pEXCEPTIONp WHEN e_highlimit THENp DBMS_OUTPUT.PUT_LINE(The salary is too large!);p
31、 ROLLBACK;pEND;Oracle 数据库基础教程2007100OTHERS异常处理器异常处理器pOTHERS异常处理器是一个特殊的异常处理器,可以捕获所有的异常。p通常,OTHERS异常处理器总是作为异常处理部分的最后一个异常处理器,负责处理那些没有被其他异常处理器捕获的异常。Oracle 数据库基础教程2007101pDECLAREp v_sal emp.sal%TYPE;p e_highlimit EXCEPTION;pBEGINp SELECT sal INTO v_sal FROM emp WHERE ename=JOAN;p UPDATE emp SET sal=sal+1
32、00 WHERE empno=7900;p IF v_sal6000 THEN p RAISE e_highlimit;p END IF;pEXCEPTIONp WHEN e_highlimit THENp DBMS_OUTPUT.PUT_LINE(The salary is too large!);p ROLLBACK;p WHEN OTHERS THENp DBMS_OUTPUT.PUT_LINE(There is some wrong in selecting!);pEND;Oracle 数据库基础教程2007102p可以通过两个函数来获取错误相关信息。nSQLCODE:返回当前错误代码
33、。:返回当前错误代码。p如果是用户定义错误返回值为1;p如果是ORA-1403:NO DATA FOUND错误,返回值为100;p其他Oracle内部错误返回相应的错误号。nSQLERRM:返回当前错误的消息文本。:返回当前错误的消息文本。p如果是Oracle内部错误,返回系统内部的错误描述;p如果是用户定义错误,则返回信息文本为“User-defined Exception”。Oracle 数据库基础教程2007103pDECLAREp v_sal emp.sal%TYPE;p e_highlimit EXCEPTION;p v_code NUMBER(6);p v_text VARCHAR
34、2(200);pBEGINp SELECT sal INTO v_sal FROM emp WHERE ename=JOAN;p UPDATE emp SET sal=sal+100 WHERE empno=7900;p IF v_sal6000 THEN p RAISE e_highlimit;p END IF;pEXCEPTIONp WHEN e_highlimit THENp DBMS_OUTPUT.PUT_LINE(The salary is too large!);p ROLLBACK;p WHEN OTHERS THENp v_code:=SQLCODE;p v_text:=SQL
35、ERRM;p DBMS_OUTPUT.PUT_LINE(v_code|v_text);pEND;Oracle 数据库基础教程200710415.5.3异常的传播异常的传播p可执行部分异常的传播n如果当前语句块有该异常的处理器,则执行如果当前语句块有该异常的处理器,则执行之,并且成功完成该语句块。然后,控制权之,并且成功完成该语句块。然后,控制权传递到外层语句块。传递到外层语句块。n如果当前语句块没有该异常的处理器,则通如果当前语句块没有该异常的处理器,则通过在外层语句块中产生该异常来传播该异常。过在外层语句块中产生该异常来传播该异常。然后,执行对外层语句块执行步骤然后,执行对外层语句块执行步骤
36、1。如果。如果没有外层语句块,则该异常将传播到调用环没有外层语句块,则该异常将传播到调用环境。境。Oracle 数据库基础教程2007105pDECLAREp v_sal emp.sal%TYPE;pBEGINp BEGIN p SELECT sal INTO v_sal FROM emp WHERE ename=JOAN;p EXCEPTIONp WHEN NO_DATA_FOUND THEN p DBMS_OUTPUT.PUT_LINE(There is not such an employee!);p END;p DBMS_OUTPUT.PUT_LINE(Now this is outp
37、utted by outer block!);pEND;p/pThere is not such an employee!pNow this is outputted by outer block!Oracle 数据库基础教程2007106pDECLAREp v_sal emp.sal%TYPE;pBEGINp BEGIN p SELECT sal INTO v_sal FROM emp WHERE deptno=10;p EXCEPTIONp WHEN NO_DATA_FOUND THEN p DBMS_OUTPUT.PUT_LINE(There is not such an employe
38、e!);p END;p DBMS_OUTPUT.PUT_LINE(Now this is outputted by outer block!);pEXCEPTIONp WHEN TOO_MANY_ROWS THENp DBMS_OUTPUT.PUT_LINE(There are more than one employee!);pEND;p/pThere are more than one employee!Oracle 数据库基础教程2007107p声明部分异常的传播n声明部分的异常立刻传播到外层语句块,即声明部分的异常立刻传播到外层语句块,即使当前语句块有异常处理器。使当前语句块有异常处理
39、器。p异常处理部分的异常的传播n异常处理器中产生的异常,可以有异常处理器中产生的异常,可以有RAISE语句显式产生,也可以通过运行时错误而隐语句显式产生,也可以通过运行时错误而隐含产生。异常立即被传播到外层语句块。含产生。异常立即被传播到外层语句块。Oracle 数据库基础教程2007108pBEGINp DECLAREpv_number NUMBER(6):=ABC;pBEGINp v_number:=10;p EXCEPTIONp WHEN OTHERS THENp DBMS_OUTPUT.PUT_LINE(This is outputted by inner block!);p END;
40、pEXCEPTIONpWHEN OTHERS THENp DBMS_OUTPUT.PUT_LINE(This is outputted by outer block!);pEND;p/pThis is outputted by outer block!Oracle 数据库基础教程200710915.6 存储子程序存储子程序p存储过程p函数p局部子程序Oracle 数据库基础教程2007110p存储子程序是指被命名的PL/SQL块,以编译的形式存储在数据库服务器中,可以在应用程序中进行调用,是PL/SQL程序模块化的一种体现。p存储子程序是以独立对象的形式存储在数据库服务器中,因此是一种全局结构
41、,与之对应的是局部子程序,即嵌套在PL/SQL块中的局部过程和函数,其存储位置取决于其所在的父块的位置。Oracle 数据库基础教程2007111存储过程存储过程p存储过程的创建p存储过程的调用p存储过程的管理Oracle 数据库基础教程2007112存储过程的创建存储过程的创建pCREATE OR REPLACE PROCEDURE procedure_namep(parameter1_name mode datatype DEFAULT|:=valuep,parameter2_name mode datatype DEFAULT|:=value,)pAS|ISp /*Declarative
42、 section is here*/pBEGINp /*Executable section is here*/pEXCEPTIONp /*Exception section is here*/pENDprocedure_name;PROCEDURE BODYOracle 数据库基础教程2007113p参数模式nIN 当过程被调用时,实参值被传递给过程。在过程内,该参数起常数 作用,可读不可写。调用结束,实参值不变。(默认参数类型)nOUT 当过程被调用时,实参值被忽略。在过程内,该参数起未初始化的变量作用,值为NULL。过程内,该参数可读可写。调用结束,形参赋给实参。nIN OUT 当过程被
43、调用时,实参值被传递给过程。在过程内,该参数起已初始化变量作用,过程内,该参数可读可写。调用结束,形参赋给实参。Oracle 数据库基础教程2007114p参数限制n声明形参时不能定义形参的长度或精度、刻度声明形参时不能定义形参的长度或精度、刻度 p参数传递nIN参数为引用传递,即实参的指针被传递给形参数为引用传递,即实参的指针被传递给形参;参;nOUT、IN OUT参数为值传递,即实参的值被参数为值传递,即实参的值被复制给形参。复制给形参。Oracle 数据库基础教程2007115p创建一个存储过程,以部门号为参数,查询该部门的平均工资,并输出该部门中比平均工资高的员工号、员工名。pCREA
44、TE OR REPLACE PROCEDURE show_emp(pp_deptno emp.deptno%TYPE)pASp v_sal emp.sal%TYPE;pBEGINpSELECT avg(sal)INTO v_sal FROM emp WHERE deptno=p_deptno;pDBMS_OUTPUT.PUT_LINE(p_deptno|average salary is:|v_sal);pFOR v_emp IN(SELECT*FROM emp WHERE deptno=p_deptno AND salv_sal)LOOPp DBMS_OUTPUT.PUT_LINE(v_em
45、p.empno|v_emp.ename);pEND LOOP;pEXCEPTIONp WHEN NO_DATA_FOUND THENp DBMS_OUTPUT.PUT_LINE(The department doesnt exists!);pEND show_emp;Oracle 数据库基础教程2007116p通常,存储过程不需要返回值,如果需要返回一个值可以通过函数调用实现。但是,如果希望返回多个值,可以使用OUT或IN OUT模式参数来实现。Oracle 数据库基础教程2007117p创建一个存储过程,以部门号为参数,返回该部门的人数和最高工资。pCREATE OR REPLACE PRO
46、CEDURE return_deptinfo(pp_deptno emp.deptno%TYPE,pp_avgsal OUT emp.sal%TYPE,pp_count OUT emp.sal%TYPE)pASpBEGINp SELECT avg(sal),count(*)INTO p_avgsal,p_count p FROM emp p WHERE deptno=p_deptno;pEXCEPTIONp WHEN NO_DATA_FOUND THENp DBMS_OUTPUT.PUT_LINE(The department dont exists!);pEND return_deptinf
47、o;Oracle 数据库基础教程2007118存储过程的调用存储过程的调用p在SQL*PLUS中调用nEXEC procedure_name(parameter_list)nEXECUTE show_emp(10)p在PL/SQL块中调用nBEGIN procedure_name(parameter_list);nEND;Oracle 数据库基础教程2007119pDECLAREp v_avgsal emp.sal%TYPE;p v_count NUMBER;pBEGINp show_emp(20);p return_deptinfo(10,v_avgsal,v_count);p DBMS_O
48、UTPUT.PUT_LINE(v_avgsal|v_count);pEND;Oracle 数据库基础教程2007120存储过程的管理存储过程的管理p修改存储过程nCREATE OR REPLACE PROCEDURECREATE OR REPLACE PROCEDUREp重新编译存储过程nALTER PROCEDURE procedure_name COMPILEALTER PROCEDURE procedure_name COMPILE;p删除存储过程nDROP PROCEDURE procedure_nameDROP PROCEDURE procedure_name名;名;p查看过程源代码
49、nselect text from user_source where name=procedure_nameprocedure_name;Oracle 数据库基础教程200712115.6.2函数函数p函数概述p函数的创建p函数的调用p函数的管理Oracle 数据库基础教程2007122函数概述函数概述p函数用于返回特定数据,可以返回一个或多个值。p在一个函数中必须包含一个或多个RETURN 语句p函数调用是PL/SQL表达式的一部分,而过程调用可以是一个独立的PL/SQL语句 Oracle 数据库基础教程2007123函数的创建函数的创建CREATE OR REPLACE FUNCTION
50、 function_name(parameter1_name mode datatype DEFAULT|:=value,parameter2_name mode datatype DEFAULT|:=value,)RETURN return_datatype AS|IS /*Declarative section is here*/BEGIN /*Executable section is here*/EXCEPTION /*Exception section is here*/END function_name;FUNCTION BODYOracle 数据库基础教程2007124p创建一个