T-SQL 中十进制计算列的精度

Precision of decimal computed columns in T-SQL

我们曾经在数据库中有以下字段:

FieldA    decimal(19, 2)

我们已将该字段更改为计算字段:

ALTER TABLE MyTable
ADD FieldA AS FieldB * FieldC

其中:

FieldB    decimal(19, 2)
FieldC    decimal(19, 5)

由此产生的新的FieldA:

FieldA    (Computed, decimal(38,6))

遗留代码使用 FieldA 并假设它有两位小数。因此,字符串翻译不应用格式。结果,使用新定义,FieldA 显示为六位小数,这是不可接受的。

是否可以修改计算列的精度(例如,保持原始类型 decimal(19, 2))或者我们是否需要在所有显示值的地方添加适当的格式?

舍入不起作用:

ADD FieldA AS ROUND(FieldB * FieldC, 2)

试试这个:

CREATE TABLE [dbo].[TEST]
(
    [A] DECIMAL(19,2)
   ,[B] DECIMAL(19,5)
   ,[C] AS [A] * [B]
   ,[D] AS CAST([A] * [B] AS DECIMAL(19,2))
);

GO

SELECT *
FROM [sys].[columns]
WHERE [object_id] = OBJECT_ID('[dbo].[TEST]');

为什么?检查 formula 对十进制值执行操作时如何设置小数精度。

所以,我们有:

[A] DECIMAL(19,2)
[B] DECIMAL(19,5)
[C] AS [A] * [B]

公式为:

p1 + p2 + 1 => 2 + 5 + 1 => 7
s1 + s2 => 19 + 19 = > 38

但是:

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. 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. The scale won't be changed if it's less than 6 and if the integral part is greater than 32. In this case, overflow error might be raised if it can't fit into decimal(38, scale)
  3. The scale will be set to 6 if it's greater than 6 and if the integral part is greater than 32. In this case, both integral part and scale would be reduced and resulting type is decimal(38,6). 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.

并且根据规则 3,比例上限为 6,您得到 DECIMAL(38,6)。这就是为什么您需要将结果显式转换为目标十进制类型。