ITPub博客

首页 > 数据库 > Oracle > PLSQL Language Reference-PL/SQL子程序-子程序参数-子程序参数模式

PLSQL Language Reference-PL/SQL子程序-子程序参数-子程序参数模式

原创 Oracle 作者:LuiseDalian 时间:2014-03-29 08:36:27 0 删除 编辑

子程序参数模式

形参的模式决定了它的行为。

IN

OUT

IN OUT

默认模式

必须指定

必须指定

给子程序传递值

返回值给调用者

传递初始值给子程序,返回更新的值给调用者

形参行为类似于常量,当子程序开始,它是值就是实参的值或默认值,且子程序不能改变它的值

像一个未初始化的变量,当子程序开始值,它的值为NULL,不管的它的实参的值是多少。Oracle建议子程序对它赋值。

像一个初始化的变量,子程开始时,它的值为实参的值。Oracle建议子程序更新它的值

实参可以是常量、初始化的变量、字面量、表达式

实参必须为变量,且它的数据类型不能指定NOT NULL

实参必须为变量,通常为字符串缓冲区或数字累加器

引用传递

默认为值传递,如果指定NOCOPY,则可能是引用传递

默认为双向值传递,如果指定NOCOPY,则可是能引用传递。

技巧:不要对函数的参数使用OUTIN OUT模式。理想状态是函数有0或多个参数,只返回一个值。带有IN OUT的参数返回多个值,有副作用。

注意Oracle数据库提供的许多包和类型的下定义使用了下面的符号和声明形参:

i1 IN VARCHAR2 CHARACTER SET ANY_CS

i2 IN VARCHAR2 CHARACTER SET i1%CHARSET

当声明自己的形参和实参的时候,不要使用这种符号,因为这是对于Oacle提供的包类型的实现保留的。

 

OUTIN OUT参数是通过值传递的

n  如果子程序成功退出,则形参的值被赋值给实参。

n  如果子程序因为未处理的异常而结束,则形参的值不赋给实参,实参保留在调用子程序之前的值。

OUT, IN OUT参数是通过引用传递的,实参和形参引用相同的内存分配,因此如果子程序改变了形参的值,则改变会立即在实参中显现出来。

-- 参数在过程调用之前、之中和之后的值

CREATE OR REPLACE PROCEDURE print (x PLS_INTEGER) IS

BEGIN

    IF x IS NOT NULL THEN

        DBMS_OUTPUT.PUT_LINE(x);

    ELSE

        DBMS_OUTPUT.PUT_LINE('NULL');

    END IF;

END print;

/

CREATE OR REPLACE PROCEDURE p (

    a        PLS_INTEGER,  -- 默认为IN

    b     IN PLS_INTEGER,

    c    OUT PLS_INTEGER,

    d IN OUT BINARY_FLOAT

) IS

BEGIN

    DBMS_OUTPUT.PUT_LINE('在过程P内部:');

    DBMS_OUTPUT.PUT('IN a = '); print(a);               --1         1

    DBMS_OUTPUT.PUT('IN b = '); print(b);               --2         20

    DBMS_OUTPUT.PUT('OUT c = '); print(c);              --NULL      NULL

    DBMS_OUTPUT.PUT_LINE('IN OUT d = ' || TO_CHAR(d));  --4.0E+000  5.0E+000

 

    -- 可以引用IN类型的参数a, b,但不能对它们赋值

    c := a + 10;   -- out参数赋值

    d := 10 / b;   -- in out参数赋值

END;

/

 

DECLARE

    aa  CONSTANT PLS_INTEGER := 1;

    bb  PLS_INTEGER  := 2;

    cc  PLS_INTEGER  := 3;

    dd  BINARY_FLOAT := 4;

    ee  PLS_INTEGER;

    ff  BINARY_FLOAT := 5;

BEGIN

    DBMS_OUTPUT.PUT_LINE('调用过程P之前:');

    DBMS_OUTPUT.PUT('aa = '); print(aa);           --1

    DBMS_OUTPUT.PUT('bb = '); print(bb);           --2

    DBMS_OUTPUT.PUT('cc = '); print(cc);           --3

    DBMS_OUTPUT.PUT_LINE('dd = ' || TO_CHAR(dd));  --4.0E+000

 

    p (aa, -- 常量

        bb, -- 初始化变量

        cc, -- 初始化变量

        dd  -- 初始化变量

    );

 

    DBMS_OUTPUT.PUT_LINE('在调用P之后:');

    DBMS_OUTPUT.PUT('aa = '); print(aa);            --1

    DBMS_OUTPUT.PUT('bb = '); print(bb);            --2

    DBMS_OUTPUT.PUT('cc = '); print(cc);            --11

    DBMS_OUTPUT.PUT_LINE('dd = ' || TO_CHAR(dd));   --5.0E+000

 

    DBMS_OUTPUT.PUT_LINE('在调用P之前:');

    DBMS_OUTPUT.PUT('ee = '); print(ee);            --NULL

    DBMS_OUTPUT.PUT_LINE('ff = ' || TO_CHAR(ff));   --5.0E+000

 

    p (1,               -- 字面量                  

        (bb + 3) * 4,   -- 表达式

        ee,             -- 未初始变量

        ff              -- 初始化变量

        );

 

    DBMS_OUTPUT.PUT_LINE('调用P之后:');

    DBMS_OUTPUT.PUT('ee = '); print(ee);             --11

    DBMS_OUTPUT.PUT_LINE('ff = ' || TO_CHAR(ff));    --5.0E-001

END;

/

 

--因为未处理的异常子程序结束, OUT, IN OUT参数

DECLARE

    j  PLS_INTEGER  := 10;

    k  BINARY_FLOAT := 15;

BEGIN

    DBMS_OUTPUT.PUT_LINE('调用P之前:');

    DBMS_OUTPUT.PUT('j = '); print(j);

    DBMS_OUTPUT.PUT_LINE('k = ' || TO_CHAR(k));

 

    p(4, 0, j, k);  -- 致使PZERO_DIVID异常退出

 

EXCEPTION

    WHEN ZERO_DIVIDE THEN

        DBMS_OUTPUT.PUT_LINE('调用P之后:');

        DBMS_OUTPUT.PUT('j = '); print(j);

        DBMS_OUTPUT.PUT_LINE('k = ' || TO_CHAR(k));

END;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17013648/viewspace-1131974/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2012-02-06

  • 博文量
    1986
  • 访问量
    5568223