plsql开发 NOCOPY

来源:互联网 发布:php redis went away 编辑:程序博客网 时间:2024/05/17 06:35
--==问题,使用如下代码块,看能否得到==--
/*
Word=SplitWORDS
Word=SplitWORDS
Word=SplitWORDS
Word=SplitWORDS
Word=SplitWORDS
*/
DECLARE
   c_value   VARCHAR2 (10) := 'SplitWords';
   l_value   VARCHAR2 (10);
BEGIN
   FOR indx IN 1 .. 5
   LOOP
      l_value := c_value;

      BEGIN
         plch_change_it (l_value, indx);
      EXCEPTION
         WHEN OTHERS
         THEN
            NULL;
      END;

      DBMS_OUTPUT.put_line ('Word=' || L_value);
   END LOOP;
END;
/

--============================================
NOCOPY 核心概念:常规模式下,plsql的参数传递都是将值复制一份传入到代码块内部使用,即进行值传递。
如果在参数声明的时候声明了 NOCOPY,则是将实参直接传入代码块使用,而非传递实参的拷贝,即引用传递。
感觉类似指针,传一个地址进去。当然一些比较大的对象作为参数的话,拷贝的代价太大的情况下,也会默认采用引用传递。
引用传递时,代码块内部和外部操作的是同一个对象,只要内部发生改变,外部也会立刻感应到这个改变
--参数为:IN OUT模式
--当过程抛出未经处理的异常,对value_io参数所做的修改并不会被“回滚”,因为用的是NOCOPY参数。
CREATE OR REPLACE PROCEDURE plch_change_it (
   value_io   IN OUT NOCOPY VARCHAR2,
   nth_in     IN            PLS_INTEGER)
IS
BEGIN
   value_io :=
      SUBSTR (value_io, 1, 5) || UPPER (SUBSTR (value_io, 6));

   IF MOD (nth_in, 2) = 0
   THEN
      RAISE VALUE_ERROR;
   END IF;
END;
/
输出结果:
Word=SplitWORDS
Word=SplitWORDS
Word=SplitWORDS
Word=SplitWORDS
Word=SplitWORDS



--参数为 OUT 模式,并非 IN OUT模式,所以无法将字符串“SplitWords”传入并对其进行操作。
-- value_io参数的模式是OUT, 所以传入的值被忽略。value_io的值被初始化为NULL并且一直都是那样。
CREATE OR REPLACE PROCEDURE plch_change_it (
   value_io      OUT NOCOPY VARCHAR2,
   nth_in     IN            PLS_INTEGER)
IS
BEGIN
   value_io :=
      SUBSTR (value_io, 1, 5) || UPPER (SUBSTR (value_io, 6));

   IF MOD (nth_in, 2) = 0
   THEN
      RAISE VALUE_ERROR;
   END IF;
END;
/
输出结果:
Word=
Word=
Word=
Word=
Word=

--进行的是值传递,直到nth_in为5时异常部分才被执行,则第5次不能得到期望值,
--(值传递,在    抛出异常的情况下,不会将在代码块内部发生改变的拷贝传递出去)。
--如果不使用NOCOPY, 那么IN OUT参数是以值而非以指针传输的,所以当过程失败,
--所有对value_io参数所做的修改将会被“回滚”。
CREATE OR REPLACE PROCEDURE plch_change_it (
   value_io   IN OUT VARCHAR2,
   nth_in     IN     PLS_INTEGER)
IS
BEGIN
   value_io :=
      SUBSTR (value_io, 1, 5) || UPPER (SUBSTR (value_io, 6));

   IF MOD (nth_in, 5) = 0
   THEN
      RAISE VALUE_ERROR;
   END IF;
END;
/
输出结果:
Word=SplitWORDS
Word=SplitWORDS
Word=SplitWORDS
Word=SplitWORDS
Word=SplitWords

0 0
原创粉丝点击