Точность, масштаб и длина (Transact-SQL)

Область применения: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure конечной точке аналитики платформы Аналитики Azure Synapse Analytics (PDW) в Microsoft Fabric Хранилище в Microsoft Fabric

Точность представляет собой количество цифр в числе. Масштаб представляет собой количество цифр справа от десятичной запятой в числе. Например, число 123.45 имеет точность 5 и масштаб 2.

В SQL Server максимальная точность числовых и десятичных типов данных по умолчанию составляет 38.

Длиной для числовых типов данных является количество байт, используемых для хранения числа. Для varchar и char длина символьной строки — это количество байтов. Для nvarchar и nchar длина строки символа — это количество пар байтов. Длина для типов данных binary, varbinary и image равна количеству байт. Например, тип данных int может содержать 10 разрядов, храниться в 4 байтах и не должен содержать десятичный разделитель. Тип данных int имеет точность 10, длину 4 и масштаб 0.

  • При объединения двух выражениях char, varchar, binary или varbinary длина результирующего выражения — это сумма длины двух исходных выражений до 8 000 байт.

  • При объединения двух выражениях nchar или nvarchar длина результирующего выражения — это сумма длины двух исходных выражений до 4000 байтовых пар.

  • При сравнении двух выражений одного типа данных, но разных длин с помощью UNIONили EXCEPTINTERSECTрезультирующей длины больше двух выражений.

Замечания

Точность и масштаб числовых типов данных, кроме decimal, фиксированы. Если арифметический оператор использует два выражения одного и того же типа, результат будет иметь тот же тип данных с точностью и масштабом, определенными для этого типа. Если оператор объединяет два выражения с различными числовыми типами данных, тип данных результата будет определяться правилами старшинства типов данных. Результат имеет точность и масштаб, определенные для этого типа данных.

В приведенной ниже таблице показано, как вычисляется точность и масштаб результата, если результат операции имеет тип decimal. Результат имеет тип decimal, если выполняется одно из следующих условий:

  • Оба выражения имеют тип decimal.
  • Одно выражение имеет тип decimal, а другое имеет тип данных со старшинством меньше, чем decimal.

Выражения операнда обозначаются как выражение с точностью p1 и масштабированием, а также выражением e2с точностью p2 и масштабированиемs2s1.e1 Точность и масштабирование для любого выражения, которое не является десятичным , является точностью и масштабом, определенным для типа данных выражения. Функция max(a, b) указывает, что требуется большее значение a или b. Аналогичным образом указывает, min(a, b) что требуется принять меньшее значение a или b.

Операция Точность результата Шкала результатов 1
e1 + e2 max(s1, s2) + max(p1 - s1, p2 - s2) + 1 max(s1, s2)
e1 - e2 max(s1, s2) + max(p1 - s1, p2 - s2) + 1 max(s1, s2)
e1 * e2 p1 + p2 + 1 s1 + s2
e1 / e2 p1 - s1 + s2 + max(6, s1 + p2 + 1) max(6, s1 + p2 + 1)
e1 { UNION | EXCEPT | INTERSECT } e2 max(s1, s2) + max(p1 - s1, p2 - s2) max(s1, s2)
e1 % e2 min(p1 - s1, p2 - s2) + max(s1, s2) max(s1, s2)

1 Точность результата и масштабирование имеют абсолютный максимум 38. Если точность результата превышает 38, она уменьшается до 38 и уменьшается соответствующий масштаб, чтобы по возможности предотвратить усечение целой части результата. В некоторых случаях, таких как умножение или деление, коэффициент масштабирования не уменьшается, чтобы сохранить десятичную точность, хотя ошибка переполнения может быть вызвана.

Кроме того и вычитания операций, нам нужно max(p1 - s1, p2 - s2) место для хранения целой части десятичного числа. Если недостаточно места для хранения (т max(p1 - s1, p2 - s2) < min(38, precision) - scale. е.), масштаб уменьшается, чтобы обеспечить достаточно места для целой части. Результирующий масштаб равен min(precision, 38) - max(p1 - s1, p2 - s2), поэтому дробная часть может быть округлена, чтобы поместиться в результирующий масштаб.

При выполнении операций умножения и деления требуется precision - scale разрядов для хранения целой части результата. Масштаб может уменьшаться согласно приведенным ниже правилам.

  1. Итоговый масштаб уменьшается до min(scale, 38 - (precision-scale)), если целая часть короче 32 разрядов, так как он не может быть больше 38 - (precision-scale). Результат может быть округлен в этом случае.
  2. Масштаб не изменяется, если оно меньше 6 и если целочисленная часть больше 32. В этом случае может возникнуть ошибка переполнения, если она не может соответствовать десятичному (38, масштабу).
  3. Масштаб имеет значение 6, если оно больше 6 и если целочисленная часть больше 32. В этом случае целочисленная часть и масштаб будут сокращены, а результирующий тип — десятичный(38, 6). Результат может быть округлен до 7 десятичных разрядов, или ошибка переполнения возникает, если целочисленная часть не может соответствовать 32 цифрам.

Примеры

Следующее выражение возвращает результат 0.00000090000000000 без округления, так как результат может соответствовать десятичным(38, 17):

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

В этом случае точность имеет значение 61, а масштаб — 40.

Целочисленная часть (precision-scale = 21) меньше 32, поэтому это первый случай в правилах умножения, а масштаб вычисляется как min(scale, 38 - (precision-scale)) = min(40, 38 - (61-40)) = 17. Тип результата — десятичная(38, 17).

Следующее выражение возвращает результат 0.000001 для соответствия десятичным (38, 6):

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

В этом случае точность имеет значение 61, а масштаб — 20.

Масштаб больше 6, а целочисленная часть (precision-scale = 41) больше 32. Это третий случай в правилах умножения, а тип результата — десятичный(38, 6).

См. также