- Este tópico contém 7 respostas, 4 vozes e foi atualizado pela última vez 16 anos, 1 mês atrás por
rwarstat.
-
AutorPosts
-
26 de outubro de 2009 às 9:49 pm #90480
Anakim
ParticipanteEstou fazendo uma instrução PL/SQL aonde eu pego dados de uma tabela e jogo em outro sendo que antes de jogar os dados na nova tabela eu tenho que pegar um dado em uma terceira tabela e com isso recebo este erro.
Abaixo segue a instrução SQL:
DECLARE
code varchar2( 2 );
temp varchar2( 12 );
msisdn varchar2( 10 );
codeBuddy varchar2( 2 );
tempBuddy varchar2( 12 );
msisdnBuddy varchar2( 10 );
idCustomer number;
idCustomerBuddy number;
BEGINFOR r IN (select
ru.msisdn,
bru.msisdn as BUDDY_MSISDN,
bl.position
from
blah.buddy_lists bl
inner join blah.nicknames n on ( bl.nick_id = n.nick_id )
inner join blah.nicknames bn on ( bl.buddy_nick_id = bn.nick_id )
inner join blah.registered_users ru on ( n.nick_id = ru.active_nick_id )
inner join blah.registered_users bru on ( bn.nick_id = bru.active_nick_id )
where
ru.country = 'BR'
and bl.nick_id <> bl.buddy_nick_id
) LOOPcode := SUBSTR( R.MSISDN, 1, 2 );
msisdn := SUBSTR( R.MSISDN, 4 );
temp := ( code || msisdn );
select id_customer into idCustomer from customer where msisdn = temp;codeBuddy := SUBSTR( R.BUDDY_MSISDN, 1, 2 );
msisdnBuddy := SUBSTR( R.BUDDY_MSISDN, 4 );
tempBuddy := ( codeBuddy || msisdnBuddy );
select id_customer into idCustomerBuddy from customer where msisdn = tempBuddy;insert into customer_buddylist ( id_customer_owner, id_customer_buddy, list_order ) values ( idCustomer, idCustomerBuddy, r.position );
END LOOP;
/* EXCEPTION
WHEN OTHERS THEN
--raise_application_error( -20008, ( idCustomer || ' ' || idCustomerBuddy ) );
raise_application_error( -20008, ( tempBuddy ) );*/
END;Alguém saberia aonde está o erro?
Lembrando que já fiz o selects na mão e o dado existe.26 de outubro de 2009 às 9:52 pm #90481Anakim
ParticipanteComplementando….
Sempre quando chega nesta linha:
select id_customer into idCustomerBuddy from customer where msisdn = tempBuddy;Recebo este erro:
ORA-01403: no data found
ORA-06512: at line 35
26 de outubro de 2009 às 9:54 pm #90482burga
Participantecoloca o select id_customer into idCustomer from customer where msisdn = temp; dentro de um CURSOR. e passa o temp como parâmetro.
26 de outubro de 2009 às 9:56 pm #90483Anakim
ParticipanteDesculpa você poderia explicar melhor a sua solução?
Porque sou novo no oracle e ainda não trabalhei com cursor.26 de outubro de 2009 às 10:09 pm #90485burga
ParticipanteO cursor já trata a exceção de no data found, assim não fica estourando no select, quando não existe retorno pra ele, é mais fácil você buscar explicações pela internet pois eu não vou saber explicar direito, hehehehe, (não por falta de vontade mas por limitação mesmo), mas o código fica mais ou menos assim:
DECLARE
code varchar2( 2 );
temp varchar2( 12 );
msisdn varchar2( 10 );
codeBuddy varchar2( 2 );
tempBuddy varchar2( 12 );
msisdnBuddy varchar2( 10 );
idCustomer number;
idCustomerBuddy number;cursor c_id_customer(tmp IN VARCHAR2) IS select id_customer into idCustomer from customer where msisdn = tmp;BEGIN
FOR r IN (select ru.msisdn, bru.msisdn as BUDDY_MSISDN, bl.position from blah.buddy_lists bl inner join blah.nicknames n on ( bl.nick_id = n.nick_id ) inner join blah.nicknames bn on ( bl.buddy_nick_id = bn.nick_id ) inner join blah.registered_users ru on ( n.nick_id = ru.active_nick_id ) inner join blah.registered_users bru on ( bn.nick_id = bru.active_nick_id ) where ru.country = 'BR' and bl.nick_id bl.buddy_nick_id ) LOOP code := SUBSTR( R.MSISDN, 1, 2 ); msisdn := SUBSTR( R.MSISDN, 4 ); temp := ( code || msisdn ); open c_id_customer(temp); fetch c_id_customer into idCustomer; close c_id_customer; codeBuddy := SUBSTR( R.BUDDY_MSISDN, 1, 2 ); msisdnBuddy := SUBSTR( R.BUDDY_MSISDN, 4 ); tempBuddy := ( codeBuddy || msisdnBuddy ); open c_id_customer(tempBuddy); fetch c_id_customer into idCustomerBuddy; close c_id_customer; insert into customer_buddylist ( id_customer_owner, id_customer_buddy, list_order ) values ( idCustomer, idCustomerBuddy, r.position ); END LOOP;/* EXCEPTION
WHEN OTHERS THEN
--raise_application_error( -20008, ( idCustomer || ' ' || idCustomerBuddy ) );
raise_application_error( -20008, ( tempBuddy ) );*/
END;Note que eu declarei um cursor com o select logo abaixo das declarações das variáveis locais. Depois foi feita a chamada a esse cursor no lugar dos dois selects que estavam sendo feitos dentro do LOOP. Assim ele usa variáveis bind também melhorando um pouco o desempenho do teu procedimento.
26 de outubro de 2009 às 11:37 pm #90494Leonardo Litz
ParticipanteEntão Anakin, esta ocorrendo o erro no_data_found pois não esta sendo encontrado o conteúdo nesta tabela.
Trate o select:
begin
select id_customer
into idCustomerBuddy
from customer
where msisdn = tempBuddy
exception when no_data_found then
null;
end;
Vlw Leonardo Litz
27 de outubro de 2009 às 12:13 am #90495Anakim
ParticipanteA data existe sim.
Valeu burga com o cursor funcionou. 😛 😛 😛 😛
Vou dá uma procurada na net, por que funcionou com cursor e por que não funcionou sem o cursor?
Valeu pelas ajudas!!! 😛 😛 😛27 de outubro de 2009 às 2:11 pm #90500rwarstat
ParticipanteAnakin,
Quando usa-se cursor ele trata a exceção no_data_found, evitando assim que estoure o erro para ti. Para usar do jeito que tu havia pensado, mas sem que estoure o erro teria que fazer como o Litz postou, colocando o teu select dentro de um outro bloco PL/SQL e fazendo o tratamento de exceção ali.
O recomendado é sempre que exista um tratamento de exceção, justamente para não ficar estourando os erros. Quando for fazer um select .. into é muito recomendado que trate o no_data_found.Abraço,
Roberto -
AutorPosts
- Você deve fazer login para responder a este tópico.