请调试以下ORACLE SQL过程

时间:2013-06-03 07:29:46

标签: sql oracle stored-procedures

当我在oracle SQL Developer上运行以下过程时

create or replace
Procedure Table_Update

IS
   s_id VARCHAR2(256 byte);

   CURSOR C1 IS
   SELECT A.SR_ID
   FROM TABLE_2 B,TABLE_1 A
   WHERE A.Primary_key=B.Primary_Key;

BEGIN
loop
   open c1;
   fetch c1 into s_id;

   exit when C1%NOTFOUND ;

   update TABLE_2 set SR_ID = s_id;       

   commit;

   END LOOP;

 CLOSE C1;
END;

table_1和table_2具有相似的结构。我的要求是来自table_1的SR_ID应该根据匹配的主键更新到table_2。当我运行该过程时,我收到以下错误消息

Connecting to the database XXX.
ORA-06511: PL/SQL: CURSOR ALREADY OPEN
ORA-06512: at "Table_Update", line 7
ORA-06512: at "Table_Update", line 13
ORA-06512: at line 2
PROCESS EXITED.
Disconnecting from the database XXX.

我一遍又一遍地试着帮助我

谢谢

3 个答案:

答案 0 :(得分:4)

正如罗杰已经说过的那样:将光标的开口移到循环外面。

但同样重要的是:不要在循环中提交。这会使事情变得更慢,给数据库带来更多压力,也会关闭光标。

但更重要的是:你根本不需要循环。您可以在单个更新语句中执行此操作:

update TABLE_2 
   set SR_ID = (select a.sr_id 
                from table_1 a 
                where a.primary_key = table_2.primary_key);  

或者使用merge声明:

merge into table_2 
using table_1 a
   on (table_2.primary_key = a.primary_key)
when matched then update 
  set sr_id = a.sr_id;

比基于光标的方法快得多。

这是一个SQLFiddle:http://sqlfiddle.com/#!4/0b810/1

答案 1 :(得分:3)

open c1;移到循环之外,您只需打开一次。

答案 2 :(得分:1)

您需要在open c1;之前移动loop 每次循环时都打开光标,你应该只打开一次光标。

更多信息http://www.techonthenet.com/oracle/cursors/