GARANTIR DESCONTO

Fórum Problema Divisão retorna Zero #523852

23/06/2015

0

Galera, estou com um store procedure no firebird 2.5, onde eu preciso fazer um calculo de tendencia, mas o resultado do mesmo esta me retornando zero. Acredito que seja alguma logica matemática. Já tentei converter com CAST, mas não consegui.

O campo dias_decorridos é inteiro e preciso divido por um campo numeric(18,2), assim como fazemos no excel.


CREATE OR ALTER PROCEDURE SP_RESULT_METAS_VENDAS (
    dt_ini date,
    dt_fim date)
returns (
    met_id integer,
    data_ini date,
    data_fim date,
    dias_uteis integer,
    dias_decorridos integer,
    fun_id integer,
    fun_apelido varchar(30),
    meta_valor numeric(18,2),
    meta_qtde numeric(9,2),
    meta_qtde_diaria numeric(9,2),
    meta_valor_diaria numeric(18,2),
    qtde_pedidos numeric(9,2),
    valor_pedidos numeric(18,2),
    resultado_qtde numeric(9,2),
    resultado_valor numeric(18,2),
    perc_result_qtde numeric(5,2),
    perc_result_valor numeric(5,2),
    tendencia numeric(18,2),
    perc_tendencia numeric(5,2),
    equ_id integer,
    equipe varchar(44),
    responsavel integer,
    responsavel_nome varchar(30),
    obs varchar(200),
    status integer,
    data_cad timestamp,
    data_alt timestamp,
    loj_id integer,
    loj_nome varchar(30),
    usu_id integer,
    usu_login varchar(20))
as
declare variable v1 numeric(18,2);
declare variable v2 numeric(18,2);
BEGIN
  FOR
    select 
        metas_vendas.met_id,
        metas_vendas.data_ini,
        metas_vendas.data_fim,
        (SELECT uteis FROM NUM_DIAS_UTEIS(metas_vendas.data_ini, metas_vendas.data_fim, 'FORTALEZA', 'CE')),
        current_date - metas_vendas.data_ini,
        metas_vendas.fun_id,
        funcionarios.fun_apelido,
        metas_vendas.meta_valor,
        metas_vendas.meta_qtde,
        metas_vendas.equ_id,
        equipes.equipe,
        equipes.fun_id AS RESPONSAVEL,
        (SELECT FUNCIONARIOS.FUN_APELIDO FROM FUNCIONARIOS WHERE FUNCIONARIOS.FUN_ID = EQUIPES.FUN_ID) AS RESPONSAVEL_NOME,
        metas_vendas.obs,
        metas_vendas.status,
        metas_vendas.data_cad,
        metas_vendas.data_alt,
        metas_vendas.loj_id,
        lojas.loj_nome,
        metas_vendas.usu_id,
        usuarios.usu_login
    from metas_vendas
       inner join funcionarios on (metas_vendas.fun_id = funcionarios.fun_id)
       left join equipes on (metas_vendas.equ_id = equipes.equ_id)
       inner join lojas on (metas_vendas.loj_id = lojas.loj_id)
       inner join usuarios on (metas_vendas.usu_id = usuarios.usu_id)
    where
        cast(metas_vendas.data_ini as date) between :dt_ini and :dt_fim and
        cast(metas_vendas.data_fim as date) between :dt_ini and :dt_fim
    INTO :MET_ID,
         :DATA_INI,
         :DATA_FIM,
         :dias_uteis,
         :dias_decorridos,
         :FUN_ID,
         :FUN_APELIDO,
         :META_VALOR,
         :META_QTDE,
         :EQU_ID,
         :EQUIPE,
         :RESPONSAVEL,
         :RESPONSAVEL_NOME,
         :OBS,
         :STATUS,
         :DATA_CAD,
         :DATA_ALT,
         :LOJ_ID,
         :LOJ_NOME,
         :USU_ID,
         :USU_LOGIN
  DO


  FOR
    select
         sum(pedidos_itens.pi_qtde) ,
         sum(pedidos_itens.pi_total)
    from pedidos
    inner join pedidos_itens on (pedidos.ped_id = pedidos_itens.ped_id)
    inner join produtos on (pedidos_itens.prod_id = produtos.prod_id)
    left join fornecedor on (produtos.for_id = fornecedor.for_id)
    where
        pedidos.status = 1 and
        pedidos.tipo_id < 5 and
        cast(pedidos.data_emissao as date) between :dt_ini and :dt_fim  and
        pedidos.fun_id = :fun_id

    INTO  :QTDE_PEDIDOS,
          :VALOR_PEDIDOS
  DO



  BEGIN
    if (QTDE_PEDIDOS > 0) then
    begin
      RESULTADO_QTDE  =  QTDE_PEDIDOS - META_QTDE;
      perc_result_qtde = (QTDE_PEDIDOS / META_QTDE)*100;
    end
    else RESULTADO_QTDE  = 0;
    if (VALOR_PEDIDOS > 0) then
    begin
       RESULTADO_VALOR =  VALOR_PEDIDOS - META_VALOR;
       perc_result_valor = (VALOR_PEDIDOS / META_VALOR)*100;
    end
    else RESULTADO_VALOR =0;

    meta_qtde_diaria  = META_QTDE / dias_uteis;
    meta_valor_diaria = META_VALOR / dias_uteis ;

    v1 = (META_VALOR * iif(VALOR_PEDIDOS < 0,VALOR_PEDIDOS*-1,VALOR_PEDIDOS));

    perc_tendencia = CAST((dias_decorridos  / v1) as numeric(5,2));

    SUSPEND;
  END
