merge语句使用

时不时地,由于以下任何原因,我们不得不将INSERT与UPDATE区分开来感到尴尬:

  • 我们必须至少发表两个声明
  • 我们必须考虑性能
  • 我们必须考虑比赛条件
  • 我们必须在[UPDATE; 如果UPDATE_COUNT = 0 THEN INSERT]和[INSERT; 如果例外然后更新]
  • 我们必须对每个更新/插入的记录执行一次这些语句

总而言之,这是错误和挫败感的重要根源。 同时,使用SQL MERGE语句可能是如此简单!

MERGE的典型情况

在许多其他用例中,当处理多对多关系时,MERGE语句可能会派上用场。 假设我们有以下架构:

CREATE TABLE documents (id NUMBER(7) NOT NULL,CONSTRAINT docu_id PRIMARY KEY (id));CREATE TABLE persons (id NUMBER(7) NOT NULL,CONSTRAINT pers_id PRIMARY KEY (id));CREATE TABLE document_person (docu_id NUMBER(7) NOT NULL,pers_id NUMBER(7) NOT NULL,flag NUMBER(1) NULL,CONSTRAINT docu_pers_pk PRIMARY KEY (docu_id, pers_id),CONSTRAINT docu_pers_fk_docu FOREIGN KEY (docu_id) REFERENCES documents(id),CONSTRAINT docu_pers_fk_pers FOREIGN KEY (pers_id) REFERENCES persons(id));

上表用于建模哪个人已阅读(flag = 1)/已删除(flag = 2)哪个文档。 为简单起见,通常将“ document_person”实体与“ documents”外部联接,以便“ document-person”记录的存在或不存在可能具有相同的语义:“ flag IS NULL”表示未读文档。
现在,当您要将文档标记为已读时,必须决定是插入一个新的“ document_person”,还是更新现有的“ document_person”。 与删除相同。 与将所有文档标记为已读或删除所有文档相同。

改用MERGE

您可以一口气做到这一切! 假设您要插入/更新一条记录,以将一个文档标记为已读:

-- The target tableMERGE INTO document_person dst-- The data source. In this case, just a dummy recordUSING (SELECT :docu_id as docu_id, :pers_id as pers_id, :flag    as flagFROM DUAL) src-- The merge condition (if true, then update, else insert)ON (dst.docu_id = src.docu_id AND dst.pers_id = src.pers_id)-- The update actionWHEN MATCHED THEN UPDATE SETdst.flag = src.flag-- The insert actionWHEN NOT MATCHED THEN INSERT (dst.docu_id,dst.pers_id,dst.flag)VALUES (src.docu_id,src.pers_id,src.flag)

这看起来很相似,但是比MySQL的INSERT .. ON DUPLICATE KEY UPDATE语句冗长得多,这更加简洁。

发挥到极致

但是,您可以走得更远! 如前所述,您可能还希望将给定人员的所有文档标记为已读。 合并没问题。 如果指定:docu_id,则以下语句与上一条相同。 如果将其保留为空,它将仅将所有文档标记为:flag:

MERGE INTO document_person dst-- The data source is now all "documents" (or just :docu_id) left outer-- joined with the "document_person" mappingUSING (SELECT d.id     as docu_id, :pers_id as pers_id, :flag    as flagFROM documents dLEFT OUTER JOIN document_person d_p ON d.id = d_p.docu_id AND d_p.pers_id = :pers_id-- If :docu_id is set, select only that documentWHERE (:docu_id IS NOT NULL AND d.id = :docu_id)-- Otherwise, select all documentsOR (:docu_id IS NULL)) src-- If the mapping already exists, update. Else, insertON (dst.docu_id = src.docu_id AND dst.pers_id = src.pers_id)-- The rest stays the sameWHEN MATCHED THEN UPDATE SETdst.flag = src.flagWHEN NOT MATCHED THEN INSERT (dst.docu_id,dst.pers_id,dst.flag)VALUES (src.docu_id,src.pers_id,src.flag)

jOOQ中的MERGE支持

jOOQ也完全支持MERGE。 有关更多详细信息,请参见手册(滚动至底部):
http://www.jooq.org/manual/JOOQ/Query/
合并愉快!

参考:我们的JCG合作伙伴 Lukas Eder在JAVA,SQL和JOOQ博客上使用SQL:2003 MERGE语句 编写了 Arcane magic 。

相关文章 :

  • Java中的数据库架构导航
  • ORM问题
  • SQL或NOSQL:这是问题吗?
  • 什么是NoSQL?
  • 按汇总分组/多维数据集

