in

SDT Community Server

SDT Forums, Blogs, Photos server.

wego

当心 Oracle Procedure 中的 IN 参数也会被你无意中修改了它的值

在 Oracle Procedure 中使用 IN 参数似乎很好地对该参数起到保护作用, 其实不然! 请看如下 Code

-- Spec Part 

PACKAGE TEST
IS
   g1   NUMBER;

   PROCEDURE proc1;

   PROCEDURE proc2 (p1 IN NUMBER);
END;        

-- Body Part

 PACKAGE BODY TEST
IS
   PROCEDURE proc1
   IS
   BEGIN
      g1 := 1;
      proc2 (g1);
      DBMS_OUTPUT.put_line ('g1=' || g1);
   END;

   PROCEDURE proc2 (p1 IN NUMBER)
   IS
      c1   CONSTANT NUMBER := p1;
   BEGIN
      --p1 := p1 + 1;  这句是编译不通过的, 似乎已对 IN 参数保护了.
      DBMS_OUTPUT.put_line ('p1=' || p1);
      DBMS_OUTPUT.put_line ('c1=' || c1);
      g1 := g1 + 1;  -- 这句间接地改变了 IN 参数值!
      DBMS_OUTPUT.put_line ('after p1=' || p1);   -- 已经被改了!
      DBMS_OUTPUT.put_line ('after c1=' || c1); 
   END;
END;

运行 proc1 后输出:

p1=1
c1=1
after p1=2
after c1=1
g1=2

总结:

1) 若要确保过程内任意地方都能访问到 IN 参数的初始值, 需要使用附加常量

2) 尽可能少用全局变量 (风险很大)

3) 其它非 Oracle 数据库也可能出现该情况.

 

Published Oct 08 2008, 03:29 PM by wego
Filed under:

Comments

No Comments
Copyright SDT, 2006-2009. All rights reserved.