一、In、out、in out模式
在Oracle中过程与函数都可以有参数,参数的类型可以指定为in、out、in out三种模式。
三种参数的具体说明,如下图所示:
(1)in模式
in模式是引用传递。调用过程时实际参数将值以引用方式传递给存储过程的形式参数,形式参数在过程中是只读模式的,也就是说:只能通过形式参数读取到实际参数的值。当过程执行完毕后,实际参数的值不会发生任何变化。
过程:
create or replace procedure MyProcedure(param1 in INTEGER) --param1形式参数
AS
BEGIN
……..
END
调用:
num:=100;
MyProcedure(num); --num 实际参数
分析:
实际参数num将其值100传递给过程的形式参数param1,param1的值变为100,过程执行完后返回到调用过程的语句,实际参数num的值不会发生任何变化。
(2)out模式
out模式是值传递。调用过程的时候,形式参数会忽略实际参数的值,而被初始化为null值,形式参数是可读写的,所以在过程中形式参数的值可以被修改,过程执行完毕后,形式参数会将其值赋值给实际参数。
过程
create or replace procedure MyProcedure(param1 out INTEGER) --param1形式参数
AS
BEGIN
DBMS_OUTPUT.PUT_LINE(param1); --param1为null
param1:=1; --修改param1的值为1
END
调用:
num:=100;
MyProcedure(num); --num 实际参数
分析:
实际参数并不能将其值传给过程的形式参数,相反过程的形式参数的初始值为null,等过程执行完后param1的值变为1,过程返回时将形式参数的值赋值给实际参数,所以num的值从100变为了1;
(3)in out模式
in out模式是值传递的。调用过程的时候,实际参数的值会以值传递的方式赋值给形式参数,在过程中形式参数的值可以被修改,等过程执行完毕后,形式参数又会将其值赋值给实际参数。
过程:
create or replace procedure MyProcedure(param1 in out INTEGER) --param1形式参数,能接受实际参数传来的值
AS
BEGIN
DBMS_OUTPUT.PUT_LINE(param1); --param1为null
param1:=1;
END
调用:
num:=100;
MyProcedure(num); --num 实际参数
分析:
实际参数num将其值100传递给过程的形式参数param1,param1的值初始化为100,过程执行中param1的值变为1,等过程执行完毕返回时又将形式参数param1的值赋值给了实际参数num,所以num的值从100变为了1;
将字面值或常量当作实际参数,由于存在值的复制。所以与out或in out模式的形式参数相关联的实际参数必须是一个变量,而不能是一个常量或表达式。必须有一个可以存储返回值的位置。
out模式和in out模式的主要区别就是:in out模式能将实际参数的值传递给过程的形式参数,out模式的形式参数的初始值只能为null。
二、传值和传引用
默认情况下,缺省为in模式,in接收常量、变量、表达式,out/in out只能接受变量。
引用传递的方式效率比较高,传递大型PL/SQL数组时表现尤为突出。
IN | OUT | IN OUT |
---|---|---|
The default | Must be specified | Must be specified |
Passes values to a subprogram | Returns values to the caller | Passes initial values to a subprogram and returns updated values to the caller |
Formal parameter acts like a constant | Formal parameter acts like an uninitialized variable | Formal parameter acts like an initialized variable |
Formal parameter cannot be assigned a value | Formal parameter must be assigned a value | Formal parameter should be assigned a value |
Actual parameter can be a constant, initialized variable, literal, or expression | Actual parameter must be a variable | Actual parameter must be a variable |
Actual parameter is passed by reference (a pointer to the value is passed in) | Actual parameter is passed by value (a copy of the value is passed out) unless NOCOPY is specified | Actual parameter is passed by value (a copy of the value is passed in and out) unless NOCOPY is specified |
NOCOPY提示
·in模式总是以引用方式传递参数,所以不允许在in模式上使用NOCOPY提示;
·out、in out模式可以通过NOCOPY关键字来告诉PL/SQL编译器采用引用方式来传递参数值;NOCOPY只是一个编译器提示,而不是编译指令,所以它并不是总是有效;
·以下几种情况会忽略NOCOPY的存在,如下图所示: