PL/SQL块主要有两种类型,即命名块和匿名块。匿名块(以DECLARE或BEGIN开始)每次使用时都要进行编译,除此之外,该类块不在数据库中存储并且不能直接从其他的PL/SQL块中调用。过程,函数,包和触发器都属于命名块,这类构造没有匿名块的限制,它们可以存储在数据库中并在适当的时候运行。
创建子程序: PL/SQL的过程和函数的运行方式非常类似于其他3GL(第3代程序设计语言)使用的过程和函数。它们之间具有许多共同的特征属性。总起来说,过程和函数统称为子程序。两者不同的是,过程调用本身是一个PL/SQL语句,而函数调用是作为表达式的一部分执行的。
创建过程的语法如下所示:
CREATE [OR REPLACE] PROCEDURE procedure_name
[ ( argument[{IN | OUT | IN OUT}] type] {IS | AS}
/* Declarative section is here */
BEGIN
/* Executable section is here */
EXCEPTION
/* Exception section is here */
END [ procedure_name];
创建函数的语法如下所示:
CREATE [OR REPLACE] FUNCTION function_name
[( argument[{IN | OUT | IN OUT}] type]
RETURN return_type {IS | AS}
BEGIN
/* Executable section is here */
RETURN expression;
EXCEPTION
/* Exception section is here */
END [ function_name];
过程和函数的参数表都是可选的,并且函数声明部分和函数调用都没有使用括弧。然而,由于函数调用是表达式的一部分,所以函数返回类型是必须要有的。函数的类型可以用来确定包含函数调用的表达式的类型。
过程和函数的撤消: 撤消过程的语法是:DROP PROCEDURE procedure_name;
撤消函数的语法是:DROP FUNCTION function_name;
子程序参数: 子程序形参可以有三种模式:IN,OUT或IN OUT。(Oracle8i增加了NOCOPY限定符)如果没有为形参指定模式,其默认模式为IN。模式说明如下:
IN :当过程被调用时,实参的值将传入该过程。在该过程内部,形参类似PL/SQL使用的常数,即该值具有只读属性不能对其修改。当该过程结束时,控制将返回到调用环境,这
时,对应的实参没有改变。
OUT :当过程被调用时,实参具有的任何值将被忽略不计。在该过程内部,形参的作用类似没有初始化的PL/SQL变量,其值为空(NULL)。该变量具有读写属性。当该过程结束时,控制将返回调用环境,形参的内容将赋予对应的实参。(在Oracle8i中,该操作可由NOCOPY变更。)
IN OUT :该模式是模式IN和OUT的组合。当调用过程时,实参的值将被传递到该过程中。在该过程内部,形参相当于初始化的变量,并具有读写属性。当该过程结束时,控制将返回到调用环境中,形参的内容将赋予实参(在Oracle8i中与参数NOCOPY有关)。
Oracle8i提供了一个叫做NOCOPY的编译选项。使用该项声明参数的语法如下:
parameter_name [mode] NOCOPY datatype
其中parameter_name是参数名,mode是参数的模式(IN ,OUT ,IN OUT),datatype是参数的数据类型。如果使用了NOCOPY,则PL/SQL编译器将按引用传递参数,而不按值传递。当参数按引用传递时,任何对实参的修改也将引起对其对应形参的修改,这是因为该实参和形参同时位于相同的存储单元的缘故。
在某些情况下,NOCOPY将被编译器忽略,这时的参数仍将按值传递。这时,编译器不会报告编译错误。由于NOCOPY是一个提示项(Hint),编译器可以决定是否执行该项。
NOCOPY的主要优点是可以提高程序的效率。当我们传递大型PL/SQL表时,其优越性特别显著。
过程和函数有许多相同的特点: 1、通过设置OUT参数,过程和函数都可以返回一个以上的值。
2、过程和函数都可以具有声明部分、执行部分,以及异常处理部分。
3、过程和函数都可以接收默认值。
4、都可以使用位置或名称对应法调用过程和函数。
5、过程和函数都可以接受参数NOCOPY。
过程和函数的选择:
对于什么时候使用函数更合适,什么时候使用过程更有效这一问题,一般来说,过程和函数的使用与子程序将要返回的值的数量以及这些值的使用方法有关:通常,如果返回值在一个以上,用过程为好。如果只有一个返回值,使用函数就可以满足要求。尽管函数可以合法的使用参数OUT,但这种做法通常不予考虑。除此之外,函数还可以在SQL语句中调用。