计算列值与其使用的标量函数不同

时间:2014-07-31 08:32:11

标签: sql-server sql-function calculated-columns

我有一个带有计算列的表,它使用标量函数

CREATE FUNCTION [dbo].[ConvertToMillimetres]
(
    @fromUnitOfMeasure int,
    @value decimal(18,4)
)
RETURNS decimal(18,2)
WITH SCHEMABINDING
AS
BEGIN
    RETURN
    CASE 
        WHEN @fromUnitOfMeasure=1 THEN @value
        WHEN @fromUnitOfMeasure=2 THEN @value * 100
        WHEN @fromUnitOfMeasure=3 THEN @value * 1000
        WHEN @fromUnitOfMeasure=4 THEN @value * 25.4
     ELSE @value
    END
END

GO

该表包含此列

[LengthInMm]  AS (CONVERT([decimal](18,2),[dbo].[ConvertToMillimetres]([LengthUnitOfMeasure],[Length]))) PERSISTED,

假设表中的[Length]为62.01249且[LengthUnitOfMeasure]为4,则LengthInMm计算值附带1575.11但是当我直接运行该函数时

SELECT [dbo].[ConvertToMillimetres] (4, 62.01249) GO

它附带1575.12

[Length]列是(decimal(18,4,null))

有人能说出为什么会这样吗?

3 个答案:

答案 0 :(得分:0)

我不确定这真的算是一个答案,但是你可能遇到了特定版本SQL的问题?

我只是去复制它(在本地SQL 2014安装上)并获得以下内容:

create table dbo.Widgets (
  Name varchar(20),
  Length decimal(18,4),
  LengthInMm AS [dbo].[ConvertToMillimetres] (4, Length) PERSISTED
)

insert into dbo.Widgets (Name, Length) values ('Thingy', 62.01249)

select * from dbo.Widgets

结果如下:

Name                 Length                                  LengthInMm
-------------------- --------------------------------------- ---------------------------------------
Thingy               62.0125                                 1575.12

(1 row(s) affected)

请注意,您的定义使用[LengthInMm] AS (CONVERT([decimal](18,2),[dbo].[ConvertToMillimetres]([LengthUnitOfMeasure],[Length]))) PERSISTED,但这似乎对结果没有影响。

答案 1 :(得分:0)

我也试过我的电脑(Microsoft SQL Server 2012 - 11.0.2100.60(X64))。工作正常:

CREATE TABLE dbo.data(
    LengthUnitOfMeasure INT,
    [Length] decimal(18,4),
    [LengthInMm] AS (CONVERT([decimal](18,2),[dbo].[ConvertToMillimetres]([LengthUnitOfMeasure],[Length]))) PERSISTED
)


INSERT INTO dbo.data (LengthUnitOfMeasure, [Length])
SELECT 4, 62.01249

SELECT * 
FROM dbo.data

/*
RESULT
LengthUnitOfMeasure Length  LengthInMm
4                   62.0125 1575.12
*/

答案 2 :(得分:0)

我想,我找到了答案:

让我们看看你在说什么:

有一个decimal(18,4)数据类型的列。 有一个计算列依赖于此列。 选择计算字段并手动提供相同结果时,结果会有所不同。 (右?)

抱歉,输入参数不一样: 表中的列为decimal(18,4)。您手动提供的值为decimal(7,5)(62.01249)

由于表中的列无法存储标度为5的任何值,因此提供的值将不相等。 (此外,表中没有62.01249列中Length值的记录)

从表中查询[Length]列时的输出是什么?是62.0124吗?如果是,那么这就是答案。由于输入值不相等,结果不能相等。

更具体一点:62.01249将被投射(隐式强制转换)为62.0125

ROUND(25.4 * 62.0124, 2) = 1575.11
ROUND(25.4 * 62.0125, 2) = 1575.12

编辑每个试图重建架构的人都犯了同样的错误(包括我)。当我们(盲目地)将原始问题中的值插入到我们的实例中时,我们将62.01249插入Length列 - >发生了相同的隐式转换,因此我们在表中有值62.0125