隐式转换和舍入

时间:2010-12-14 16:32:09

标签: sql-server sql-server-2005 tsql

刚刚遇到一个有趣的问题:

declare @test as int
set @test = 47

select @test * 4.333

返回203.651

declare @test as int
set @test = 47

declare @out as int
set @out = (select @test * 4.333)

select @out

返回203

declare @test as int
set @test = 47

declare @out as int
set @out = round((select @test * 4.333),0)

select @out

返回204

现在我知道 为什么 它会这样做。因为存在从十进制到int的隐式转换,因此小数位需要切断(因此为203),而如果我在隐式转换之前进行舍入,则得到204.

我的问题是为什么当SQL Server进行隐式转换时它是不是也会舍入?我知道如果我有一个很大的数字,它需要存储在一个小的地方,我要做的第一件事这样做可能会使它尽可能接近原始数字。

这对我来说似乎并不直观。

1 个答案:

答案 0 :(得分:4)

这让我阅读,答案似乎明显不满意,我能够找到的最早的SQL参考(ANSI 92可用here 4.4.1数字特征陈述

  

每当精确或近似   数值分配给a            表示精确数值的数据项或参数,   一个            其值的近似值保留了显着的优势   舍入或截断后的数字表示在数据中   类型            目标。该值被转换为具有精度和            目标的规模。是否截断或舍入的选择   是            实现定义的。

这让微软选择为tsql实现这两个中的哪一个,我认为为了简单起见,他们选择了截断。从wikipedia article on rounding来看,这似乎不是一天中不常见的决定。

有趣的是,根据我发现的文档,只有转换为整数会导致截断,其他转换会导致舍入。虽然由于一些奇怪的原因,从货币到整数的转换似乎逆转了趋势,因为它允许转为。

From     To       Behaviour

numeric  numeric  Round

numeric  int      Truncate

numeric  money    Round

money    int      Round

money    numeric  Round

float    int      Truncate

float    numeric  Round

float    datetime Round

datetime int      Round

来自here

的表格