SQL Server有意思的数据类型隐式转换问题
写这篇文章的时候,还真不知道如何取名,也不知道这个该如何将其归类。这个是同事遇到的一个案例,案例比较复杂,这里抽丝剥茧,仅仅构造一个简单的案例来展现一下这个问题。我们先构造测试数据,如下所示:
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一样的突然出现。需要谨慎留心!

参考资料:
SQL Server有意思的数据类型隐式转换问题的更多相关文章
- SQL Server中提前找到隐式转换提升性能的办法
http://www.cnblogs.com/shanksgao/p/4254942.html 高兄这篇文章很好的谈论了由于数据隐式转换造成执行计划不准确,从而造成了死锁.那如果在事情出现之前 ...
- 【转】SQL SERVER标量表达式的隐式转换
在SQL Server中的数据类型中,存在着优先级的问题.标量表达示的返回结果类型也会根据操作数的类型而定,如1 +'1'=2.而不是'11',因些Int型的优先级比VARCHAR型的优先级要高.所以 ...
- JavaScript复习之--javascript数据类型隐式转换
JavaScript数据类型隐式转换.一,函数类 isNaN() 该函数会对参数进行隐式的Number()转换,如果转换不成功则返回true. alert() 输出的内容隐式的 ...
- js数据类型隐式转换问题
js数据类型隐式转换 ![] == false //true 空数组和基本类型转换,会先[].toString() 再继续比较 ![] == [] //true ![] //false [] == [ ...
- js中的数据类型隐式转换的三种情况
js的数据类型隐式转换主要分为三种情况: 1. 转换为boolean类型 2. 转换为number类型 3. 转换为string类型 转换为boolean类型 数据在 逻辑判断 和 逻辑运算 之中会隐 ...
- Oracle数据类型隐式转换小析
测试使用环境:oracle 11g r1 平常写sql语句时,大大咧咧,不太注意和数字有关的数据类型,有时例如 where c1=111 和 where c1='111'这样混用,却不曾想这里面另有蹊 ...
- MySQL SQL优化之字符串索引隐式转换
之前有用户很不解:SQL语句非常简单,就是select * from test_1 where user_id=1 这种类型,而且user_id上已经建立索引了,怎么还是查询很慢? test_1的表结 ...
- SQL Server优化器特性-隐式谓词
我们都知道,一条SQL语句提交给优化器会产生相应的执行计划然后执行输出结果,但他的执行计划是如何产生的呢?这可能是关系型数据库最复杂的部分了.这里我为大家介绍一个有关SQL Server优化器的特性- ...
- JavaScript —— 常用数据类型隐式转换
公用方法: let checkType = (data) => { if(data){ console.log(true); }else{ console.log(false); } } 一.字 ...
随机推荐
- C# ODP.NET 调用Oracle函数返回值时报错的一个解决方案
有人在社区问到:C#调用Oracle中自定义函数的返回值时,无法正常调用.但在PL/SQL中正常调用返回. 于是动手一试: 1.准备函数(Oralce 11g.2.0.0.4) CREATE OR R ...
- Leetcode327: Count of Range Sum 范围和个数问题
###问题描述 给定一个整数数组,返回range sum 落在给定区间[lower, upper] (包含lower和upper)的个数.range sum S(i, j) 表示数组中第i 个元素到j ...
- Password Management:Hardcoded Password 密码管理:硬编码密码
- SpringBoot源码篇:Spring5内置tomcat实现code-based的web.xml实现
一.简介 上篇文章讲了SpingBoot诞生的历史背景和技术演进背景,并通过源码说明了SpringBoot是如何实现零配置的包括如何省去web.xml配置的原理.本文接上一篇文章,通过demo演示Sp ...
- WebShell代码分析溯源(十一)
WebShell代码分析溯源(十一) 一.一句话变形马样本 <?php $e = $_REQUEST['e'];declare(ticks=1);register_tick_function ( ...
- springcloud vue.js 微服务分布式 前后分离 集成代码生成器 shiro权限 activiti工作流
1.代码生成器: [正反双向](单表.主表.明细表.树形表,快速开发利器)freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本.处理类.service等完整模块2. ...
- MS16-072域内中间人攻击
0x01 漏洞利用 在目标主机域用户口令已知的条件下,目标主机在进行策略更新时,对域服务器的认证存在漏洞,攻击者劫持认证服务器的过程,引导至伪造的域服务器,并在域服务器中制定用户的计划任务策略,可以获 ...
- Computer: Use the mouse to open the analog keyboard
Xx_Introduction Please protection,respect,love,"China's Internet Security Act"! For learni ...
- 团队项目之Scrum5
小组:BLACK PANDA 时间:2019.11.25 每天举行站立式会议 提供当天站立式会议照片一张 2 昨天已完成的工作 2 实现文章展示页面 完善后台的编辑功能接口 今天计划完成的工作 2 ...
- [20191125]探究等待事件的本源.txt
[20191125]探究等待事件的本源.txt --//当工作中遇到oracle的性能问题时,查看awr报表提供很好的解决问题途径.但是有时候很容易想当然.--//比如以前我一看到 log file ...