Erro de retorno de Função

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
rickab7
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 53
Registrado em: Sex, 25 Ago 2006 8:11 pm
Localização: campo grande
stephany henrique de almeida batista

Galera tenho essa função:

Selecionar tudo

CREATE OR REPLACE FUNCTION humc_vl_contagem_ant
(contagem IN NUMBER ) RETURN number 
IS

vl_produto NUMBER(16, 12);
qtd        NUMBER(5);
vl_total   NUMBER(16, 12);

BEGIN

      vl_total := 0;
      FOR C IN (SELECT * FROM itcontagem WHERE cd_contagem = contagem)
      LOOP

        SELECT Decode(qt_estoque, NULL, 0, qt_estoque) INTO qtd FROM copia_estoque WHERE cd_contagem = contagem AND cd_produto = c.cd_produto AND cd_lote = c.cd_lote AND qt_estoque > 0;
    
        SELECT Decode(vl_ultima_entrada, NULL, 0, vl_ultima_entrada) INTO vl_produto FROM produto WHERE cd_produto = c.cd_produto; 

      vl_total := vl_total + (vl_produto * qtd);

      END LOOP;      

      RETURN vl_total ;

END;


//Select

SELECT c.cd_contagem,
            humc_vl_contagem_ant(c.cd_contagem)
       
       FROM contagem c
            

mais todo retorno dela é vazio, alguém pode me ajudar

meu select:



[/code]
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

Fica um pouco difícil de saber qual é o problema, pois a gente não tem a sua base aqui pra testar.
Mas olhando por cima, parece que ele nem está entrando no LOOP. Ou está caindo em algum exception no fim da rotina.

Outra coisa que você pode melhorar é usar NVL em vez de DECODE.

Selecionar tudo

CREATE OR REPLACE FUNCTION humc_vl_contagem_ant
(contagem IN NUMBER ) RETURN number
IS

vl_produto NUMBER(16, 12);
qtd        NUMBER(5);
vl_total   NUMBER(16, 12);

BEGIN

      vl_total := 0;
      FOR C IN (SELECT * FROM itcontagem WHERE cd_contagem = contagem)
      LOOP

        SELECT NVL(qt_estoque,  0) 
        INTO qtd 
        FROM copia_estoque 
        WHERE cd_contagem = contagem 
          AND cd_produto = c.cd_produto 
          AND cd_lote = c.cd_lote 
          AND qt_estoque > 0;
   
        SELECT NVL(vl_ultima_entrada,  0) 
        INTO vl_produto 
        FROM produto 
        WHERE cd_produto = c.cd_produto;

        vl_total := vl_total + (vl_produto * qtd);

      END LOOP;     

      RETURN vl_total ;

END;
Avatar do usuário
TBou
Rank: Analista Sênior
Rank: Analista Sênior
Mensagens: 136
Registrado em: Qui, 05 Ago 2004 9:33 am
Localização: Campo Grande - MS
Thiago Bourscheidt
thiago.info@apoiorural.com.br
Analista de Sistemas

Seria Interessante você tratar o When_no_tada_found e when too_many_rows nestas Duas selects.

desta Forma não vai cair Fora de function se ocorrer algum erro.

Selecionar tudo

      BEGIN 
        SELECT NVL(qt_estoque,  0)
        INTO qtd
        FROM copia_estoque
        WHERE cd_contagem = contagem
          AND cd_produto = c.cd_produto
          AND cd_lote = c.cd_lote
          AND qt_estoque > 0;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            qtd := 0; 
      END;
      BEGIN 
        SELECT NVL(vl_ultima_entrada,  0)
        INTO vl_produto
        FROM produto
        WHERE cd_produto = c.cd_produto; 
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            vl_produto := 0; 
      END;
Avatar do usuário
TBou
Rank: Analista Sênior
Rank: Analista Sênior
Mensagens: 136
Registrado em: Qui, 05 Ago 2004 9:33 am
Localização: Campo Grande - MS
Thiago Bourscheidt
thiago.info@apoiorural.com.br
Analista de Sistemas

Outra coisa legal a se fazer é colocar um When others geral da function dando um return -1 aiw se retornar -1 você já sabe que esta ocorrendo um erro na execução da function

Selecionar tudo

CREATE OR REPLACE FUNCTION humc_vl_contagem_ant
(contagem IN NUMBER ) RETURN number
IS

vl_produto NUMBER(16, 12);
qtd        NUMBER(5);
vl_total   NUMBER(16, 12);

BEGIN

      vl_total := 0;
      FOR C IN (SELECT * FROM itcontagem WHERE cd_contagem = contagem)
      LOOP

        SELECT NVL(qt_estoque,  0)
        INTO qtd
        FROM copia_estoque
        WHERE cd_contagem = contagem
          AND cd_produto = c.cd_produto
          AND cd_lote = c.cd_lote
          AND qt_estoque > 0;
   
        SELECT NVL(vl_ultima_entrada,  0)
        INTO vl_produto
        FROM produto
        WHERE cd_produto = c.cd_produto;

        vl_total := vl_total + (vl_produto * qtd);

      END LOOP;     

      RETURN vl_total ;

EXCEPTION
  WHEN OTHERS THEN
    RETURN(-1);
END;
Responder
  • Informação