2015-08-19 3 views
1

У меня есть следующий код:PLSQL «ошибка Курсор уже открыт»

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, это говорит мне, что курсор уже открыт?

ответ

6

Вы открываете курсор:

open cur; 

, а затем, не закрывая его, вы открываете снова в цикле курсора:

«для петли курсора» конструкция открывает курсор первой. Не нужно открывать его заранее. Смотрите documentation:

«Курсор для LOOP заявления неявно объявляет свой индекс цикла как запись переменные типа строки, что указанный курсор вернется, а затем открывает курсор»

3

Два пути для использования Cursor:

  1. OPEN; FETCH INTO; CLOSE;
  2. FOR I IN C1;

СПОСОБ 1: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. 
Смежные вопросы