Compartilhar via


Precisão, escala e comprimento (Transact-SQL)

Aplica-se a: SQL Server Banco de Dados SQL do Azure Instância Gerenciada de SQL do Azure Azure Synapse Analytics PDW (Analytics Platform System) Ponto de extremidade de análise de SQL no Microsoft Fabric Warehouse no Microsoft Fabric

A precisão é o número de dígitos em um número. A escala é o número de dígitos à direita da casa decimal em um número. Por exemplo, o número 123.45 tem uma precisão de 5 e uma escala de 2.

Em SQL Server, a precisão máxima padrão dos tipos de dados numeric e decimal é 38.

O comprimento de um tipo de dados numérico é o número de bytes usado para armazenar o número. Para varchar e char, o tamanho de uma cadeia de caracteres é o número de bytes. Para nvarchar e nchar, o comprimento da cadeia de caracteres é o número de pares de bytes. O comprimento para os tipos de dados binary, varbinary e image é o número de bytes. Por exemplo, um tipo de dados int pode conter 10 dígitos, é armazenado em 4 bytes e não aceita casas decimais. O tipo de dados int tem uma precisão de 10, um comprimento de 4 e uma escala de 0.

  • Ao concatenar duas expressões char, varchar, binary ou varbinary, o tamanho da expressão resultante é a soma dos tamanhos das duas expressões de origem, até 8 mil bytes.

  • Ao concatenar duas expressões nchar ou nvarchar, o tamanho da expressão resultante é a soma dos tamanhos das duas expressões de origem, até 4 mil pares de bytes.

  • Ao comparar duas expressões do mesmo tipo de dados, mas diferentes comprimentos usando UNION, EXCEPT ou INTERSECT, o comprimento resultante é o mais longo das duas expressões.

Comentários

A precisão e a escala dos tipos de dados numéricos além de decimal são fixos. Quando um operador aritmético tiver duas expressões do mesmo tipo, o resultado terá o mesmo tipo de dados com precisão e escala definidas para esse tipo. Se um operador aritmético tiver duas expressões com tipos de dados numéricos diferentes, a regras de precedência do tipo de dados definirão os tipos de dados do resultado. O resultado terá a precisão e a escala definidas para seu tipo de dados.

A tabela a seguir define como a precisão e a escala do resultado são calculadas quando o resultado de uma operação é do tipo decimal. O resultado será decimal quando qualquer um dos:

  • As duas expressões são do tipo decimal.
  • Uma expressão é decimal e a outra é um tipo de dados com uma precedência inferior a decimal.

As expressões de operandos são indicadas como expressão e1, com precisão p1 e escala s1, e expressão e2, com precisão p2 e escala s2. A precisão e a escala de qualquer expressão que não seja decimal serão aquelas definidas para o tipo de dados da expressão. A função max(a, b) indica para obter o valor maior de a ou b. Da mesma forma, min(a, b) obterá o menor valor de a ou b.

Operação Precisão de resultado Escala de resultado 1
e1 + e2 max(s1, s2) + max(p1 - s1, p2 - s2) + 1 máx(s1, s2)
e1 - e2 max(s1, s2) + max(p1 - s1, p2 - s2) + 1 máx(s1, s2)
e1 * e2 p1 + p2 + 1 s1 + s2
e1 / e2 p1 - s1 + s2 + máx(6, s1 + p2 + 1) máx(6, s1 + p2 + 1)
e1 { UNION | EXCEPT | INTERSECT } e2 max(s1, s2) + max(p1 - s1, p2 - s2) máx(s1, s2)
e1 % e2 min(p1 - s1, p2 - s2) + max(s1, s2) máx(s1, s2)

1 A precisão e a escala de resultado têm um máximo absoluto de 38. Quando uma precisão de resultado for maior que 38, ela será reduzida para 38 e a escala correspondente será reduzida para tentar evitar o truncamento da parte integral de um resultado. Em alguns casos, como multiplicação ou divisão, o fator de escala não é reduzido para manter a precisão decimal, embora o erro de estouro possa ser gerado.

Em operações de adição e de subtração, precisamos de max(p1 - s1, p2 - s2) casas para armazenar a parte integral do número decimal. Se não houver espaço suficiente para armazená-los, (ou seja, max(p1 - s1, p2 - s2) < min(38, precision) - scale), a escala será reduzida para fornecer espaço suficiente para a parte integral. A escala resultante será min(precision, 38) - max(p1 - s1, p2 - s2), portanto, a parte fracionária poderá ser arredondada para se ajustar à escala resultante.

Em operações de multiplicação e divisão, precisamos de precision - scale casas para armazenar a parte integral do resultado. A escala pode ser reduzida usando as seguintes regras:

  1. A escala resultante será reduzida para min(scale, 38 - (precision-scale)) se a parte integral for menor que 32, pois ela não poderá ser maior que 38 - (precision-scale). Nesse caso, o resultado pode ser arredondado.
  2. A escala não é alterada se for inferior a 6 e se a parte integral for maior que 32. Nesse caso, o erro de estouro poderá ser gerado se ela não couber em decimal(38, scale).
  3. A escala é definida como 6 se for maior do que 6 e se a parte integral for maior do que 32. Nesse caso, tanto a parte integral quanto a escala seriam reduzidas e o tipo resultante seria decimal (38, 6). O resultado pode ser arredondado para 7 casas decimais ou o erro de estouro é gerado se a parte integral não couber em 32 dígitos.

Exemplos

A expressão a seguir retorna o resultado 0.00000090000000000 sem arredondamento, pois o resultado cabe em (38, 17):

SELECT CAST(0.0000009000 AS DECIMAL(30, 20)) * CAST(1.0000000000 AS DECIMAL(30, 20)) [decimal(38, 17)];

Neste caso, a precisão é de61 e escala é de 40.

A parte integral (precision-scale = 21) é menor que 32, então este caso é o primeiro caso nas regras de multiplicação, e a escala é calculada como min(scale, 38 - (precision-scale)) = min(40, 38 - (61-40)) = 17. O tipo de resultado é decimal(38, 17).

A expressão a seguir retorna o resultado 0.000001 para caber em decimal(38, 6):

SELECT CAST(0.0000009000 AS DECIMAL(30, 10)) * CAST(1.0000000000 AS DECIMAL(30, 10)) [decimal(38, 6)];

Neste caso, a precisão é de 61 e escala é de 20.

A escala é maior do que 6 e a parte integral (precision-scale = 41) é maior do que 32. Esse caso é o terceiro caso nas regras de multiplicação e o tipo de resultado é decimal(38, 6).

Confira também