1
resposta

[Dúvida] duvida sobre o select pos cursor e erro de logica

essa foi a resolução da atividade que eu criei, porem ao conferir com a do professor me passou uma duvida, n sei se deixei isso passar em alguma aula, mas pq utilizar o cursor apenas para pegar o id e depois fazer outro select para pegar o valor_total?

create or replace PROCEDURE SOMA_VENDAS_cursor
(p_VENDA_LIMITE IN produto_venda_exercicio.valor_total%type, p_ID_RETORNO OUT produto_venda_exercicio.id%type)
IS
   v_ID produto_venda_exercicio.id%type;
   v_VALOR_TOTAL produto_venda_exercicio.valor_total%type;
   v_VENDA_TOTAL produto_venda_exercicio.valor_total%type := 0;
   cursor cur_vendas is select id,valor_total from PRODUTO_VENDA_EXERCICIO;
BEGIN
    open cur_vendas;
    
    loop 
        FETCH cur_vendas INTO v_ID, v_VALOR_TOTAL;
        v_VENDA_TOTAL := v_VENDA_TOTAL+ v_VALOR_TOTAL;
        if v_VENDA_TOTAL >= p_VENDA_LIMITE THEN
         EXIT;
      END IF;
      EXIT WHEN cur_vendas%NOTFOUND;
    END LOOP;
     p_ID_RETORNO := v_ID;
     close cur_vendas;
END;

alem disso o meu codigo parece ter algum erro de logica que eu n peguei, talvez seja justamente o problema do select, mas ao rodar como sugerido ele retorna 8 ao inver de 6 onde esta a minha falha?

1 resposta

Oii, Evandro, tudo bem?

A utilização de um cursor no exemplo do professor se deve à necessidade de iterar sobre os registros de forma controlada e eficiente, especialmente em um contexto onde os IDs podem não seguir uma sequência numérica contínua.

Isso é importante porque, ao usar um cursor, o PL/SQL gerencia melhor o conjunto de resultados, reduzindo o overhead de acessos ao banco de dados (e melhorando a performance em cenários com grandes volumes de dados).

Quanto ao erro que você mencionou, ele está relacionado ao momento em que você decide sair do loop.

No seu código, você acumula o valor_total em v_VENDA_TOTAL e só depois verifica se alcançou o limite com o p_VENDA_LIMITE. Isso pode fazer com que o valor final do v_VENDA_TOTAL exceda o limite antes de sair do loop, especialmente se o valor_total de uma venda individual for significativamente alto.

Uma sugestão para ajustar isso seria verificar o limite antes de adicionar o valor_total ao acumulado. Você pode fazer deste jeito, por exemplo:

FETCH cur_vendas INTO v_ID, v_VALOR_TOTAL;
IF v_VENDA_TOTAL + v_VALOR_TOTAL >= p_VENDA_LIMITE THEN
   p_ID_RETORNO := v_ID;
   EXIT;
END IF;
v_VENDA_TOTAL := v_VENDA_TOTAL + v_VALOR_TOTAL;

Se outra dúvida surgir, estamos disponíveis.

Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.