欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SQL Server有意思的数据类型隐式转换问题

程序员文章站 2023-01-14 08:50:26
写这篇文章的时候,还真不知道如何取名,也不知道这个该如何将其归类。这个是同事遇到的一个案例,案例比较复杂,这里抽丝剥茧,仅仅构造一个简单的案例来展现一下这个问题。我们先构造测试数据,如下所示: CREATE TABLE TEST( ID INT, GOOD_TYPE VARCHAR(12), GOO... ......

写这篇文章的时候,还真不知道如何取名,也不知道这个该如何将其归类。这个是同事遇到的一个案例,案例比较复杂,这里抽丝剥茧,仅仅构造一个简单的案例来展现一下这个问题。我们先构造测试数据,如下所示:

 

create table test
( 
  id    int, 
  good_type  varchar(12),
  good_weight numeric(18,2)
)
 
insert into dbo.test
values( 1, 't1',1.27) 

 

select  good_type,
        case when ( good_type = 't1' ) then 99.1 + sum(good_weight)
             else ceiling(sum(good_weight))
        end as grossweight ,
        sum(good_weight) as netweight
from    dbo.test
group by good_type;

 

 

 

如上所示,为什么99.1 + sum(good_weight)变成100了呢? 原始sql非常复杂,我们分析、排除掉各个因素后,始终不得要领,各种折腾中发现,如果这样转换一下(请见下面截图),居然就ok了,后面分析了一下,应该是case when里面的不同数据类型导致隐式转换,说实话之前还真没有留意case when中存在数据类型的隐性转换,但是为什么就一定从numeric转换为int了呢? 而不是int隐性转换为numeric呢, 说实话没有看到相关文档的官方,如果按照官方文档:

 

当两个不同数据类型的表达式用运算符组合后,优先级较低的数据类型首先转换为优先级较高的数据类型。 如果此转换不是所支持的隐式转换,则返回错误。 对于组合具有相同数据类型的操作数表达式的运算符时,运算的结果便为该数据类型

 

而我们知道,decimal 和 numeric 是同义词,可互换使用,而官方文档数据类型优先级 (transact-sql)”中,decimal的优先级明显高于int,如果真要按照原理来解释,应该是int转换numeric才对(两种数据类型支持隐式转换),所以越想越糊涂,只知道有这么一回事,但是真正的root cause尚不清楚,而且在精确度要求较高的报表中,这种现象就会类似bug一样的突然出现。需要谨慎留心!

 

 

参考资料: