Eu queria descobrir se era possível evitar o uso do cursor para iterar as linhas da tabela em PL/SQL e tentei o seguinte script:
set serveroutput on;
declare
v1 tbl_plant.plant_id%type := 0; -- number(10,0)
v2 tbl_plant.name%type := ''; -- varchar2(50)
begin
while true
loop
select plant_id, name
into v1, v2
from tbl_plant
where rownum = 1
and plant_id > v1
order by plant_id;
exit when sql%rownum = 0;
dbms_output.put_line(v1 || v2);
end loop;
end;
Então, percebi que o compilador otimiza isso em um cursor implícito quando o while
loop é usado e tentei contornar:
set serveroutput on;
declare
v1 tbl_plant.plant_id%type := 0;
v2 tbl_plant.name%type := '';
begin
<<divein>>
select plant_id, name
into v1, v2
from tbl_plant
where rownum = 1
and plant_id > v1
order by plant_id;
if sql%rownum = 0 then
goto bailout;
end if;
dbms_output.put_line(v1 || v2);
goto divein;
<<bailout>>
null;
end;
Mas em ambos os casos, recebi exatamente o mesmo erro:
PLS-00207: identifier 'ROWNUM', applied to implicit cursor SQL, is not a legal cursor attribute
Mas se eu comentasse while
ou goto
e os rótulos, eliminando qualquer tipo de loop, o mesmo select funcionava bem e retornava o primeiro id/nome tbl_plant
por ID da planta.
É possível iterar sem usar um cursor?
O nome válido do atributo do cursor é
%NOTFOUND
,%FOUND
,%ROWCOUNT
,%ISOPEN
. Não há nenhum%rownum
atributo. Em sua pergunta, você usa cursores implícitos, portanto, deve sersql%rowcount
.