CURSOR RAISE APPLICATION

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
huntersc
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 15
Registrado em: Sex, 12 Mar 2010 3:11 pm
Localização: FLORIANOPOLIS - SC

Boa Tarde,

Estou criando uma procedure de integração mais não estou sabendo como tratar os erros oriundos de triggers.

Chamo um procedure onde carrego um cursor de pedidos..
ao inserir em uma tabela e essa retorna um erro, preciso gravar numa tabela uma flag que aquele pedido deu erro e continuar o cursor.

Estou usando RAISE_APPLICATION_ERROR mais acho que esse não é o correto pois ele sai da operação não continuando.

alguém poderia me dizer como se procede em um caso desse?

Obrigado
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

exception tem o escopo definido pelo bloco onde são geradas..

se você colocar um bloco begin end especifico para a inserção do registro já dentro do loop não funcionaria?

e dentro desse bloco capturar a exceção e tratar o erro, gravando a flag
Avatar do usuário
Bogos
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 20
Registrado em: Ter, 06 Jul 2010 8:58 am
Localização: Americana / SP
Contato:
Ivens Bógos
Analista Desenvolvedor Oracle

Um exemplo do que o victor disse:

Selecionar tudo

begin
    for rs in (select * from t_tabela) loop
        begin
            chamada_de_procedure;
        exception when EXCEPTION_A_SER_TRATADA then
            grava_flag;
        end;
    end loop;
end;
Abraços
huntersc
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 15
Registrado em: Sex, 12 Mar 2010 3:11 pm
Localização: FLORIANOPOLIS - SC

Bogos,
Eu não chamo a procedure para inserir...

a procedure que tem um insert ... em uma tabela onde essa tabela tem triggers de validações que podem dar o erro...

Exemplo:

Selecionar tudo

CREATE OR REPLACE PROCEDURE Pedidos(........)
..........................
 OPEN PEDIDO;
        LOOP        
            FETCH PEDIDO INTO  P_DTEMISSAO,P_CLIENTE.........
                EXIT WHEN PEDIDO%NOTFOUND;

           insert into Pedidos_confirmados .......

        END LOOP
Usando o

Selecionar tudo

exception when EXCEPTION_A_SER_TRATADA then 
            grava_flag; 
depois do insert continuaria o loop?

OBRIGADO
JR
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

SIM..
se der algum erro no insert, este erro sera tratado dentro do bloco begin end que ele se encontra

tem q fazer a adaptação para seu código...
é so você substituir o

Selecionar tudo

chamada_de_procedure;
por

Selecionar tudo

insert into Pedidos_confirmados .......

Selecionar tudo


CREATE OR REPLACE PROCEDURE Pedidos(........) 
.......................... 
 OPEN PEDIDO; 
        LOOP        
            FETCH PEDIDO INTO  P_DTEMISSAO,P_CLIENTE......... 
                EXIT WHEN PEDIDO%NOTFOUND; 

         
        begin 
              insert into Pedidos_confirmados ....... 
        exception when EXCEPTION_A_SER_TRATADA then 
            grava_flag; 
        end; 


        END LOOP 
huntersc
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 15
Registrado em: Sex, 12 Mar 2010 3:11 pm
Localização: FLORIANOPOLIS - SC

Valeu Victor,

Utilizei

Selecionar tudo

   OPEN PEDIDO;
        LOOP        
            FETCH PEDIDO INTO  P_NUPEDIDO,P_DTEMISSAO,P_CLIENTE,P_TOP,P_NEG;  
                EXIT WHEN PEDIDO%NOTFOUND;
                  

        BEGIN

        /** INSERI CABEÇARIO PEDIDO **/
        DBMS_OUTPUT.PUT_LINE('INSERINDO ' || P_NUPEDIDO);

         insert ...........................
       
        exception when OTHERS then                                    
                                   DBMS_OUTPUT.PUT_LINE('ERRO NA INSERCAO' || P_NUPEDIDO);
                      END; 
        END LOOP;
   CLOSE PEDIDO;
Parece que funcionou..
Gostaria de capturar o Erro que vem da trigger tem como? para poder por no log!!

[]s
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

vamo la..

se você souber qual o erro gerado pela trigger da pra você fazer +ou- assim

Selecionar tudo

exception when ERRO_TRIGGER then
    DBMS_OUTPUT.PUT_LINE('ERRO NA TRIGGER' || P_NUPEDIDO); 
exception when OTHERS then
    DBMS_OUTPUT.PUT_LINE('ERRO NA INSERCAO' || P_NUPEDIDO); 
assim qualquer outro erro diferente de ERRO_TRIGGER caira no outro bloco[/code]
Avatar do usuário
Bogos
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 20
Registrado em: Ter, 06 Jul 2010 8:58 am
Localização: Americana / SP
Contato:
Ivens Bógos
Analista Desenvolvedor Oracle

Só para deixar registrado, procure não usa when OTHERS, procure sempre tratar os erros individualmente, salvo situações em que é realmente necessário capturar QUALQUER erro.
Fica a dica :wink:

Abraço[/b]
huntersc
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 15
Registrado em: Sex, 12 Mar 2010 3:11 pm
Localização: FLORIANOPOLIS - SC

Muito Obrigado.. Funcionou
Agora me deu outra duvida que não consegui resolver..
Inserir O pedido, Agora tenho que inserir os Itens_Pedido

não posso declarar o cursor no declare pois preciso saber o numero do pedido que vem do 1 cursor..

