2
respostas

Resultado FLOAT com Cursor em Procedure

Gostaria de saber o que eu poderia alterar na Procedure seguinte para obter o resultado do faturamento como FLOAT e não INT.

CREATE PROCEDURE `mais_um_campo`()
BEGIN
    DECLARE QUANTIDADE INT;
    DECLARE PRECO FLOAT;
    DECLARE FATURAMENTOACUM FLOAT;
    DECLARE fim_do_cursor INT;
    DECLARE c CURSOR FOR
    SELECT INF.QUANTIDADE, INF.PRECO FROM ITENS_NOTAS_FISCAIS INF
    INNER JOIN NOTAS_FISCAIS  NF ON NF.NUMERO = INF.NUMERO
    WHERE MONTH(NF.DATA_VENDA) = 1 AND YEAR(NF.DATA_VENDA) = 2017;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET fim_do_cursor = 1;

    OPEN c;
        SET fim_do_cursor = 0;
        SET FATURAMENTOACUM = 0;
        WHILE fim_do_cursor = 0
        DO
            FETCH c INTO QUANTIDADE, PRECO;
            IF fim_do_cursor = 0 THEN
                SET FATURAMENTOACUM = FATURAMENTOACUM + (QUANTIDADE * PRECO);
            END IF;
        END WHILE;
    CLOSE c;
    SELECT FATURAMENTOACUM;
END
2 respostas

Tente fazer a conversão de todos os fatores para float. Ficaria da seguinte forma:

De:

SET FATURAMENTOACUM = FATURAMENTOACUM + (QUANTIDADE * PRECO);

Para:

SET FATURAMENTOACUM = CAST(FATURAMENTOACUM as FLOAT) + (CAST(QUANTIDADE as FLOAT) * CAST(PRECO as FLOAT));

Olá Igor!

Nessa Stored Procedure você já está obtendo o faturamento com FLOAT, note que a variável que acumula o faturamento é declarada como FLOAT:

DECLARE FATURAMENTOACUM FLOAT;

Então o faturamento no final de todo o loop é do tipo FLOAT, mas estranhamento o resultado aparece como um inteiro, essa reação é causa pelo fato que no MySQL "valores de ponto flutuante (FLOAT ) são aproximados e não são armazenados como valores exatos, as tentativas de tratá-los como exatos nas comparações podem levar a problemas. Eles também estão sujeitos a dependências de plataforma ou implementação." Segundo própria documentação do MySQL. Então é isso que está deixando o resultado como um número inteiro, então acho que você deveria usar a variável FATURAMENTOACUM como DECIMAL(18,14):

DECLARE FATURAMENTOACUM DECIMAL(18,14);

"As variáveis do tipo DECIMAL armazenam valores de dados numéricos exatos", assim você vai conseguir chegar ao número exato. E coloquei como 18 de precisão e 14 de escala, porque se executarmos o comando:

SELECT MAX(INF.QUANTIDADE * INF.PRECO) FROM ITENS_NOTAS_FISCAIS INF
INNER JOIN NOTAS_FISCAIS  NF ON NF.NUMERO = INF.NUMERO
WHERE MONTH(NF.DATA_VENDA) = 1 AND YEAR(NF.DATA_VENDA) = 2017;

Teremos como resultado "4214.766460418701", assim é uma margem bem grande para poder chegar o mais próximo possível do exato.

Espero que tenha ajudado!

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software