过程和函数都是命名块,可以一次定义,多次调用。函数和过程的使用显著的改善了代码的可重用性,增加了可维护性。
#过程
过程是执行特定的任务(动作)的命名块。过程封装了业务逻辑,随后在应用层和数据层都可调用之前已经定义的过程。
CREATE [OR REPLACE] PROCEDURE [schema.]name[( parameter [IN] [OUT] data_type [DEFAULT default_value] [, parameter [IN] [OUT] data_type...] ) ]
[AUTHID DEFINER | CURRENT_USER]
IS
[--declarations statements]
BEGIN
--executable statements
[ EXCEPTION
---exception handlers]
END [name];
在IS之前的部分叫做过程的头部,即过程的签名。
-
参数列表中参数的有三种模式,IN,OUT,INOUT。IN代表参数为只读参数,如果在对该参数修改,编译器将会报错;OUT代表只写参数,OUT参数用于返回数据到调用者,当过程执行时,无论之前OUT参数本来是什么值,它都会被初始化为对应类型的默认值;IN OUT表示参数为可读可写参数,过程内部可以读取参数的值,也可以改变参数的值返回给调用者,DEFAULT default_value 指明参数的默认值,如果调用时没有实际的参数值传递,则会使用默认值
-
AUTHID DEFINER | CURRENT_USER可选部分用于指定当前过程执行时是用过程所有者的权限还是执行时的当前用户的权限
在IS之后的部分为过程体,结构和匿名块很相似。
调用方式:
BEGIN
--no parameter
procedure_name;
--or
procedure_name();
--with position parameter
procedure_name(parameter_value,...);
--with named parameter
procedure_name(parameter_name => parameter_value,...);
--with position parameter and named parameter
procedure_name(parameter_value, parameter_name => parameter_value,...);
END;
##Hello World
CREATE OR REPLACE PROCEDURE
hello_place (place_in IN VARCHAR2)
IS
l_message VARCHAR2 (100);
BEGIN
l_message := 'Hello ' || place_in;
DBMS_OUTPUT.put_line (l_message);
END hello_place;
#函数
函数用于计算然后返回一个值。函数和过程在结构上很类似,不同之处在于函数会通过RETURN返回值。在函数签名部分,通过RETURN DATATYPE声明返回的数据类型,在函数体中通过RETURN DATA返回结果DATA,类型为DATATYPE。
CREATE [OR REPLACE] FUNCTION [schema.]name[( parameter [IN] [OUT] data_type[, parameter [IN] [OUT] data_type...] ) ]
RETURN DATATYPE
[AUTHID DEFINER | CURRENT_USER]
IS
[--declarations statements]
BEGIN
--executable statements
RETURN DATA;
[ EXCEPTION
---exception handlers]
END [name];
调用方式:
函数的调用方式和过程一样,此外由于函数返回数据,所以可以用于赋值,也可以直接用于SQL中。
DECLARE
variable RETURNDATATYPE;
BEGIN
variable := function_name();
variable := function_name(parameter...);
INSERT INTO table VALUES (function_name(parameter...));
END;
##Hello World
CREATE OR REPLACE FUNCTION
hello_message
(place_in IN VARCHAR2)
RETURN VARCHAR2
IS
BEGIN
RETURN 'Hello ' || place_in;
END hello_message;
#命名
对变量的命名规则同样适用于过程和函数以及其他数据库对象。不同点在于对于不是用双引号声明的标识符,数据库都是以大写的形式处理对待的。
CREATE OR REPLACE PROCEDURE
hello_world
IS
BEGIN
DBMS_OUTPUT.put_line
('Hello World!');
END hello_world;
上述过程在数据库中的名字将是“HELLO_WORLD”,该过程可以被如下调用:
BEGIN
hello_world;
HELLO_WORLD;
"HELLO_WORLD";
END;
但却不能被如此调用:
BEGIN
"hello_world";
END;