Como faço para declarar o 2 cursor? Coloquei depois do insert mais da erro

Selecionar tudo

.....................
insert
...............

exception when OTHERS then                                    
                                   DBMS_OUTPUT.PUT_LINE('ERRO NA INSERCAO' || P_NUPEDIDO);    
                                   RETORNO := 'E' ;
                                   P_ERRO := 1;                              
          END;
    
    IF (P_ERRO = 0) THEN
    BEGIN
      
    /* Inserir Itens*/
 
    CURSOR ITENS IS SELECT ......
Obrigado

[]s
huntersc
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 15
Registrado em: Sex, 12 Mar 2010 3:11 pm
Localização: FLORIANOPOLIS - SC

Opa,
eu mesmo consegui so que o loop ta repetindo :/

Log:

Selecionar tudo


INSERINDO 90912960
INSERINDO PRODUTO 47 DO PEDIDO 90912960
INSERINDO PRODUTO 7 DO PEDIDO 90912960
INSERINDO PRODUTO 47 DO PEDIDO 90912960
ERRO NA INSERCAO ITENS47
INSERINDO PRODUTO 7 DO PEDIDO 90912960
ERRO NA INSERCAO ITENS7
INSERINDO 90914374
INSERINDO PRODUTO 47 DO PEDIDO 90914374
INSERINDO PRODUTO 7 DO PEDIDO 90914374
INSERINDO PRODUTO 47 DO PEDIDO 90914374
ERRO NA INSERCAO ITENS47
INSERINDO PRODUTO 7 DO PEDIDO 90914374
ERRO NA INSERCAO ITENS7
E
O que eu fiz:
no cursor do itens coloquei

Selecionar tudo

    CURSOR ITENS(NUPEDIDO INT) IS 
                   ............			WHERE nupedido = NUPEDIDO;    
no open:

Selecionar tudo

   IF (P_ERRO = 0) THEN
    /* Inserir Itens*/       
   OPEN ITENS(P_NUPEDIDO);
   LOOP
        FETCH ITENS INTO .......
              EXIT WHEN ITENS%NOTFOUND;
     
   DBMS_OUTPUT.PUT_LINE('INSERINDO PRODUTO ' || P_CODPROD || ' DO PEDIDO ' || P_NUPEDIDO);
Problema é que ta entrando 3 vezes.. e so tenho 2 Produto :/
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

então meu amigo..

não entendi o que você fez no código pois você so postou trechos mas te pergunto..

você fez um laço dentro do outro e seu problema e que o primeiro está fazendo uma interação a mais certo?

da uma olhada na lógica ai que você vai acertar.. mas senão posta ai..
huntersc
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 15
Registrado em: Sex, 12 Mar 2010 3:11 pm
Localização: FLORIANOPOLIS - SC

Bom Dia victor,

Sim estou com um laço dentro do outro.
O Problema está no segundo laço que duplica. se tenho 2 Registros ele loopa 4 vezes..

segue codigo

Selecionar tudo

DECLARE      
    CURSOR PEDIDO IS 
                    SELECT ....................
                     FROM tbpedido;
                    
 
    CURSOR ITENS(NUPEDIDO INT) IS 
                       SELECT ........
                         FROM tblitempedido
          WHERE nupedido = NUPEDIDO;                        
    
                   
   BEGIN
    
   RETORNO := 'OK' ;
   
   /* BUSCA PEDIDOS*/
   
   OPEN PEDIDO;
        LOOP        
            FETCH PEDIDO INTO ...................
                EXIT WHEN PEDIDO%NOTFOUND;
                  

        BEGIN
                P_ERRO := 0;
                DBMS_OUTPUT.PUT_LINE('INSERINDO ' || P_NUPEDIDO);

	-- insert pedido

            COMMIT;
        exception when OTHERS then                                    
                                   DBMS_OUTPUT.PUT_LINE('ERRO NA INSERCAO' || P_NUPEDIDO);    
                                   RETORNO := 'E' ;
                                   P_ERRO := 1;
                                   ROLLBACK;                              
          END;
    
  
   IF (P_ERRO = 0) THEN
          
    /* Busca Itens*/

   DBMS_OUTPUT.PUT_LINE('Numero Pedido ' || P_NUPEDIDO); 
          
   OPEN ITENS(P_NUPEDIDO);
     LOOP
        FETCH ITENS INTO .........................;
              EXIT WHEN ITENS%NOTFOUND;
              
   DBMS_OUTPUT.PUT_LINE('Numero Cursor ' || ITENS%rowcount);
   DBMS_OUTPUT.PUT_LINE('INSERINDO PRODUTO ' || P_CODPROD || ' DO PEDIDO ' || P_NUPEDIDO);

 BEGIN  
  
  --- insert itens
       
         commit;          
     exception when OTHERS then                                    
                                   DBMS_OUTPUT.PUT_LINE('ERRO NA INSERCAO ITENS' ||  P_CODPROD);    
                                   RETORNO := 'E' ;
                                   P_ERRO := 1; 
                                   rollback;                             
       END;
      END LOOP; /* fim loop itens */
    CLOSE ITENS;
    
    /* Fim inserir Itens */
   END IF; /* FIM IF ERRO */        
        END LOOP; /* fim loop pedido */
   CLOSE PEDIDO;


    END;
END;
Como estou muito em cima do codigo talvez não ache o erro..
coloquei outputs.. para tentar achar o erro.. no rowcount do cursor aparece 4..

Valeu.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 7 visitantes