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

最新文章

  1. (转)对《30个提高Web程序执行效率的好经验》的理解
  2. zookeeper集群搭建(windows环境下)
  3. 流控panabit的安装及配置
  4. PHP 反射 ReflectionClass
  5. js获取input file文件二进制码
  6. Python基础7:字符串方法
  7. Java如何计算一个程序的运行时间
  8. vs2013新建asp.net web 项目报错,此模板尝试加载组件程序集NuGet Package Manage
  9. 【原创】USART异步模式配置
  10. docker必须要sudo,但是sudo的话,又获得不了环境变量怎么办?
  11. IO流的总结(二)
  12. wingIDE Pro6 破解教程
  13. DDD领域模型实现依赖注入(六)
  14. 入门angularJs笔记手记一
  15. Knockout开发中文API系列4–绑定关键字
  16. IntelliJ IDEA导出Java 可执行Jar包
  17. 20135234mqy-——信息安全系统设计基础第五周学习总结
  18. linux下安装微信小程序开发工具
  19. 安卓开发神器vysor+adb wifi
  20. 深入理解bootstrap框架之第二章整体架构

热门文章

  1. C++Primer学习笔记(1)
  2. Linux内核笔记——进程管理之执行体
  3. 洛谷 P1378 油滴扩展 Label:搜索
  4. 做 Web 开发少不了这些的
  5. 一个简便的方法,获取某个页面元素的Xpath值
  6. Salesforce注册开发者账号
  7. JS转换数字金额为大写
  8. 【Telerik】弹出对话框RadWindow,确认删除信息
  9. sublime text 插件(前端自用)
  10. Spring Mvc的入门