The following code is setting the variable vBoleto to null when the select above return no rows. Can someone explain why please?
Sometimes vBoleto wont return rows from sn_grupo_contestacao
, so I need to get the id_boleto_origem
from the last vBoleto found in the sn_boleto
table.
Here's the full code:
declare
--20120807
vContrato sn_contrato.num_contrato%type := 18111110;
vCid sn_contrato.cid_contrato%type := '05509';
vBoleto sn_boleto.id_boleto%type := 82452735;
vOrigem sn_boleto.id_boleto%type;
vGrupoCont sn_grupo_contestacao.id_grupo_contestacao%type;
vParceiro sn_grupo_contestacao.id_parceiro%type;
vTot number := 0;
vStatus number := 0;
begin
--- esboço ih - contestação com itens de outras cobrancas
select id_grupo_contestacao, id_parceiro
into vGrupoCont, vParceiro
from sn_grupo_contestacao
where id_boleto = vBoleto
and fc_situacao_grupo = 'P'
and num_contrato = vContrato
and cid_contrato = vCid;
exception
when no_data_found then
while true loop
begin
select id_boleto_origem
into vOrigem
from sn_boleto
where id_boleto = vBoleto;
vBoleto := vOrigem;
exception
when no_data_found then
exit;
end;
end loop;
end;
答案 0 :(得分:0)
The variable isn't being set to null when no data is found, it's being done on the previous iteration of the loop.
Lets say you have a simple structure:
create table sn_boleto (id_boleto number, id_boleto_origem number);
insert into sn_boleto values (1, null);
insert into sn_boleto values (2, 1);
insert into sn_boleto values (3, 1);
insert into sn_boleto values (82452735, 2);
Your first time around the loop:
select id_boleto_origem
from sn_boleto
where id_boleto = 82452735;
ID_BOLETO_ORIGEM
---------------------------------------
2
So you set your vBoleto variable to 2 and repeat:
select id_boleto_origem
from sn_boleto
where id_boleto = 2;
ID_BOLETO_ORIGEM
---------------------------------------
1
You set your vBoleto variable to 1 and repeat:
select id_boleto_origem
from sn_boleto
where id_boleto = 1;
ID_BOLETO_ORIGEM
---------------------------------------
(null)
You have not got a no_data_found
yet, so you still set your vBoleto variable to null; and repeat:
select id_boleto_origem
from sn_boleto
where id_boleto = null;
no rows selected
Now you get no_data_found
, but it's too late, you've already set vBoleto
to null.
You could avoid this by breaking out of the loop earlier, based on the value you did get rather than waiting for the exception:
select id_boleto_origem
into vOrigem
from sn_boleto
where id_boleto = vBoleto;
if vOrigem is null then
exit;
end if;
vBoleto := vOrigem;
Incidentally, your loop is reinventing hierarchical queries; you could replace that with:
...
exception
when no_data_found then
select connect_by_root id_boleto
into vBoleto
from sn_boleto
where id_boleto = vBoleto
connect by prior id_boleto = id_boleto_origem
start with id_boleto_origem is null;
end;