Cursor com exception

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
julianaf024
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 22
Registrado em: Sex, 30 Out 2009 10:24 am
Localização: sp
Juliana Fernandes

Por favor me falem onde estou errando.

Faça uma Função chamada fun_total_duplicata_RMnnnnn, para que faça uma totalização das duplicatas a partir do parametro do numero da nota fiscal. Crie os tratamentos de exceptions necessários. Cuidado não use
RAISE_APPLICATION_ERROR.

Selecionar tudo

CREATE OR REPLACE FUNCTION FUN_TOTAL_DUPLICATA_RM63016
(P_NR_NOTA IN LOC_DULICATA.NR_NOTA%TYPE) RETURN NUMBER IS

       CURSOR CUR IS
          SELECT  COUNT (*) TOTAL
            FROM LOC_DUPLICATA
              WHERE NR_NOTA = P_NR_NOTA;
                   
          V_RETURN NUMBER := 0;
BEGIN
FOR V_TOTAL IN C_TOTAL LOOP
V_RETURN := V_TOTAL.TOTAL;
END LOOP;
RETURN V_RETURN;
EXCEPTION
   WHEN NO_DATA_FOUND THEN 
      DBMS_OUTPUT.PUT_LINE('ERRO NO_DATA_FOUND ');
   WHEN TOO_MANY_ROWS THEN 
      DBMS_OUTPUT.PUT_LINE('ERRO TOO_MANY_ROWS ');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('ERRO OTHERS ');
END;
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

qual e o erro?

n entendi porque você precisa de cursor neste caso.. todo via segue um exemplo para você ter por base

Selecionar tudo

DECLARE 
    /* DECLARANDO O CURSOR DE PRODUTOS */
    CURSOR C_PRODUTOS IS 
        SELECT * FROM TB_PRODUTOS;
        
    /* DECLARANDO UMA VARIAVEL QUE SERA O REGISTRO DA TABELA */
    REG_PRODUTO C_PRODUTOS%ROWTYPE;
    
BEGIN
    /* ABRE CURSOR */
    OPEN C_PRODUTOS
    
    LOOP
        /* LÊ UM REGISTRO DO CURSOR */
        FETCH C_PRODUTOS INTO REG_PRODUTO;
        
        /* ABANDONA O LOOP CASO SEJA O FINAL DO CURSOR */
        EXIT WHEN C_PRODUTOS%NOTFOUND;
        
        /* 
        AQUI SERA INSERIDO O CODIGO QUE IRA MANIPULAR OS DADOS COMO: 
            - INSERIR EM OUTRA TABELA, 
            - FAZER ALGUM CALCULO, 
            - ETC. 
        */
    
    END LOOP;
    
    /* FECHA O CURSOR */
    CLOSE C_PRODUTOS
END;
julianaf024
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 22
Registrado em: Sex, 30 Out 2009 10:24 am
Localização: sp
Juliana Fernandes

já tentei com e sem cursor, mas ambos compilam com advertencia.
O que seria mais indicado para resolver o enunciado?
SergioLBJr
Rank: Oracle Guru
Rank: Oracle Guru
Mensagens: 448
Registrado em: Ter, 16 Jun 2009 3:07 pm
Localização: Parobé - RS
Sérgio Luiz Bonemberger Junior
Programador Junior
Parobé RS

[]s

Pra que este cursor? tu nem abre ele.

E posta o erro para podermo entender o que esta acontecendo.
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

vê ai se vai..

Selecionar tudo

CREATE OR REPLACE FUNCTION FUN_TOTAL_DUPLICATA_RM63016
       (P_NR_NOTA IN LOC_DULICATA.NR_NOTA%TYPE) 
RETURN NUMBER IS
       v_tot number;

BEGIN

           SELECT count(*) 
                  into v_tot 
           FROM LOC_DUPLICATA
           WHERE NR_NOTA = P_NR_NOTA;

RETURN v_tot;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
       DBMS_OUTPUT.PUT_LINE('ERRO NO_DATA_FOUND ');
  WHEN OTHERS THEN
       DBMS_OUTPUT.PUT_LINE('ERRO OTHERS ');
END FUN_TOTAL_DUPLICATA_RM63016; 
/
julianaf024
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 22
Registrado em: Sex, 30 Out 2009 10:24 am
Localização: sp
Juliana Fernandes

Debugando, deu esse erro:

Error(21,1): PLS-00103: Encountered the symbol "WHERE"
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

estranho Juliana...

tenta com um alias LD para a tabela

Selecionar tudo

CREATE OR REPLACE FUNCTION FUN_TOTAL_DUPLICATA_RM63016
       (P_NR_NOTA IN LOC_DULICATA.NR_NOTA%TYPE)
RETURN NUMBER IS
       
       v_tot NUMBER;

BEGIN

 SELECT count(*)
        INTO v_tot
 FROM LOC_DUPLICATA LD
 WHERE LD.NR_NOTA = P_NR_NOTA;

RETURN v_tot;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
       DBMS_OUTPUT.PUT_LINE('ERRO NO_DATA_FOUND ');
  WHEN OTHERS THEN
       DBMS_OUTPUT.PUT_LINE('ERRO OTHERS ');
END FUN_TOTAL_DUPLICATA_RM63016;
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Hmm. Deveria funcionar.
Uma coisa no seu codigo original que não faz sentido é colocar todos aqueles exceptions pra um cursor.

Selecionar tudo

