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);
复制代码

 

作者悦光阴
本文版权归作者和博客园所有,欢迎转载,但未经作者同意,必须保留此段声明,且在文章页面醒目位置显示原文连接,否则保留追究法律责任的权利。
分类: SQL Server
标签: NULL, Merge






本文转自悦光阴博客园博客,原文链接:http://www.cnblogs.com/ljhdo/p/4979075.html,如需转载请自行联系原作者
目录
相关文章
|
Java
synchronize 三大作用、三大用法
synchronize 三大作用、三大用法
122 0
|
8月前
|
安全 算法 编译器
C++中=delete的巧妙用法
C++中=delete的巧妙用法
216 0
|
SQL 数据挖掘 PHP
使用array_merge导致内存不足的反思
从用户喜欢表分批拿到数据,通过array_merge()组装,再批量插入到数据分析表。 测试的时候因为数据量小,没有出现问题。随着业务增长,在查询范围内已经超过3万条数据。 3万条数据在8核32G的单机上已经提示内存溢出了。
265 0
ts重点学习71-implement语句
ts重点学习71-implement语句
120 0
ts重点学习71-implement语句
ts重点学习135-声明合并
ts重点学习135-声明合并
86 0
ts重点学习135-声明合并
hook+ts业务开发思路6-状态惰性初始化和localstroage使用
hook+ts业务开发思路6-状态惰性初始化和localstroage使用
79 0
hook+ts业务开发思路6-状态惰性初始化和localstroage使用
|
移动开发 缓存 HTML5
是时候学习/推广一波可选链(Optional chaining)和空值合并(Nullish coalescing )了
最近工作中发现团队有些同学不太了解 Optional chaining 和 Nullish coalescing 两个新的操作符,正好推广一波。
是时候学习/推广一波可选链(Optional chaining)和空值合并(Nullish coalescing )了
ts重点学习72-implement语句
ts重点学习72-implement语句
244 0
ts重点学习136-声明合并
ts重点学习136-声明合并
141 0
|
SQL 监控 关系型数据库
index_merge导致死锁案例分析
一、死锁现象描述 1.1 基本环境信息 1、数据库版本以及隔离级别 mysql>select version(); +---------------------+ | version() | +---------------------+ | 5.
1102 0