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

ОБЛАСТЬ ПРИМЕНЕНИЯ: даSQL Server нетБаза данных SQL AzureнетХранилище данных SQL AzureнетParallel Data WarehouseAPPLIES TO: yesSQL Server noAzure SQL Database noAzure SQL Data Warehouse noParallel Data Warehouse

Точность представляет собой количество цифр в числе.Precision is the number of digits in a number. Масштаб представляет собой количество цифр справа от десятичной запятой в числе.Scale is the number of digits to the right of the decimal point in a number. Например, у числа 123,45 точность равна 5, а масштаб равен 2.For example, the number 123.45 has a precision of 5 and a scale of 2.

В среде SQL ServerSQL Server минимальная точность типов данных numeric и decimal по умолчанию составляет 38 разрядов.In SQL ServerSQL Server, the default maximum precision of numeric and decimal data types is 38. В более ранних версиях SQL ServerSQL Server максимум по умолчанию составляет 28.In earlier versions of SQL ServerSQL Server, the default maximum is 28.

Длиной для числовых типов данных является количество байт, используемых для хранения числа.Length for a numeric data type is the number of bytes that are used to store the number. Длина символьной строки или данных в Юникоде равняется количеству символов.Length for a character string or Unicode data type is the number of characters. Длина для типов данных binary, varbinary и image равна количеству байт.The length for binary, varbinary, and image data types is the number of bytes. Например, тип данных int может содержать 10 разрядов, храниться в 4 байтах и не должен содержать десятичный разделитель.For example, an int data type can hold 10 digits, is stored in 4 bytes, and doesn't accept decimal points. Тип данных int имеет точность 10, длину 4 и масштаб 0.The int data type has a precision of 10, a length of 4, and a scale of 0.

При сцеплении двух выражений типа char, varchar, binary или varbinary длина результирующего выражения является суммой длин двух исходных выражений и не превышает 8000 символов.When concatenating two char, varchar, binary, or varbinary expressions, the length of the resulting expression is the sum of the lengths of the two source expressions, up to 8,000 characters.

При сцеплении двух выражений типа nchar или nvarchar длина результирующего выражения является суммой длин двух исходных выражений и не превышает 4000 символов.When concatenating two nchar or nvarchar expressions, the length of the resulting expression is the sum of the lengths of the two source expressions, up to 4,000 characters.

При сравнении двух выражений одного и того же типа данных, но разной длины, с помощью UNION, EXCEPT или INTERSECT длина результата будет равняться длине большего из двух выражений.When comparing two expressions of the same data type but different lengths by using UNION, EXCEPT, or INTERSECT, the resulting length is the longer of the two expressions.

Точность и масштаб числовых типов данных, кроме decimal, фиксированы.The precision and scale of the numeric data types besides decimal are fixed. Если арифметический оператор использует два выражения одного и того же типа, результат будет иметь тот же тип данных с точностью и масштабом, определенными для этого типа.When an arithmetic operator has two expressions of the same type, the result has the same data type with the precision and scale defined for that type. Если оператор объединяет два выражения с различными числовыми типами данных, тип данных результата будет определяться правилами старшинства типов данных.If an operator has two expressions with different numeric data types, the rules of data type precedence define the data type of the result. Результат имеет точность и масштаб, определенные для этого типа данных.The result has the precision and scale defined for its data type.

В приведенной ниже таблице показано, как вычисляется точность и масштаб результата, если результат операции имеет тип decimal.The following table defines how the precision and scale of the result are calculated when the result of an operation is of type decimal. Результат имеет тип decimal, если выполняется одно из следующих условий:The result is decimal when either:

  • Оба выражения имеют тип decimal.Both expressions are decimal.
  • Одно выражение имеет тип decimal, а другое имеет тип данных со старшинством меньше, чем decimal.One expression is decimal and the other is a data type with a lower precedence than decimal.

Операнды выражений обозначены как выражение e1 с точностью p1 и масштабом s2 и выражение e2 с точностью p2 и масштабом s2.The operand expressions are denoted as expression e1, with precision p1 and scale s1, and expression e2, with precision p2 and scale s2. Точность и масштаб для любого выражения, отличного от decimal, соответствуют типу данных этого выражения.The precision and scale for any expression that is not decimal is the precision and scale defined for the data type of the expression. Функция max(a,b) принимает большее из значений a и b.The function max(a,b) means the following: take the greater value of "a" or "b". Аналогичным образом функция min(a,b) принимает меньшее из значений a и b.Similarly, min(a,b) indicates to take the smaller value of "a" or "b".

ОперацияOperation Точность результатаResult precision Масштаб результата *Result scale *
e1 + e2e1 + e2 max(s1, s2) + max(p1-s1, p2-s2) + 1max(s1, s2) + max(p1-s1, p2-s2) + 1 max(s1, s2)max(s1, s2)
e1 - e2e1 - e2 max(s1, s2) + max(p1-s1, p2-s2) + 1max(s1, s2) + max(p1-s1, p2-s2) + 1 max(s1, s2)max(s1, s2)
e1 * e2e1 * e2 p1 + p2 + 1p1 + p2 + 1 s1 + s2s1 + s2
e1 / e2e1 / e2 p1 - s1 + s2 + max(6, s1 + p2 + 1)p1 - s1 + s2 + max(6, s1 + p2 + 1) max(6, s1 + p2 + 1)max(6, s1 + p2 + 1)
e1 { UNION | EXCEPT | INTERSECT } e2e1 { UNION | EXCEPT | INTERSECT } e2 max(s1, s2) + max(p1-s1, p2-s2)max(s1, s2) + max(p1-s1, p2-s2) max(s1, s2)max(s1, s2)
e1 % e2e1 % e2 min(p1-s1, p2 -s2) + max( s1,s2 )min(p1-s1, p2 -s2) + max( s1,s2 ) max(s1, s2)max(s1, s2)

