PLSQL“错误光标已打开”

Posted

技术标签:

【中文标题】PLSQL“错误光标已打开”【英文标题】:PLSQL "error Cursor already open" 【发布时间】:2015-08-19 20:06:31 【问题描述】:

我有以下代码:

DECLARE 
  f_cd fee.fee_cd%type;
  f_name fee.fee_nm%type; 
  f_new_cd fee.new_fee_cd%type;
  f_new_name fee.new_fee_nm%type;

  Cursor cur is
    SELECT Fee_cd, fee_nm, new_fee_cd, new_fee_nm FROM Fee;
BEGIN
  if cur%ISOPEN then
    close cur;
  end if;

  open cur;

  for rec in cur loop
    fetch cur INTO f_cd, f_name, f_new_cd, f_new_name;
    dbms_output.put_line ('The Fee Code ' || f_cd
                          || ' is the one you selected and it''s name is '
                          || f_name);
  end loop;

  close cur;
END;

但我不断收到错误消息

原因:试图打开一个已经打开的游标。

操作:在重新打开之前先关闭光标。

我不知道发生了什么。当我更改代码以删除 for loop 并仅使用 loop... end loop 结构时,它可以工作。功能代码如下:

loop
  fetch cur INTO f_cd, f_name, f_new_cd, f_new_name;
  dbms_output.put_line ('The Fee Code ' || f_cd
                        || ' is the one you selected and it''s name is '
                        || f_name);    
  exit when cur%notfound;
end loop;

close cur;
END;

为什么当我使用 for 循环时它告诉我光标已经打开?

【问题讨论】:

【参考方案1】:

您正在打开光标:

open cur;

然后不关闭它,在游标循环中再次打开:

for rec in cur loop

“for cursor loop”构造首先打开游标。无需事先打开它。见documentation:

"游标FOR LOOP语句将其循环索引隐式声明为指定游标返回的行类型的记录变量,然后打开游标。"

【讨论】:

【参考方案2】:

Cursor的两种使用方式:

    OPEN ; FETCH INTO;CLOSE; FOR I IN C1;

方法一: OPEN C1; LOOP ; FETCH C1 INTO ; END LOOP; CLOSE C1;

DECLARE
v_code_id   your_users.cod_id%type;  
v_code_user your_users.cod_user%type ;
cursor C_users is select cod_id,cod_user from your_users where 1=1; 
BEGIN
OPEN C_users;  --opening cursor
loop
Fetch C_users into v_code_id,v_code_user; -- Fetching from Cursoe
exit when C_users%NOTFOUND;
DELETE from your_users WHERE cod_emp  IN (v_code_id);
dbms_output.put_line( 'USER : ' || ' ' ||  v_code_user || ' is deleted.' );
End Loop;
commit;
Close C_users ; --Closing Cursor
END;

输出:

USER :  mahi is deleted.
USER :  xyz is deleted.

Statement processed.

方法2: FOR i in C1; LOOP ; END LOOP

DECLARE
cursor C_users is
 select cod_id,cod_user from your_users where 1=1; 
BEGIN
For rec in C_users 
loop
 DELETE from your_users WHERE cod_emp  IN (rec.cod_id );
 dbms_output.put_line( 'USER : ' || ' ' ||  rec.cod_user || ' is deleted.' );
End Loop;
commit;
END;

输出:

USER :  xyz is deleted.
USER :  mahi is deleted.

【讨论】:

以上是关于PLSQL“错误光标已打开”的主要内容,如果未能解决你的问题,请参考以下文章

plsql导出csv数据是空白

通过 PLSQL 打开文本文件而不创建目录

如何使用 PLSQL 打开、读取和存储 XLSX 文件的 DB 内容?

plsql异常关闭后恢复sql

怎么用plsql导入dmp文件

PLSQL配置怎么连ORACLE