1
resposta

MINHA RESOLUÇÃO

Bom dia a todos,

Primeiramente, criei a procedure CALCULA_IMPOSTO conforme solicitado.

CREATE OR REPLACE PROCEDURE CALCULO_IMPOSTO
(p_ID IN PRODUTO_VENDA_EXERCICIO.ID%type,
p_VALOR_IMPOSTO OUT NUMBER)
IS
    v_PRECO PRODUTO_VENDA_EXERCICIO.PRECO%type;
    v_QUANTIDADE PRODUTO_VENDA_EXERCICIO.QUANTIDADE%type;
    v_PERCENTUAL_IMPOSTO PRODUTO_VENDA_EXERCICIO.PERCENTUAL_IMPOSTO%type;
BEGIN
    SELECT PRECO, QUANTIDADE, PERCENTUAL_IMPOSTO
    INTO v_PRECO, v_QUANTIDADE, v_PERCENTUAL_IMPOSTO
    FROM PRODUTO_VENDA_EXERCICIO WHERE ID = p_ID;
    p_VALOR_IMPOSTO := NVL(v_PRECO,0) * NVL(v_QUANTIDADE,0) * (NVL(v_PERCENTUAL_IMPOSTO,0) / 100);
END;

Depois fiz a conferência para verificar se o cálculo está correto

SET SERVEROUTPUT ON;
DECLARE
    v_ID PRODUTO_VENDA_EXERCICIO.ID%type;
    v_VALOR_IMPOSTO NUMBER;
BEGIN
    v_ID := 2;
    CALCULO_IMPOSTO(v_ID,v_VALOR_IMPOSTO);
    DBMS_OUTPUT.PUT_LINE('O Valor do imposto do produto: ' || v_ID ||  ' é de R$' || v_VALOR_IMPOSTO);
END;

O cálculo deu certo, pois a quantidade é 200, preço 25, e percentual imposto 15, no final o resultado é de fato 750.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

1 resposta

Olá, Adriano. Como vai?

Parabéns pela resolução do exercício! O seu código ficou excelente, muito bem estruturado e a lógica aplicada está impecável.

O uso da função NVL foi uma excelente prática de programação defensiva. Garantir que valores nulos sejam tratados como 0 evita erros inesperados de execução (como tentar fazer cálculos com NULL), o que é fundamental ao lidar com bancos de dados em ambientes reais de produção.

Para agregar ainda mais valor ao seu projeto e complementar sua solução, quero deixar duas sugestões de boas práticas que são muito utilizadas no dia a dia por desenvolvedores PL/SQL:

1. Tratamento de Exceções (Exceptions)

No cenário atual, o seu SELECT ... INTO funciona perfeitamente porque o v_ID := 2 existe na tabela. Contudo, se por acaso um ID inexistente for passado como parâmetro, o Oracle irá disparar um erro do tipo NO_DATA_FOUND.

Para deixar sua procedure ainda mais robusta, você pode adicionar um bloco de EXCEPTION no final dela. Veja como ficaria:

CREATE OR REPLACE PROCEDURE CALCULO_IMPOSTO
(p_ID IN PRODUTO_VENDA_EXERCICIO.ID%type,
p_VALOR_IMPOSTO OUT NUMBER) IS
    v_PRECO PRODUTO_VENDA_EXERCICIO.PRECO%type;
    v_QUANTIDADE PRODUTO_VENDA_EXERCICIO.QUANTIDADE%type;
    v_PERCENTUAL_IMPOSTO PRODUTO_VENDA_EXERCICIO.PERCENTUAL_IMPOSTO%type;
BEGIN
    SELECT PRECO, QUANTIDADE, PERCENTUAL_IMPOSTO
    INTO v_PRECO, v_QUANTIDADE, v_PERCENTUAL_IMPOSTO
    FROM PRODUTO_VENDA_EXERCICIO WHERE ID = p_ID;
    
    p_VALOR_IMPOSTO := NVL(v_PRECO,0) * NVL(v_QUANTIDADE,0) * (NVL(v_PERCENTUAL_IMPOSTO,0) / 100);

EXCEPTION
    WHEN NO_DATA_FOUND THEN
        p_VALOR_IMPOSTO := 0;
        DBMS_OUTPUT.PUT_LINE('Aviso: O ID ' || p_ID || ' não foi encontrado.');
    WHEN OTHERS THEN
        p_VALOR_IMPOSTO := 0;
        DBMS_OUTPUT.PUT_LINE('Erro inesperado: ' || SQLERRM);
END;

2. Formatação da Saída de Valores

No bloco anônimo de teste, você concatenou o texto com o valor bruto. Como estamos lidando com dinheiro, uma dica legal para os seus próximos relatórios ou testes é utilizar a função TO_CHAR combinado com uma máscara de formato. Isso ajuda a garantir que casas decimais apareçam corretamente (como R$750,00).

Você pode alterar a linha do seu DBMS_OUTPUT para:

DBMS_OUTPUT.PUT_LINE('O Valor do imposto do produto: ' || v_ID ||  ' é de R$' || TO_CHAR(v_VALOR_IMPOSTO, '999G999D99'));

Isso formata o número no padrão monetário de forma bem elegante.

Seu resultado bateu certinho com os dados da tabela, mostrando que você compreendeu muito bem os conceitos de parâmetros IN e OUT. Continue com esse ótimo desempenho!

Espero que possa ter lhe ajudado!