* Точность и масштаб результата имеют абсолютный максимум, равный 38.* The result precision and scale have an absolute maximum of 38. Если точность результата превышает 38, она уменьшается до 38 и уменьшается соответствующий масштаб, чтобы по возможности предотвратить усечение целой части результата.When a result precision is greater than 38, it's reduced to 38, and the corresponding scale is reduced to try to prevent truncating the integral part of a result. В некоторых случаях, например при умножении или делении, масштаб не уменьшается, чтобы сохранить десятичную точность, хотя при этом может возникнуть ошибка переполнения.In some cases such as multiplication or division, scale factor won't be reduced, to maintain decimal precision, although the overflow error can be raised.

При выполнении операций сложения и вычитания требуется max(p1 - s1, p2 - s2) разрядов для хранения целой части числа с десятичной дробью.In addition and subtraction operations, we need max(p1 - s1, p2 - s2) places to store integral part of the decimal number. Если места для ее хранения недостаточно, то есть max(p1 - s1, p2 - s2) < min(38, precision) - scale, масштаб уменьшается, чтобы места для целой части хватало.If there isn't enough space to store them that is, max(p1 - s1, p2 - s2) < min(38, precision) - scale, the scale is reduced to provide enough space for integral part. Итоговый масштаб будет равен MIN(precision, 38) - max(p1 - s1, p2 - s2), поэтому дробная часть может округляться, чтобы соответствовать этому масштабу.Resulting scale is MIN(precision, 38) - max(p1 - s1, p2 - s2), so the fractional part might be rounded to fit into the resulting scale.

При выполнении операций умножения и деления требуется precision - scale разрядов для хранения целой части результата.In multiplication and division operations, we need precision - scale places to store the integral part of the result. Масштаб может уменьшаться согласно приведенным ниже правилам.The scale might be reduced using the following rules:

  1. Итоговый масштаб уменьшается до min(scale, 38 - (precision-scale)), если целая часть короче 32 разрядов, так как он не может быть больше 38 - (precision-scale).The resulting scale is reduced to min(scale, 38 - (precision-scale)) if the integral part is less than 32, because it can't be greater than 38 - (precision-scale). В этом случае результат может округляться.Result might be rounded in this case.
  2. Масштаб не изменяется, если он меньше 6 и если целая часть длиннее 32 разрядов.The scale won't be changed if it's less than 6 and if the integral part is greater than 32. В этом случае может возникнуть ошибка переполнения, если число не помещается в decimal(38, scale).In this case, overflow error might be raised if it can't fit into decimal(38, scale)
  3. Масштаб будет задан равным 6, если он больше 6 и если целая часть длиннее 32 разрядов.The scale will be set to 6 if it's greater than 6 and if the integral part is greater than 32. В этом случае уменьшаются как целая часть, так и масштаб, и итоговым типом будет decimal(38,6).In this case, both integral part and scale would be reduced and resulting type is decimal(38,6). Результат может округляться до 6 десятичных знаков, либо может возникнуть ошибка переполнения, когда целая часть не помещается в 32 разряда.Result might be rounded to 6 decimal places or the overflow error will be thrown if the integral part can't fit into 32 digits.

ПримерыExamples

Следующее выражение возвращает результат 0.00000090000000000 без округления, так как он помещается в decimal(38,17):The following expression returns result 0.00000090000000000 without rounding, because result can fit into decimal(38,17):

select cast(0.0000009000 as decimal(30,20)) * cast(1.0000000000 as decimal(30,20)) [decimal 38,17]

В этом случае точность равна 61, а масштаб — 40.In this case precision is 61, and scale is 40. Целая часть (точность – масштаб = 21) короче 32 разрядов, поэтому это случай (1) в правилах умножения и масштаб вычисляется как min(scale, 38 - (precision-scale)) = min(40, 38 - (61-40)) = 17.Integral part (precision-scale = 21) is less than 32, so this case is case (1) in multiplication rules and scale is calculated as min(scale, 38 - (precision-scale)) = min(40, 38 - (61-40)) = 17. Тип результата — decimal(38,17).Result type is decimal(38,17).

Следующее выражение возвращает результат 0.000001, который помещается в decimal(38,6):The following expression returns result 0.000001 to fit into decimal(38,6):

select cast(0.0000009000 as decimal(30,10)) * cast(1.0000000000 as decimal(30,10)) [decimal(38, 6)]

В этом случае точность равна 61, а масштаб — 20.In this case precision is 61, and scale is 20. Масштаб больше 6, а целая часть (precision-scale = 41) длиннее 32 разрядов.Scale is greater than 6 and integral part (precision-scale = 41) is greater than 32. Это случай (3) в правилах умножения, и типом результата будет decimal(38,6).This case is case (3) in multiplication rules and result type is decimal(38,6).

См. также разделSee also

Выражения (Transact-SQL)Expressions (Transact-SQL)
Типы данных (Transact-SQL)Data Types (Transact-SQL)