NULL的陷阱:Merge
NULL表示unknown,不确定值,所以任何值(包括null值)和NULL值比较都是不可知的,在on子句,where子句,Merge或case的when子句中,任何值和null比较的结果都是false,这就是NULL设下的陷阱,我被坑过。
有一次,我使用Merge同步数据,由于target表中存在null值,虽然在source表中对null值做过处理,但是忽略了target表中的null值,导致数据merge失败。
step1,创建示例数据
--create source table
create table dbo.dt_source
(
id int null,
code int null
)
on [primary]
with(data_compression=page) --create target table
create table dbo.dt_target
(
id int null,
code int null
)
on [primary]
with(data_compression=page)
step2,插入示例数据
示例数据中,Source表和Target表中都存在null值,不管是在Source表,还是在Target表,都要避免和null值进行比较。
--insert data into table
insert into dbo.dt_source(id,code)
values(1,1),(2,2),(3,null) insert into dbo.dt_target(id,code)
values(1,1),(2,null)
step3,错误写法:只处理Source表中的null,而忽略Target表中的null
-- -1 stand for unknwon value
merge dbo.dt_target t
using dbo.dt_source s
on t.id=s.id
when matched and( t.code<>isnull(s.code,-1))
then update
set t.code=s.code
when not matched
then insert(id,code)
values(s.id,s.code);
查看Target和Srouce表中的数据,数据不同步,不同步的原因是when matched子句之后的and 条件, t.code中存在null值,null值和任何值(包括null值)比较的结果都是unknown,在when子句中视为false。

正确写法1,不管是在target表,还是在source表,只要存在null值,必须进行处理,避免出现和null进行比较的情况。
处理的方式是使用一个值来表示unknwon,如果ID列有效值不可能是负值,那么可以使用-1来代替unknown。因为-1和-1 是相等的,逻辑上就将null值和null值视为相同。
-- -1 stand for unknwon value
merge dbo.dt_target t
using dbo.dt_source s
on t.id=s.id
when matched and( isnull(t.code,-1)<>isnull(s.code,-1))
then update
set t.code=s.code
when not matched
then insert(id,code)
values(s.id,s.code);
正确写法2,在条件子句中,使用is null或 is not null来处理null值。
Tsql 使用is null和is not null来确实是,不是 null。 null is null 的逻辑值是true,other_value is null 为false, other_value is not null 为true。
merge dbo.dt_target t
using dbo.dt_source s
on t.id=s.id
when matched and( t.code<>s.code or t.code is null or s.code is null)
then update
set t.code=s.code
when not matched
then insert(id,code)
values(s.id,s.code);
NULL的陷阱:Merge的更多相关文章
- Merge语句中NULL的陷阱
NULL表示unknown,不确定值,所以任何值(包括null值)和NULL值比较都是不可知的,在on子句,where子句,Merge或case的when子句中,任何值和null比较的结果都是fals ...
- Merge使用
Role r = new Role(); r.setName("TEST"); r.setDescription("123"); r.setLevel(2); ...
- shell中while循环的陷阱
在写while循环的时候,发现了一个问题,在while循环内部对变量赋值.定义变量.数组定义等等环境,在循环外面失效. 一个简单的测试脚本如下: #!/bin/bash echo "abc ...
- 关于 JavaScript 中 null 的一切
原文地址:Everything about null in JavaScript 原文作者:Dmitri Pavlutin 译者:Gopal JavaScript 有两种类型:原始类型(strings ...
- [MySQL Reference Manual]15. 其他存储引擎
15. 其他存储引擎 15. 其他存储引擎 15.1 设置存储引擎 15.2 MyISAM存储引擎 15.2.1 MyISAM启动选项 15.2.2 Key的空间要求 15.2.3 MyISAM表存储 ...
- javascript 手势缩放 旋转 拖动支持:hammer.js
原文: https://cdn.rawgit.com/hammerjs/hammer.js/master/tests/manual/visual.html /*! Hammer.JS - v2.0.4 ...
- 【SQL】CLR聚合函数什么鬼
之前写过一个合并字符串的CLR聚合函数,基本是照抄MS的示例,外加了一些处理,已经投入使用很长时间,没什么问题也就没怎么研究,近日想改造一下,遇到一些问题,遂捣鼓一番,有些心得,记录如下. 一.杂项 ...
- mm/mmap.c
/* * linux/mm/mmap.c * * Written by obz. */#include <linux/stat.h>#include <linux/sched. ...
- java Util
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.qihangedu.tms.a ...
随机推荐
- PHP获取二维数组中的指定若干列【同array_column】
PHP5.3以上 用到了array_map 使用匿名函数进行处理 代码: <?php function array_col($arr = array(), $idx = 0, $newidx ...
- Dictionary Learning(字典学习、稀疏表示以及其他)
第一部分 字典学习以及稀疏表示的概要 字典学习(Dictionary Learning)和稀疏表示(Sparse Representation)在学术界的正式称谓应该是稀疏字典学习(Sparse Di ...
- LINUX常见问题
FQA1:如何进入linux单用户模式修改root密码 进入单用户模式:1. grub进入启动画面之后,敲入“e”,把光标移动到kernel ...那一行,再敲入“e”,在kernel 一行的最后加上 ...
- 【验证】C# dataSource 的记忆功能
做项目时遇到的问题:dataSource被ComboBox引用过一次,会记忆最后一次选中的值,然后下一次再用时这个值会直接呈现在ComboBox中. 为验证是dataSource还是ComboBox自 ...
- xpath tutorial
http://www.cnblogs.com/yukaizhao/archive/2011/07/25/xpath.html http://www.w3schools.com/xpath/defaul ...
- C#输出文本树形层次,前或者后自定义空格位数
Indent String with Spaces This example shows how to indent strings using method for padding in C#. T ...
- 使用 Graphviz 画拓扑图
使用 Graphviz 画拓扑图 0)前述 本文着重讲一下 Graphviz 的风格控制,基础一些的就不在这里讲啦. graphviz 的主页是http://www.graphviz.org/. Gr ...
- 轻松3步实现c#windowsform窗体美化
1.需要下载IrisSkin4.dll或者IrisSkin2.dll和ssk皮肤文件. 2.添加引用IrisSkin4.dll或者IrisSkin2.dll到项目中,将下载好的ssk皮肤文件复制到项目 ...
- springmvc上传文件,抄别人的
SpringMVC中的文件上传 分类: SpringMVC 2012-05-17 12:55 26426人阅读 评论(13) 收藏 举报 stringuserinputclassencoding 这是 ...
- angular 中父元素ng-repeat后子元素ng-click失效
在angular中使用ng-repeat后ng-click失效,今天在这个上面踩坑了.特此记录一下. 因为ng-repeat创造了新的SCOPE.如果要使用这个scope的话就必须使用$parent来 ...