关于oracle中的ORA-01002:提取违反顺序
一.oracle文档中的描述:Action: 1) Do not issue a fetch statement after the last row has been retrieved - there are no more rows to fetch. 
                               2) Do not issue a COMMIT inside a fetch loop for a cursor that has been opened FOR UPDATE. 
                               3) Reexecute the statement after rebinding, then attempt to fetch again
二:测试及我的问题
    Action:1   是不是说当取得游标最后一个记录后,如果还接着取记录,就会出这个错误,如果是的话,我测试一下,为什么不报错.................
        测试:DECLARE
                  V_NUM INTEGER:=1;
                  N INTEGER;
                  T_COUNT INTEGER;
                  CURSOR EMP_CURSOR IS SELECT NUM FROM TEST FOR UPDATE;
              BEGIN
                  SELECT COUNT(*) INTO T_COUNT FROM TEST; 
                  OPEN EMP_CURSOR;
                  WHILE V_NUM<T_COUNT+5 LOOP
                  FETCH EMP_CURSOR INTO N;
                  DBMS_OUTPUT.put_line(SQLCODE||','||sqlerrm);
                   IF N>10 THEN 
                   UPDATE TEST SET NUM=9 WHERE CURRENT OF EMP_CURSOR;
                   END IF;
                   DBMS_OUTPUT.put_line('第'||V_NUM||'个V_NUM');
                   V_NUM:=V_NUM+1;
                   END LOOP;
                   COMMIT;
                   CLOSE EMP_CURSOR;
              END;
           
    
    Action:2   a.不能在for update的游标循环中写COMMIT,那COMMIT是不是写在 循环结束的后面(END LOOP;的后面)??????、
               b.如果在for update的游标循环中调用其他的储存过程,如果其他储存过程 COMMIT或出错ROLLBACK 就报ORA-01002:提取违反顺序,
                 这个问题该怎么解决???????
        b的测试:储存过程TEST1(V_NUM IN INTEGER,OUT_SQLCODE OUT INTEGER,OUT_MSG OUT VARCHAR2) 它的关键代码如下:
                 BEGIN
                  DBMS_OUTPUT.put_line('输出RESULT:'||V_NUM/V_NUM);
                  EXCEPTION
                      WHEN OTHERS THEN
                         OUT_SQLCODE:=SQLCODE;
                         OUT_MSG:=SQLERRM;
                         ROLLBACK;
                         RETURN;
                  END;
                 
                 现在写个匿名块 用到表 TEST (num integer)注:TEST表中有多个0记录。代码如下:
                 DECLARE 
                     OUT_SQLCODE INTEGER;
                     OUT_MSG VARCHAR2(100);
                     N INTEGER;
                     CURSOR P_CURSOR IS SELECT NUM FROM TEST FOR UPDATE NOWAIT;
                BEGIN
                     OPEN P_CURSOR;
                     LOOP
                     FETCH P_CURSOR INTO N;
                     EXIT WHEN P_CURSOR%NOTFOUND ;
                     TEST1(N,OUT_SQLCODE ,OUT_MSG );
                     --commit;
                     END LOOP;
                     COMMIT;
                     CLOSE P_CURSOR;
                END;
             因为TEST表中有0记录,在执行存储过程会ROLLBACK,就会出错!如果在储存过程中加了INSERT 或DELETE 子句后COMMIT也不报错!
             这个问题如何解决??????????????
   Action3:  英语不好,翻译不了!什么重新捆绑后重新执行......搞不懂! 请高手指教????????
                 

解决方案 »

  1.   

    action 1 里面,你的  %NOTFOUND 呢?
    是不是这个 WHILE V_NUM<T_COUNT+5 LOOP 当 V_NUM > T_COUNT 后出错了?
      

  2.   

    我的意思是想让它 V_NUM > T_COUNT 后出错 可是程序不报错!运行到大于游标总记录后还可以运行!
    为什么不报错呢???ORACLE中
    Do not issue a fetch statement after the last row has been retrieved - there are no more rows to fetch.  
    这句话怎么不管用呢????