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);

Merge语句中NULL的陷阱的更多相关文章

  1. SQL语句中=null和is null

    平时经常会遇到这两种写法:IS NOT NULL与!=NULL.也经常会遇到数据库有符合条件!=NULL的数据,但是返回为空集合.实际上,是由于对二者使用区别理解不透彻. 默认情况下,推荐使用 IS ...

  2. Sql server的Merge语句,源表中如果有重复数据会导致执行报错

    用过sql server的Merge语句的开发人员都应该很清楚Merge用来做表数据的插入/更新是非常方便的,但是其中有一个问题值得关注,那就是Merge语句中的源表中不能出现重复的数据,我们举例来说 ...

  3. 【SQL Server学习笔记】Delete 语句、Output 子句、Merge语句

    原文:[SQL Server学习笔记]Delete 语句.Output 子句.Merge语句 DELETE语句 --建表 select * into distribution from sys.obj ...

  4. 【转载】SQL Server - 使用 Merge 语句实现表数据之间的对比同步

    原文地址:SQL Server - 使用 Merge 语句实现表数据之间的对比同步 表数据之间的同步有很多种实现方式,比如删除然后重新 INSERT,或者写一些其它的分支条件判断再加以 INSERT ...

  5. 转:SQL Server - 使用 Merge 语句实现表数据之间的对比同步

    表数据之间的同步有很多种实现方式,比如删除然后重新 INSERT,或者写一些其它的分支条件判断再加以 INSERT 或者 UPDATE 等.包括在 SSIS Package 中也可以通过 Lookup ...

  6. SQL Server - 使用 Merge 语句实现表数据之间的对比同步

    表数据之间的同步有很多种实现方式,比如删除然后重新 INSERT,或者写一些其它的分支条件判断再加以 INSERT 或者 UPDATE 等.包括在 SSIS Package 中也可以通过 Lookup ...

  7. 如何理解T-SQL中Merge语句(二)

    写在前面的话:上一篇写了如何理解T-SQL中Merge语句,基本把Merge语句要讲的给讲了,在文章的后面,抛出了几个结,当时没有想明白怎么去用文字表达,这一篇就来解答一下这几个结,又是一篇“天马行空 ...

  8. SQLServer 2008中SQL增强之三 Merge(在一条语句中使用

    SQLServer 2008中SQL增强之三 Merge(在一条语句中使用Insert,Update,Delete)   SQL Server 2008提供了一个增强的SQL命令Merge,用法参看M ...

  9. 如何理解T-SQL中Merge语句

    写在前面的话:之前看过Merge语句,感觉没什么用,完全可以用其他的方式来替代,最近又看了看Merge语句,确实挺好用,可以少写很多代码,看起来也很紧凑,当然也有别的优点. ====正文开始===== ...

随机推荐

  1. MDT配置数据库

    连接数据库可以使用数据库账户和Windows集成身份验证两种方法:使用数据库账户:1.连接数据库时选择TCP/IP2.在数据库中添加相应规则后,配置数据库3.在CustomSettings.ini文件 ...

  2. [咸恩静][Good Bye]

    歌词来源:http://music.163.com/#/song?id=35437298 作曲 : 安英民 [作曲 : 安英民] 作词 : 安英民/로코 [作词 : 安英民/lo-Ko] 나를 떠나버 ...

  3. Java Classloader机制解析

    做Java开发,对于ClassLoader的机制是必须要熟悉的基础知识,本文针对Java ClassLoader的机制做一个简要的总结.因为不同的JVM的实现不同,本文所描述的内容均只限于Hotspo ...

  4. js实现svg图形转存为图片下载[转]

    我们知道canvas画布可以很方便的js原生支持转为图片格式并下载,但是svg矢量图形则并没有这方面原生的支持.研究过HighChart的svg图形的图片下载机制,其实现原理大体是浏览器端收集SVG代 ...

  5. SuperMap/PlottingSymbol

    https://github.com/SuperMap/PlottingSymbol

  6. 基于easyui开发Web版Activiti流程定制器详解(二)——文件列表

    上一篇我们介绍了目录结构,这篇给大家整理一个文件列表以及详细说明,方便大家查找文件. 由于设计器文件主要保存在wf/designer和js/designer目录下,所以主要针对这两个目录进行详细说明. ...

  7. 给 Virtualbox 中 Ubuntu 系统设置静态 IP

    虚拟机网络选择 桥接网卡 模式. 主要涉及两个步骤: 1. 修改 /etc/network/interfaces 文件: 2. 修改 dns : 第一步,修改 interfaces 文件: sudo ...

  8. ueditor 百度编辑器 解决表格没有边框

    因为项目需要,发现直接从word和excel复制粘贴以后,居然在禅道上表格没有边框了,故查了一下 这里从word,以及excel粘贴复制,都能直接有边框了,同时在编辑器里面新增表格,也能直接显示边框了 ...

  9. Java阶段性总结与获奖感想

    一.获奖感想 这次能获得小黄衫,可以说是对我自己这半学期以来努力学习的一种肯定,也是激励我继续努力的动力. 首先,我要感谢给予我们耳目一新的学习方式的娄老师.我曾在我期望的师生关系中提到,我的高中班主 ...

  10. mongodb的学习-3-在Mac上的安装配置

    1.使用homebrew安装: brew install mongodb 查看安装好的版本: mongo --version MongoDB shell version v3.6.4 git vers ...