[firebase-br] Numeric x Decimal x Double Precission x Float
Hélio Oliveira
hpensador em gmail.com
Qua Set 4 10:58:45 -03 2013
Bom dia Colegas!
Firebird 2.0
Colegas tenho uma rotina de geração de um relatório gerencial que
reproduzem os valores gerados na SEFIP, porém estou com um problema na
base do arredondamento dos valores. Se trunco (utilizando a SP_Trunc) ou
não, nunca consigo chegar ao valor exato gerado pelo aplicativo SEFIP.
Este relatório é obtido a partir de uma Stored Procedure, já fiz testes
com os tipos NUMERIC e DOUBLE PRECISSION sem obter sucesso.
Qual a experiência de vocês em situações tipicas como esta minha e qual
o melhor tipo a ser utilizado nesta situação. Abaixo a SP na integra.
create or alter procedure GPS (
MES integer,
ANO integer,
SEQUENCIA integer)
returns (
COD_LOTACAO varchar(7),
NOME_LOTACAO varchar(505),
COD_SECRETARIA varchar(7),
NOME_SECRETARIA varchar(50),
QTDE_FUNCIONARIO_LOTACAO integer,
BASE_CALC_INSS numeric(12,2),
VALOR_SALARIO_FAMILIA numeric(12,2),
VALOR_SALARIO_MATERNIDADE numeric(12,2),
VALOR_INSS_EMPRESA numeric(12,2),
VALOR_RAT numeric(12,2),
VALOR_INSS_FUNCIONARIO numeric(12,2),
VALOR_INSS_RECOLHER numeric(12,2))
as
declare variable TOTAL_PROVENTOS_INSS numeric(12,2);
declare variable TOTAL_DESCONTOS_INSS numeric(12,2);
declare variable PERC_INSS_EMPRESA numeric(6,2);
declare variable ALIQUOTA_SAT numeric(6,2);
declare variable ALIQUOTA_FAP numeric(6,2);
declare variable COD_INSS integer;
declare variable CODIGO_SF integer;
declare variable CODIGO_SM integer;
declare variable MATRICULA integer;
declare variable BC_INSS numeric(12,2);
declare variable VLR_INSS double precision;
declare variable VLR_RAT double precision;
begin
select c.codigo_inss,
c.codigo_sal_fam,
c.codigo_sal_mat
from config c
into :cod_inss, codigo_sf, :codigo_sm;
/* Aliquotas de calculo do INSS */
select tm.aliq_fap
from tabela_mensal tm
where tm.mes = :mes
and tm.ano = :ano into :aliquota_fap;
/* */
select ma.percentual_ce,
ma.sefip_sat
from mesano ma
where ma.mes = :mes
and ma.ano = :ano
into :perc_inss_empresa, :aliquota_sat;
/* Neste laço é feita a busca de todos os códigos de lotação
presentes no capa-variavel do mês */
for select distinct cv.codigo_lotacao
from capa_variavel cv
where cv.mes = :mes
and cv.ano = :ano
and cv.sequencia = :sequencia
order by cv.codigo_lotacao
into :cod_lotacao do
begin
/* Código e nome da Secretaria */
select l.codigo,
l.nome
from lotacao l
where l.codigo = substring(:cod_lotacao from 1 for 2) || '00000'
and l.nivel = 1
into :cod_secretaria, :nome_secretaria;
/* Nome da Lotação */
select l.nome
from lotacao l
where l.codigo = :cod_lotacao into :nome_lotacao;
/* Total de Funcionários da Lotação */
select count(matricula)
from capa_variavel cv
where cv.mes = :mes
and cv.ano = :ano
and cv.sequencia = :sequencia
and cv.codigo_lotacao = :cod_lotacao into :qtde_funcionario_lotacao;
base_calc_inss = 0;
valor_inss_empresa = 0;
valor_rat = 0;
for select cv.matricula
from capa_variavel cv
where cv.mes = :mes
and cv.ano = :ano
and cv.sequencia = :sequencia
and cv.codigo_lotacao = :cod_lotacao
order by cv.matricula
into :matricula do
begin
/* Total de proventos que incidem previdência dos Funcionários da
Lotação */
select sum(v.valor)
from variavel v
join funcionario x on (x.codigo = v.matricula and x.previdencia
= 1)
join provento p on (p.codigo = v.provento and p.previdencia =
'S' and p.codigo <= 499)
where v.mes = :mes
and v.ano = :ano
and v.sequencia = :sequencia
and v.matricula = :matricula into :total_proventos_inss;
if (:total_proventos_inss is null) then
total_proventos_inss = 0.00;
/* Total de descontos que incidem previdência dos Funcionários da
Lotação */
select sum(v.valor)
from variavel v
join funcionario x on (x.codigo = v.matricula and x.previdencia
=1)
join provento p on (p.codigo = v.provento and p.previdencia =
'S' and p.codigo >= 500)
where v.mes = :mes
and v.ano = :ano
and v.sequencia = :sequencia
and v.matricula = :matricula into :total_descontos_inss;
if (:total_descontos_inss is null) then
total_descontos_inss = 0.00;
bc_inss = :total_proventos_inss - :total_descontos_inss;
base_calc_inss = :base_calc_inss + :bc_inss;
end
--execute procedure sp_trunc((:base_calc_inss *
(:perc_inss_empresa/100)), 2) returning_values :vlr_inss;
--execute procedure sp_trunc((:base_calc_inss *
((:aliquota_sat*:aliquota_fap)/100)), 2) returning_values :vlr_rat;
vlr_inss = :base_calc_inss * (:perc_inss_empresa/100);
vlr_rat = :base_calc_inss * ((:aliquota_sat*:aliquota_fap)/100);
valor_inss_empresa = :valor_inss_empresa + :vlr_inss;
valor_rat = :vlr_rat;
/* Valor total do INSS dos Funcionários da Lotação */
select sum(v.valor)
from variavel v
join capa_variavel cv on (cv.matricula = v.matricula
and cv.mes = v.mes
and cv.ano = v.ano
and cv.sequencia = v.sequencia)
join funcionario x on (x.codigo = v.matricula and x.previdencia = 1)
where v.mes = :mes
and v.ano = :ano
and v.sequencia = :sequencia
and cv.codigo_lotacao= :cod_lotacao
and v.provento = :cod_inss into :valor_inss_funcionario;
if (:valor_inss_funcionario is null) then
valor_inss_funcionario = 0.00;
/* Valor do Salário Família dos Funcionários da Lotação */
select sum(v.valor)
from variavel v
join capa_variavel cv on (cv.matricula = v.matricula
and cv.mes = v.mes
and cv.ano = v.ano
and cv.sequencia = v.sequencia)
join funcionario x on (x.codigo = v.matricula and x.previdencia = 1)
where v.mes = :mes
and v.ano = :ano
and v.sequencia = :sequencia
and cv.codigo_lotacao = :cod_lotacao
and v.provento = :codigo_sf into :valor_salario_familia;
if (:valor_salario_familia is null) then
valor_salario_familia = 0.00;
/* Valor do Salário Maternidade dos Funcionários da Lotação */
select sum(v.valor)
from variavel v
join capa_variavel cv on (cv.matricula = v.matricula
and cv.mes = v.mes
and cv.ano = v.ano
and cv.sequencia = v.sequencia)
join funcionario x on (x.codigo = v.matricula and x.previdencia = 1)
where v.mes = :mes
and v.ano = :ano
and v.sequencia = :sequencia
and cv.codigo_lotacao= :cod_lotacao
and v.provento = :codigo_sm into :valor_salario_maternidade;
if (:valor_salario_maternidade is null) then
valor_salario_maternidade = 0.00;
/* Calculo do INSS */
valor_inss_recolher = (:valor_inss_empresa + :valor_rat +
:valor_inss_funcionario) -
(:valor_salario_familia +
:valor_salario_maternidade);
suspend;
end
end
Mais detalhes sobre a lista de discussão lista