翻译自: https://www.javacodegeeks.com/2011/12/arcane-magic-with-sql2003-merge.html

merge语句使用

merge语句使用_使用SQL:2003 MERGE语句的奥术魔术相关推荐

  1. sql select 语句_学习SQL:SELECT语句

    sql select 语句 The SELECT statement is probably the most important SQL command. It's used to return r ...

  2. mysql sql语句 引号_关于sql:何时在MySQL中使用单引号,双引号和反引号

    我正在尝试学习编写查询的最佳方法. 我也理解保持一致的重要性. 到现在为止,我已经随机使用单引号,双引号和反引号而没有任何实际想法. 例: $query = 'INSERT INTO table (i ...

  3. 加sql查询语句导出_搞不懂这些查询语句,SQL简单查询也无法从入门到熟练

    大纲: 一.基本的查询语句 二.指定查询条件 三.注释和SQL语句注意事项 四.运算符 五.谓词 一.基本的查询语句 从表中选取数据时需要使用select语句,也就是只从表中选出(select)必要数 ...

  4. mysql经典sql语句大全_经典SQL语句大全

    下列语句部分是Mssql语句,不可以在access中使用. SQL分类: DDL-数据定义语言(CREATE,ALTER,DROP,DECLARE) DML-数据操纵语言(SELECT,DELETE, ...

  5. mysql 查询语句超时_解决SQL查询总是 超时已过期

    1.由于数据库设计问题造成SQL数据库新增数据时超时 症状: Microsoft OLE DB Provider for SQL Server 错误 '80040e31' ([ODBC SQL Ser ...

  6. mysql的经典sql语句大全_经典SQL语句大全_基础篇_提升篇_技巧篇_开发经典篇

    一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- ...

  7. mysql语句编码_使用SQL语句操作MYSQL字符编码

    -- 查看所有的字符编码 SHOW CHARACTER SET; -- 查看创建数据库的指令并查看数据库使用的编码 show create database dbtest; -- 查看数据库编码: s ...

  8. sql镶嵌查询_标准SQL嵌套查询语句

    展开全部 1.简单子查询62616964757a686964616fe78988e69d8331333433626530 select name,age from person where age & ...

  9. mysql 处理一条语句卡死_一条MySQL查询语句,卡死机器,不知道为什么,求高手指点!...

    你的位置: 问答吧 -> MySQL -> 问题详情 一条MySQL查询语句,卡死机器,不知道为什么,求高手指点! 我的这条查询语句有什么问题吗?为什么一运行,机器就卡死了!N久查询不出结 ...

最新文章

  1. 网络推广下叮咚买菜已完成D轮融资,生鲜电商下一次融资又在何方?
  2. 网站制作与运营离不开几个重要部分
  3. hdu 4503 湫湫系列故事——植树节
  4. Delphi中预想不到的代码楼主zswang(伴水清清)(专家门诊清洁工)2002-05-16 14:20:38 在 Delphi / VCL组件开发及应用 提问
  5. 【渝粤题库】陕西师范大学700005 遗传学
  6. 朱啸虎:自己来说可以把一小部分资产购买比特币,作为资产配置是可以考虑的
  7. 2019 年,Rust 与 WebAssembly 将让 Web 开发更美好
  8. 数据结构与算法(C#)入门 --- 线性表
  9. HTML_简单JQ的AJAX响应式交互
  10. 有一种方法叫“重启”
  11. VMware Tools手动安装
  12. 迅雷离线下载分享网站
  13. 【华为机试真题 Python实现】勾股数元祖
  14. 从20s优化到500ms,我用了这三招
  15. DFS(深度优先搜索算法)
  16. 小马哥----高仿三星note3 n9002 9006主板型号A202 刷机后修复返回键失灵实例说明
  17. 为什么OFDM抗多径?
  18. c++ string容器
  19. 国外cpa广告联盟emu项目最新介绍
  20. JAVA-打印圆形三种代码

热门文章

  1. 输入框限定保留三位小数点
  2. set注意点map遍历
  3. 希尔排序+移位法(吊打交换法)
  4. android之微信分享文本
  5. android拦截短信获取短信内容,《英雄联盟手游》先锋测试招募说明:仅安卓用户...
  6. php oracle 无查询结果,php - Oracle Insert查询不起作用,也不会抛出任何错误 - 堆栈内存溢出...
  7. 登录系统 提示框_实物资产管理软件操作手册(职员和系统用户)
  8. (转)如何查看java本地方法
  9. commons cli_从Commons CLI迁移到picocli
  10. oracle中悲观锁定_如何使用悲观锁定修复乐观锁定竞争条件