Точность, масштаб и длина (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
илиEXCEPT
INTERSECT
результирующей длины больше двух выражений.
Замечания
Точность и масштаб числовых типов данных, кроме decimal, фиксированы. Если арифметический оператор использует два выражения одного и того же типа, результат будет иметь тот же тип данных с точностью и масштабом, определенными для этого типа. Если оператор объединяет два выражения с различными числовыми типами данных, тип данных результата будет определяться правилами старшинства типов данных. Результат имеет точность и масштаб, определенные для этого типа данных.
В приведенной ниже таблице показано, как вычисляется точность и масштаб результата, если результат операции имеет тип decimal. Результат имеет тип decimal, если выполняется одно из следующих условий:
- Оба выражения имеют тип decimal.
- Одно выражение имеет тип decimal, а другое имеет тип данных со старшинством меньше, чем decimal.
Выражения операнда обозначаются как выражение с точностью p1
и масштабированием, а также выражением e2
с точностью p2
и масштабированиемs2
s1
.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
разрядов для хранения целой части результата. Масштаб может уменьшаться согласно приведенным ниже правилам.
- Итоговый масштаб уменьшается до
min(scale, 38 - (precision-scale))
, если целая часть короче 32 разрядов, так как он не может быть больше38 - (precision-scale)
. Результат может быть округлен в этом случае. - Масштаб не изменяется, если оно меньше 6 и если целочисленная часть больше 32. В этом случае может возникнуть ошибка переполнения, если она не может соответствовать десятичному (38, масштабу).
- Масштаб имеет значение 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).