EXCEPTION
   WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE('ERRO NO_DATA_FOUND ');
   WHEN TOO_MANY_ROWS THEN
      DBMS_OUTPUT.PUT_LINE('ERRO TOO_MANY_ROWS ');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('ERRO OTHERS '); 
Veja:
* Um cursor não gera NO_DATA_FOUND. Apenas em select normais.
* É esperado que um cursor possa retornar mais de uma linha, então o TOO_MANY_ROWS também não faz sentido aqui. (nunca vai cair nesses 2).

Tente ir no SQL*PLUS e compilar o código que victorhugomuniz mandou: (tirei também o no-data-found, pois um COUNT sempre vai retornar alguma coisa, nem que seja NULO). Se der erro, manda pra nos a resposta!

Selecionar tudo

CREATE OR REPLACE FUNCTION FUN_TOTAL_DUPLICATA_RM63016
       (P_NR_NOTA IN LOC_DULICATA.NR_NOTA%TYPE)
RETURN NUMBER IS
       v_tot number;

BEGIN

           SELECT count(*)
                  into v_tot
           FROM LOC_DUPLICATA
           WHERE NR_NOTA = P_NR_NOTA;

RETURN v_tot;
EXCEPTION
  WHEN OTHERS THEN
       DBMS_OUTPUT.PUT_LINE('ERRO OTHERS ');
END FUN_TOTAL_DUPLICATA_RM63016;
/ 
Editado pela última vez por dr_gori em Sex, 30 Out 2009 4:02 pm, em um total de 1 vez.
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

e verdade..

a TOO_MANY_ROWS eu tinha visto que nunca aconteceria

agora a NO_DATA_FOUND eu não pensei .. e verdade o count retornara zero caso não haja registros e então sempre tera dados

valeuu dr_gori

:D
julianaf024
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 22
Registrado em: Sex, 30 Out 2009 10:24 am
Localização: sp
Juliana Fernandes

Realmente não tem nada de dados na tabela.
Deve retornar null...

Da uma olhada nos erros:

Selecionar tudo

Error(19,8): PLS-00103: Encountered the symbol "DBMS_OUTPUT" 
*Error(19,44): PLS-00103: Encountered the symbol ";" when expecting one of the following:     . ( , * % & - + / at mod remainder rem <an identifier>    <a double-quoted delimited-identifier> <an exponent (**)> as    from into || multiset bulk 
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

você quem criou esse banco? você esta tentando criar como usuario dba do banco?

tenta dar um

Selecionar tudo

set serveroutput on;

ou então troca esse teu tratamento para o mesmo da outra function sua

Selecionar tudo

EXCEPTION
    WHEN OTHERS THEN
      RAISE_APPLICATION_ERROR(-20011,'ERRO FUN_CONSULTA_NF_RM63016: ' || SQLERRM);
julianaf024
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 22
Registrado em: Sex, 30 Out 2009 10:24 am
Localização: sp
Juliana Fernandes

Esse ambiente é gerado por um scritp que a Faculdade fornece.
Posso criar esse ambiente onde eu quiser. Muitas tabelas não tem dados, mas o professor diz que o fato de não ter dados não impede o funcionamento da procedure ou função.

Com o SET SERVEROUTPUT ON continuou o mesmo erro.
Com o tratamento de exception sugerido, deu o erro de WHERE.

Error(20,1): PLS-00103: Encountered the symbol "WHERE"


Obs.: Vitor, te mandei um email, você recebeu?
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

para esse erro do where você tentou colocar o alias LD conforme falei e uma resposta acima??


obs: vi sim e já te respondi!!
julianaf024
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 22
Registrado em: Sex, 30 Out 2009 10:24 am
Localização: sp
Juliana Fernandes

Sim, o erro continuou.
JOPA
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 58
Registrado em: Sex, 30 Out 2009 9:52 am
Localização: Salvador - BA
Contato:
Atenciosamente,

João Paulo A. C. do Bomfim

"Deu certo? Deixa! Funcionou? Não mexa!"

julianaf024,

Entendendo o objetivo de se obter a totalização das duplicatas a partir do parametro do numero da nota fiscal, tente dessa forma:

Selecionar tudo

create or replace FUNCTION FUN_TOTAL_DUPLICATA_RM63016(P_NR_NOTA IN LOC_DUPLICATA.NR_NOTA%TYPE) RETURN NUMBER 
IS
   V_RETURN NUMBER;
BEGIN
   IF p_nr_nota IS NULL THEN
      v_return := 0;
   ELSE
     BEGIN
        SELECT COUNT(*)
        INTO   v_return
        FROM   LOC_DUPLICATA
        WHERE  NR_NOTA = p_nr_nota;
     EXCEPTION
        WHEN OTHERS THEN
           v_return := 0;
     END;
   END IF;
   
   RETURN v_return;
   
END FUN_TOTAL_DUPLICATA_RM63016;
julianaf024
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 22
Registrado em: Sex, 30 Out 2009 10:24 am
Localização: sp
Juliana Fernandes

Ficou perfeito João Paulo.
Não tinha pensado em fazer assim... Ta rodando certinnho.
Obrigada!!!!
JOPA
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 58
Registrado em: Sex, 30 Out 2009 9:52 am
Localização: Salvador - BA
Contato:
Atenciosamente,

João Paulo A. C. do Bomfim

"Deu certo? Deixa! Funcionou? Não mexa!"

Por nada julianaf024, um forte abraço!!!

:wink:
Responder
  • Informação
  • Quem está online

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