Skip to main content

Command Palette

Search for a command to run...

Cuidado com MONEY e SMALLMONEY no Microsoft SQL Server

Published
Cuidado com MONEY e SMALLMONEY 
no Microsoft SQL Server
S

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

  1. 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 com CAST/ROUND no ponto de apresentação.

  2. 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 DECIMAL com escala consistente; arredonde apenas ao exibir.

  3. DW e processos ETL

    • Agregações pesadas + MONEY = risco de divergência.

    • Solução: modelagem de fatos com DECIMAL(19,4) (valores) e DECIMAL(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) ou CAST(... 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 e DECIMAL(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!

More from this blog

S

SQL Server Expert

30 posts

O SQL Server Expert é o blog oficial do Prof. Landry Duailibe, dedicado a profissionais de dados que desejam dominar o Microsoft SQL Server em profundidade.