T-SQL中的一些小陷阱
1,当心ISNULL函数对你的逻辑引起BUG
有人喜欢或者习惯于(并不代表我推荐,甚至这种写法没有任何好处)用ISNULL处理变量这种方式写查询
比如:select * from TestISNULL where name = ISNULL(@name,name)
@name相当于传入到存储过程中的参数,如果@name为null,
相当于:select * from TestISNULL where name = name,看起来恒成立,是真的吗?
目的是在@name为null的时候,这个查询条件不生效
当时当遇到字段name中的某些数据为null的时候,实际逻辑就变成了
select * from TestISNULL where null= null,null=null是什么结果?
自己试试或者继续往下看就知道了,
此时会产生一些“莫名其妙”的bug,这种bug是跟数据有关,有时候出现,而有时候又没有问题,
对于“有时候出现有时候不出现的问题”,不管是SQL还是应用程序代码,定位起来都不是太容易的
这种情况,会对对问题的排查产生了很大的干扰
看例子:
--ISNULL 处理变量的一个小陷阱 Create Table TestISNULL ( id int, name ) ) GO ,'AAA') ,'BBB') GO ) set @name=null select * from TestISNULL where name = ISNULL(@name,name) --结果是两行没有任何问题 /* id name ----------- ---------------------- 1 AAA 2 BBB (2 row(s) affected) */ --插入一条数据 ,null) GO select * from TestISNULL --全部结果是三行 /* id name ----------- -------------------- 1 AAA 2 BBB 3 NULL (3 row(s) affected) */ --继续用isnull的方式处理变量做查询 ) set @name=null select * from TestISNULL where name = ISNULL(@name,name) --结果是两行,你明白为什么吗 /* id name ----------- ---------------------- 1 AAA 2 BBB (2 row(s) affected)
究竟为什么呢?好吧,下面应该很清楚了
2,SQL Server 对数据类型优先级引起Case When 的一些语法错误
继续用上面的表验证另外一个小语法问题,某些逻辑处理数据的时候,字段为null的时候,将结果统一标记为一种数值,如下
当然,这样是通不过的,提示将AAA转换为数值的时候失败
这种问题本质上是:会将低优先级的varchar转换为高优先级的int进行对比
但是在将字符转换为数值型的时候,就会出现转换失败的情况
这里就涉及到SQL Server数据类型优先级的问题,有兴趣的自行MSDN
SELECT id, CASE ELSE name END AS name FROM TestISNULL
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'AAA' to data type int.
解决办法就是统一数据类型,注意字符0和数值0是不一样的,这样就不会引起数据类型优先级转换的问题
SELECT id, CASE ' ELSE name END AS name FROM TestISNULL
当然这个问题的“变种”不仅限于case when,有各种各样的“变种”,
当遇到“Error converting data type *** to ***.”此类问题的时候,可以考虑是不是这个原因引起的,对快速定位问题可以起到帮助作用,避免在这些小逻辑上浪费太多时间。
T-SQL中的一些小陷阱的更多相关文章
- C# 中几个小“陷阱”
每天写代码,偶尔就会有让你抓狂的时候:代码改了千百遍,蓦然回首,Bug就在灯火阑珊处……这里就列举一些容易犯错的几个小地方,以后遇到了其他的,再慢慢添加. 1. 获取程序当前运行路径 情景复现 ...
- java常量池中基本数据类型包装类的小陷阱
想必大部分学过java的人都应该做过这种题目: public class Test { public static void main(String[] args) { //第一个字符串 String ...
- C++ string中的几个小陷阱,你掉进过吗?
C++开发的项目难免会用到STL的string,使用管理都比char数组(指针)方便的多,但在得心应手的使用过程中也要警惕几个小陷阱,避免我们项目出bug却迟迟找不到原因. 1. 结构体中的stri ...
- Unity 3D中C#的性能优化小陷阱
本篇内容主要来自Unity官方手册: 一般性能优化 一些地方为本人瞎编杜撰,请酌情参考.如有错误,欢迎指出. Unity里C#编程虽然既简单还很爽,但是性能小陷阱还不少.我总强迫自己让代码最优,因此很 ...
- ESXi与物理交换机静态链路聚合配置过程中的小陷阱
作者:陆斌文章来自微信公众号:平台人生 内容简介:ESXi与物理交换机之间配置静态链路聚合时,因为静态链路聚合的特点,在进行down网卡和从虚拟交换机移除网卡的操作时,可能会无法完成故障流量切换,影响 ...
- 那些年我们踩过的坑,SQL 中的空值陷阱!
文章目录 NULL 即是空 三值逻辑 空值比较 NOT IN 与空值 函数与空值 DISTINCT.GROUP BY.UNION 与空值 ORDER BY 与空值 空值处理函数 字段约束与空值 SQL ...
- 正则表达式小技巧,sql中in的字符串处理
工作中我经常写sql,当写带in的语句时,需要敲好多单引号,逗号,敲写起来容易易出错.因此,我写了一个小工具,处理这种繁琐工作.原理简单,利用正则表达式匹配.替换. 先看界面,一个html页面,包含三 ...
- Python中定义函数时参数有默认值的小陷阱
在定义函数的时候,如果函数的参数有默认值,有两种类型的参数,一种是整数,字符串这种不可变类型,另一种是列表这种可变类型,对于第一种情况没有什么特殊的地方,但是对于可变类型,有一个微妙的小陷阱. 可变类 ...
- sql 中set和select区别
基于SQL中SET与SELECT赋值的区别详解 2012年09月06日 ⁄ 综合 ⁄ 共 912字 ⁄ 字号 小 中 大 ⁄ 评论关闭 最近的项目写的SQL比较多,经常会用到对变量赋值,而我使用SET ...
随机推荐
- ListView组件应用源码
首先在xml文件中定义ListView组件 <ListView android:id="@+id/show_view_list" android:layout_width=& ...
- Android消息队列和Looper
1. 什么是消息队列 消息队列在android中对应MessageQueue这个类,顾名思义,消息队列中存放了大量的消息(Message) 2.什么是消息 消息(Message)代表一个行为(what ...
- label正确显示多行数据
label显示多行文字时会遇到文字中包含换行符“\n”,这时需要对字符进行全部替换, if(labelContent.indexOf('\\n')>0){labelContent=labelCo ...
- 360等杀掉了app的主进程后 ,如何自动开启 如何防止被kill
如何阻止360等进程查杀工具停止App后台进程安全软件优化内存时需要关闭没用的进程既然你同意使用360,,也允许了360的最高权限..那么他就有足够的权限来杀掉app后台进程. 一 如何保证app进程 ...
- 微软connect教程系列—EntityFramework7(三)
随着Asp.NET5的开源,以及跨平台,ORM框架EF7也与时俱进,支持asp.net core,也支持关系型数据库和非关系型数据库,以及在linux和mac上跨平台使用. 下面演示的即通过使用E ...
- VS2008 Pocket PC 2003 SE仿真程序上网设置
设置大体分为3个步骤:Microsoft ActiveSync安装配置.Pocket PC 2003 SE仿真程序配置.Pocket PC 2003连接到Microsoft ActiveSync. 1 ...
- IIS负载均衡ARR路由请求到ARR服务器和处理服务器
.net web 使用IIS ARR(Application Request Route)技术实现web的高性能.高可靠.易扩展及负载均衡.ARR的使用请参考 IIS负载均衡-Application ...
- Java序列化格式详解
RPC的世界,由于涉及到进程间网络远程通信,不可避免的需要将信息序列化后在网络间传送,序列化有两大流派: 文本和二进制. 文本序列化 序列化的实现有很多方式,在异构系统中最常用的就是定义成人类可读的文 ...
- VS2013 好用的插件
切换到vs2013上有些时间了,以下是我个人认为比较好的插件. Resharper 神器中的神器,提升编码效率的第一神器,附带提高编码能力:除去臃肿的体积,堪称完美: Productivity Pow ...
- 【团队分享之二】IT团队绩效提升的一些见解