Oracle Database 10g基础教程 清华大学出版社 第14章 过程、函数和程序包 教学目标 教学难点和重点 教学过程 2019年5月4日
教学目标 理解和掌握过程、函数和程序包的基本概念和特点 理解在过程中使用输入和输出参数的特点 了解函数和过程的区别和联系 理解和掌握程序包的结构的特点 理解和掌握程序包的规范 2019年5月4日
教学难点和重点 过程、函数和程序包的基本概念和特点 在过程中使用输入和输出参数 函数和过程的区别和联系 程序包的结构 程序包的规范 2019年5月4日
教学过程 14.1 概述 14.2 过程 14.3 函数 14.4 程序包 2019年5月4日
14.1 概述 使用过程、函数和程序包代替PL/SQL程序块由许多好处,例如增强可扩展性、提高模块化水平、可重用性增强、可维护性加强、有利于抽象和数据隐藏、增强安全性等。 2019年5月4日
14.2 过程 从本质上来看,过程就是命名的PL/SQL程序块,它可以被赋予参数,存储在数据库中,然后由另外一个应用或PL/SQL例程调用。 14.2 过程 从本质上来看,过程就是命名的PL/SQL程序块,它可以被赋予参数,存储在数据库中,然后由另外一个应用或PL/SQL例程调用。 下面,详细讲述过程的创建、执行、安全、使用参数等内容。 2019年5月4日
创建或替换 [create [or replace]] procedure procedure_name[(parameter[, parameter]…)] [authid {definer | current_schema}]{is | as} [pragma autonomous_transaction;] [local_declarations] begin executable statements [exception exception handlers] end [procedure_name]; 2019年5月4日
执行过程 过程创建之后,就可以执行了。用户既可以从匿名PL/SQL程序块中直接调用,也可以在SQL*Plus中使用execute函数来执行。 execute函数可以简写为exec。 2019年5月4日
使用参数 过程可以进行参数化处理。参数可以是任意合法的PL/SQL类型。参数可以有3种模式,即in、out和in out。 in参数是输入参数,需要通过调用者传入,只能由过程来读取。也就是说,他们是只读值。这是参数行为中最常使用的模式,是没有给出参数模式指示器时的默认模式。in参数可以具有默认值,因此调用者不一定必须为其提供指定值。 out参数是输出参数,能够由过程写入。该参数适合用于过程向调用者返回多个信息。out参数没有默认值,也不能是常量或表达式,必须向out参数传递返回值。 in out参数同时具有in参数和out参数的特性,过程可以读取和写入他们的值。 2019年5月4日
局域声明 如同匿名PL/SQL程序块一样,过程也可以定义局域变量。这些定义紧随可选的参数列表之后。在匿名PL/SQL程序块中,它使用declare保留字开始。在过程声明中,由于使用了create or replace语法,所以不必再使用declare保留字了。在前面的swap过程示例中,l_temp就是一个局域变量。 除了局域变量之外,在局域声明部分还可以定义其他许多内容。用户可以定义记录、类型、数组,甚至还可以是其他过程。 2019年5月4日
14.3 函数 函数与过程非常类似,也是数据库中存储的命名PL/SQL程序块。创建函数与创建过程,都遵循同样的规则。函数与过程的安全方式和参数传递也相同。函数的主要特征是它必须返回一个值。这个返回值既可以是number或varchar2这样简单的数据类型,也可以是PL/SQL数组或对象这样复杂的数据类型。 2019年5月4日
语法 [create [or replace]] function function_name [(parameter[, parameter]…)] return datatype [authid {definer | current_schema}] [parallel_enable] [deterministic] {is | as} [pipelined [using implementation_type]] [aggregate [update value] {with external context} using implementation_type] [pragma autonomous_transaction;] [local declarations] begin executable statements [exception exception handlers] end [name]; 2019年5月4日
返回值 定义过程和定义函数的主要区别之一是,定义函数必须使用return子句返回数据。在定义函数的函数体中的任何地方,用户都可以return <expresson>;子句。 注意,这里的expression表达式要等于return数据类型。 图14-25是一个创建函数的示例。 2019年5月4日
确定性 如果对于给定的输入,函数总是会返回完全相同的结果,那么就称该函数具有确定性。例如,upper()函数具有确定性。如果向其输入Oracle Database 10g,那么它就返回ORACLE DATABASE 10G的结果。如果函数不能每次都返回相同的值,用户就不能将其作为确定性函数建立。 为了提示函数具有确定性,用户可以按照如图14-28所示的示例那样执行。 2019年5月4日
常见错误 根据经验,用户在开发函数时,经常会碰到下面一些错误: 忘记获取返回值; 试图定义不能返回值的函数; 定义没有返回数据类型的函数。 了解这些错误的形式将会帮助用户避免这些问题,并且可以在出现错误时快速修正他们。下面,通过几个示例讲述这些常见的错误。 2019年5月4日
14.4 程序包 程序包可以允许用户从逻辑上组织过程、函数、对象类型等各种内容。程序包通常由2部分组成:规范和主体。 14.4 程序包 程序包可以允许用户从逻辑上组织过程、函数、对象类型等各种内容。程序包通常由2部分组成:规范和主体。 规范是程序包的公共接口。 主体则包含了规范的实现以及所有私有例程、数据和变量。 本节讲述有关程序包的内容。 2019年5月4日
语法 如同函数一样,这里展示了定义程序包的完整语法。但是,限于篇幅,就不深入讨论所有的参数特性了。 定义程序包规范的语法如P320页所示 2019年5月4日
规范 程序包规范是程序包的接口。在规范中定义的所有内容都可以由调用者使用,并且可以由具有这个程序包execute权限的用户使用。在规范中定义的过程可以被执行,变量也可以被引用,类型能够被访问。这些是程序包的公共特性。 在如图14-32所示的示例中,我们将要使用两个过程print_ename()和print_sal(),定义一个被称为employee_pkg的程序包。 2019年5月4日
主体 程序包主体是用户实际编写的子例程,实现规范中定义的接口。规范中显示的所有过程和函数都必须在主体中实现。 在如图14-34所示的示例中,显示了如何实现employee_pkg程序包中的print_ename过程和print_sal过程。 2019年5月4日
程序包变量和其他声明 用户可以定义程序包的全局变量。这些变量既可以定义在程序包规范中,也可以定义在程序包的主体中。 定义在规范中的那些变量可以象规范中的过程和函数一样被引用,他们被称为公共变量。这些变量可以被任何具有程序包上execute权限的用户读取和修改。 在主体中定义的程序包级别的变量只能由主体中的过程实现来访问,这些变量被称为私有变量。 2019年5月4日