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

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一样的突然出现。需要谨慎留心!

 

参考资料:

https://docs.microsoft.com/zh-cn/sql/t-sql/data-types/data-type-precedence-transact-sql?view=sql-server-2017

https://docs.microsoft.com/zh-cn/sql/t-sql/data-types/data-type-conversion-database-engine?view=sql-server-2017

SQL Server有意思的数据类型隐式转换问题的更多相关文章

  1. SQL Server中提前找到隐式转换提升性能的办法

        http://www.cnblogs.com/shanksgao/p/4254942.html 高兄这篇文章很好的谈论了由于数据隐式转换造成执行计划不准确,从而造成了死锁.那如果在事情出现之前 ...

  2. 【转】SQL SERVER标量表达式的隐式转换

    在SQL Server中的数据类型中,存在着优先级的问题.标量表达示的返回结果类型也会根据操作数的类型而定,如1 +'1'=2.而不是'11',因些Int型的优先级比VARCHAR型的优先级要高.所以 ...

  3. JavaScript复习之--javascript数据类型隐式转换

    JavaScript数据类型隐式转换.一,函数类    isNaN()    该函数会对参数进行隐式的Number()转换,如果转换不成功则返回true.    alert()    输出的内容隐式的 ...

  4. js数据类型隐式转换问题

    js数据类型隐式转换 ![] == false //true 空数组和基本类型转换,会先[].toString() 再继续比较 ![] == [] //true ![] //false [] == [ ...

  5. js中的数据类型隐式转换的三种情况

    js的数据类型隐式转换主要分为三种情况: 1. 转换为boolean类型 2. 转换为number类型 3. 转换为string类型 转换为boolean类型 数据在 逻辑判断 和 逻辑运算 之中会隐 ...

  6. Oracle数据类型隐式转换小析

    测试使用环境:oracle 11g r1 平常写sql语句时,大大咧咧,不太注意和数字有关的数据类型,有时例如 where c1=111 和 where c1='111'这样混用,却不曾想这里面另有蹊 ...

  7. MySQL SQL优化之字符串索引隐式转换

    之前有用户很不解:SQL语句非常简单,就是select * from test_1 where user_id=1 这种类型,而且user_id上已经建立索引了,怎么还是查询很慢? test_1的表结 ...

  8. SQL Server优化器特性-隐式谓词

    我们都知道,一条SQL语句提交给优化器会产生相应的执行计划然后执行输出结果,但他的执行计划是如何产生的呢?这可能是关系型数据库最复杂的部分了.这里我为大家介绍一个有关SQL Server优化器的特性- ...

  9. JavaScript —— 常用数据类型隐式转换

    公用方法: let checkType = (data) => { if(data){ console.log(true); }else{ console.log(false); } } 一.字 ...

随机推荐

  1. Django的Form验证

    Django的Form验证 Form验证:Form提交Form表单数据验证 针对Form提交的数据进行验证 创建模板 class loginForm() 请求提交给模板,创建对象 obj=loginF ...

  2. 安装SDK 6.0(二)

    2==>安装SDK 6.0 打开安卓Android Studio 出现 Unable to access Android SDK add-on list 点击 Cancal 在点击Cancel ...

  3. 形如 T(n) = a * T(n/b) + f(n) 的时间复杂度计算方法

    形如 T(n) = a * T(n/b) + f(n) 的时间复杂度计算方法 有一种方法叫做主方法(Master method)是用来专门计算这种形式的时间复杂度的,方法具体如下: 下边举例进行说明: ...

  4. 【30天自制操作系统】day02:寄存器和Makefile

    基本寄存器 AX(accumulator):累加寄存器 CX(counter):计数寄存器 DX(data):数据寄存器 BX(base):基址寄存器 SP(stack pointer):栈指针寄存器 ...

  5. React: 研究Flux设计模式

    一.简介 一般来说,State管理在React中是一种最常用的实现机制,使用这种state管理系统基本可以开发各种需求的应用程序.然而,随着应用程序规模的不断扩张,原有的这种State管理系统就会暴露 ...

  6. HTTP 400 与 SpringMVC的 HttpPutFormContentFilter、FormContentFilter

    前端发送了一个http PUT请求,如下, json_xml: {,},,}},,},,}},},}},,},{,}],,},,}},,,,},,}},},}},,},{,}],,},,}},,},{ ...

  7. eclipse中js中文乱码问题的解决办法

    在Eclipse中编辑JS文件简直是一种折磨,但是却总是很无奈得要去适应. 这里说一下Eclipse中,编辑JS文件时候,出现中文乱码问题的解决办法. 这个问题很容易想到是文件编码的问题,因此通常是修 ...

  8. springboot中使用aop技术

    aop是面向切面编程的意思,它可以需要先选择一些切入点,然后对这些切入点进行拦截,注入统一的代码逻辑,这也是解耦的一种方式,也是为了避免重复的代码,让开发人员把关注点放在业务上. 引用包 'org.s ...

  9. JS基础语法---String对象下的方法(字符串的方法)

    实例方法---->必须要通过new的方式创建的对象(实例对象)来调用的方法 静态方法---->直接通过大写的构造函数的名字调用的方法(直接通过大写的对象名字调用的) 字符串的常用属性: . ...

  10. 47.QT-QChart之曲线图,饼状图,条形图使用

     1.使用准备 在pro中, 添加QT+= charts 然后在界面头文件中添加头文件并声明命名空间,添加: #include <QtCharts> QT_CHARTS_USE_NAMES ...