END
Sidney Abreu

Sidney Abreu

Responder

Posts

23/06/2015

Dorivan Sousa

dias atras eu tentei fazer
select 5/10 from rdb$database


e o firebird retornava zero... ai eu tentei

select cast(5 as numeric(12,2))/10 from rdb$database


e retornou 0.5

aqui linha 134
perc_tendencia = CAST((dias_decorridos  / v1) as numeric(5,2));


voce ta fazendo o cast no resultado, tenta fazer o cast do dias_corrido e depois dividir
aqui
perc_tendencia = CAST(dias_decorridos as numeric(5,2))  / v1 ;
Responder

Gostei + 0

23/06/2015

Sidney Abreu

fiz assim:

perc_tendencia = CAST(dias_decorridos as numeric(5,2)) / v1;

Não deu certo ainda
Responder

Gostei + 0

23/06/2015

Dorivan Sousa

coloca essas variaveis
v1, dias_decorridos

pra retornar na stored procedure pra conferir os valores.
Responder

Gostei + 0

23/06/2015

Sidney Abreu

Ja fiz, e estão retornando correto.
Responder

Gostei + 0

23/06/2015

Dorivan Sousa

numeric(5,2)

coloca

numeric(18,6)

vai que a divisao é um resultando 0.00001

coloca tambem na declaracao da variavel no cabecalho da procedure
Responder

Gostei + 0

23/06/2015

Isaac Jose

Boa tarde essa tabela tem falores nullos
Responder

Gostei + 0

23/06/2015

Sidney Abreu

Infelizmente não é, o resultado do v1 = 1799973000, dias = 22

22/1799973000 era pra ser 1,2222....

sei que inteiro com inteiro retorna inteiro, e qualquer coisa com real, retorna real.

Mas não consigo entender a lógica do firebird
Responder

Gostei + 0

23/06/2015

Dorivan Sousa

voce alterou ao perc_tendencia para numeric(18,6)?

faz no ibo esse codigo abaixo e retorna 0

select 22/1799973000 from rdb$database;

se fizer

select cast(22 as numeric(18,6))/1799973000 from rdb$database

retorna 0,000000

agora quando eu faço
select cast(22 as numeric(18,6))/cast(1799973000 as numeric(18,6)) from rdb$database

retorna 0,000000012222

q é o valor correto pois nao tem como 22 dividido pra 1799973000 ser 1,2222 o resultado é 1,22224055583056e-8 isso é uma notacao cientifica observa o e-8 no final
Responder

Gostei + 0

23/06/2015

Sidney Abreu

Fiz assim:
v1 = META_VALOR * iif(VALOR_PEDIDOS < 0,VALOR_PEDIDOS*-1,VALOR_PEDIDOS);

v2 = cast(dias_decorridos as numeric(18,6)) / cast(v1 as numeric(18,6));

tendencia = v1;
perc_tendencia = v2 ;

tendencia e perc_tendencia ambos estão numeric(18,6), não existe valor null, ainda assim nao funcionou
Responder

Gostei + 0

23/06/2015

Dorivan Sousa

perc_tendencia ainda ta numeric(5,2) na declaracao da procedure? deve ser numeric(18,6) pelo menos.

interessante uso firebird ha algum tempo e mais engraçado é que passei por uma situacao parecida semana passada e simplismente ignorei e resolvi de outra forma.
http://www.firebirdfaq.org/faq219/

sobre notacao cientifica

A notação científica serve para expressar números muito grandes ou muito pequenos. O segredo é multiplicar um numero pequeno por uma potência de 10.
A forma de uma Notação científica é: m . 10 e, onde m significa mantissa e E significa ordem de grandeza. A mantissa SEMPRE será um valor em módulo entre 1 e 10.

Transformando
Para transformar um numero grande qualquer em notação cientifica, devemos deslocar a vírgula para a esquerda até o primeiro algarismo desta forma:

200 000 000 000 » 2,00 000 000 000

note que a vírgula avançou 11 casas para a esquerda, então em notação científica este numero fica: 2 . 1011.

Para com valores muito pequenos, é só mover a virgula para a direita, e a cada casa avançada, diminuir 1 da ordem de grandeza:

0,0000000586 » movendo a virgula para direita » 5,86 (avanço de 8 casas) » 5,86 . 10-8

-12.000.000.000.000 » -1,2 . 1013


no caso do resultado 22 / 1799973000 = 1,22224055583056e-8 seria 0,0000000122224055583056 mover a virgula 8 casas a esquerda e preenchendo de zeros o espaço.
Responder

Gostei + 0

23/06/2015

Sidney Abreu

estão todos numeric(18,6)

CREATE PROCEDURE SP_RESULT_METAS_VENDAS (
dt_ini date,
dt_fim date)
returns (
met_id integer,
data_ini date,
data_fim date,
dias_uteis integer,
dias_decorridos integer,
fun_id integer,
fun_apelido varchar(30),
meta_valor numeric(18,2),
meta_qtde numeric(9,2),
meta_qtde_diaria numeric(9,2),
meta_valor_diaria numeric(18,2),
qtde_pedidos numeric(9,2),
valor_pedidos numeric(18,2),
resultado_qtde numeric(9,2),
resultado_valor numeric(18,2),
perc_result_qtde numeric(5,2),
perc_result_valor numeric(5,2),
tendencia numeric(18,6),
perc_tendencia numeric(18,6),
equ_id integer,
equipe varchar(44),
responsavel integer,
responsavel_nome varchar(30),
obs varchar(200),
status integer,
data_cad timestamp,
data_alt timestamp,
loj_id integer,
loj_nome varchar(30),
usu_id integer,
usu_login varchar(20))
as
declare variable v1 numeric(18,6);
declare variable v2 numeric(18,6);
Responder

Gostei + 0

23/06/2015

Sidney Abreu

estão todos numeric(18,6)

CREATE PROCEDURE SP_RESULT_METAS_VENDAS (
dt_ini date,
dt_fim date)
returns (
met_id integer,
data_ini date,
data_fim date,
dias_uteis integer,
dias_decorridos integer,
fun_id integer,
fun_apelido varchar(30),
meta_valor numeric(18,2),
meta_qtde numeric(9,2),
meta_qtde_diaria numeric(9,2),
meta_valor_diaria numeric(18,2),
qtde_pedidos numeric(9,2),
valor_pedidos numeric(18,2),
resultado_qtde numeric(9,2),
resultado_valor numeric(18,2),
perc_result_qtde numeric(5,2),
perc_result_valor numeric(5,2),
tendencia numeric(18,6),
perc_tendencia numeric(18,6),
equ_id integer,
equipe varchar(44),
responsavel integer,
responsavel_nome varchar(30),
obs varchar(200),
status integer,
data_cad timestamp,
data_alt timestamp,
loj_id integer,
loj_nome varchar(30),
usu_id integer,
usu_login varchar(20))
as
declare variable v1 numeric(18,6);
declare variable v2 numeric(18,6);
Responder

Gostei + 0

23/06/2015

Dorivan Sousa

no caso eu errei, pq o resultado é 0,0000000122224055583056 entao pegando 6 casas decimais fica 0.000000 pra mostrar qualquer dado teria q ter pelo menos 8 casas decimais e ainda mostraria 0,00000001.... coloca 18,10 pra v se mostra alguma coisa..
Responder

Gostei + 0

23/06/2015

Isaac Jose

no Sql faço verificação de valores nullos e zerados e os ignoro para que o calculo possa prosseguir.
mais nao tenho conhecimento de Fire.
Responder

Gostei + 0

23/06/2015

Sidney Abreu

Quando coloquei a v1 numeric(18,10) deu erro Arithmetic exception, numeric overflow, or string truncation
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar