Cuidado com MONEY e SMALLMONEY no Microsoft SQL Server

O Prof. Landry Duailibe é especialista em Microsoft SQL Server desde 1999, Microsoft Certified Trainer, professor universitário e criador do canal SQL Server Expert no YouTube, onde compartilha conteúdo técnico semanal para DBAs e profissionais de dados. Já ajudou milhares de alunos a evoluírem suas habilidades com SQL Server e conquistarem melhores oportunidades na área de dados.
Introdução
MONEY e SMALLMONEY parecem escolhas óbvias quando falamos de valores monetários no SQL Server. Eles existem “para dinheiro”, certo? Nem sempre. Esses tipos têm escala fixa de 4 casas decimais, o que pode introduzir truncamentos, diferenças em cálculos percentuais e variações perceptíveis quando você agrega grandes volumes (fim de mês/ano, relatórios financeiros, DW).
Neste artigo, mostro por que esses tipos podem enganar, comparo com DECIMAL e deixo um guia prático de quando e como evitá-los.
Como o SQL Server lida com MONEY e SMALLMONEY
Precisão/escala: ambos têm escala fixa de 4 casas decimais.
Armazenamento:
SMALLMONEY: 4 bytes, faixa aproximada de ±214 mil.MONEY: 8 bytes, faixa muito maior (bilhões/trilhões).
Impacto prático: operações aritméticas podem cortar resultados na escala de 4 casas (em vez de arredondar como você esperava), e o resultado intermediário pode “herdar” a escala do tipo, levando a diferenças em percentuais e somatórios.
Demonstração: percentual com MONEY vs DECIMAL
Abaixo estão os mesmos dados calculados com MONEY e com DECIMAL(19,4). Repare na diferença de comportamento do resultado:
Consulta 1 — MONEY
DECLARE @MoneyTab TABLE (Total MONEY, Parte MONEY);
INSERT INTO @MoneyTab (Total, Parte)
VALUES (271.00, 199.50), (4639.00, 4316.00), (8031.00, 7862.00);
SELECT Parte, Total, (Parte / total) * 100 AS Percentage
FROM @MoneyTab
go
Consulta 2 — DECIMAL
DECLARE @DecimalTab TABLE (Total DECIMAL(19, 4), Parte DECIMAL(19, 4));
INSERT INTO @DecimalTab (Total, Parte)
VALUES (271.00, 199.50), (4639.00, 4316.00), (8031.00, 7862.00);
SELECT Parte, Total, (Parte / Total) * 100 AS percentage
FROM @DecimalTab
go
Consulta 3 — DECIMAL com CAST (padronizando casas decimais)
DECLARE @DecimalTab TABLE (Total DECIMAL(19, 4), Parte DECIMAL(19, 4));
INSERT INTO @DecimalTab (Total, Parte)
VALUES (271.00, 199.50), (4639.00, 4316.00), (8031.00, 7862.00)
SELECT Parte,Total, cast((Parte / Total) * 100 as decimal(19,2)) AS Percentagem
FROM @DecimalTab
go

O que observar: com MONEY, é comum ver corte na escala e resultados levemente diferentes dos obtidos com DECIMAL. Em somatórios/agrupamentos, a diferença “soma” e pode alterar totais — especialmente perigosos em Data Warehouse e relatórios de fechamento.
Cenários de Atenção
Percentuais e taxas
MONEY tende a cortar em 4 casas; percentuais geralmente pedem 2 (ou mais para taxas).
Solução: calcule em
DECIMAL(p, s)apropriado e defina a escala final comCAST/ROUNDno ponto de apresentação.
Somatórios mensais/anualizados
Pequenas diferenças viram “centavos perdidos” ao somar milhares/milhões de linhas.
Solução: padronize todos os cálculos em
DECIMALcom escala consistente; arredonde apenas ao exibir.
DW e processos ETL
Agregações pesadas + MONEY = risco de divergência.
Solução: modelagem de fatos com
DECIMAL(19,4)(valores) eDECIMAL(19,6)ou maior para taxas (juros/câmbio). Em cenários críticos, considere armazenar o valor em centavos (BIGINT) e só formatar na camada de apresentação.
Boas práticas recomendadas
Prefira DECIMAL:
Valores monetários:
DECIMAL(19,4)atende 99% dos casos.Taxas/percentuais:
DECIMAL(19,6..8)para evitar perda em divisões.
Arredonde conscientemente: use
ROUND(..., 2)ouCAST(... AS DECIMAL(19,2))apenas na etapa final (exibição/entrega).Evite MONEY/SMALLMONEY em DW, relatórios financeiros e pipelines com agregação — o risco de diferenças acumuladas é real.
Padronize a escala no time: defina convenções (ex.: “percentual sempre
DECIMAL(9,4)em cálculo eDECIMAL(5,2)na entrega”).Valide com amostras grandes: antes de subir uma mudança de tipo, rode comparativos em datasets representativos e confira totais.
Conclusão
MONEY e SMALLMONEY funcionam, mas o custo de truncamentos e diferenças em cálculos cresce com o volume de dados e com a necessidade de precisão (percentuais, taxas, somas). Se você busca previsibilidade e controle, opte por DECIMAL e padronize a estratégia de arredondamento.
Fui, mas volto com mais SQL Server em breve!
✍️ Sobre o autor
O Prof. Landry é especialista em Microsoft SQL Server desde 1999, Microsoft Trainer, Professor Universitário e criador do canal SQL Server Expert no YouTube, com conteúdo técnico semanal para DBAs e profissionais de dados.
🚀 Quer aprender mais sobre SQL Server?
👉 Me acompanhe no LinkedIn e inscreva-se no canal para não perder nenhuma dica prática!





