使用SQL:2003 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语句 编写了 奥术魔术 。

相关文章 :

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373978.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Swing 学习小记

初学Swing一路问题,一路学习 问题一:JPanel中动态组件添加,刷新问题? 错误一:使用repaint()方法,以为可以刷新,可行不通。 错误继续发生:还是使用repaint()方法,与之前不…

2014编程之美资格赛

2014 编程之美挑战赛 --- 资格赛真题 题目1 : 同构 时间限制:2000ms单点时限:1000ms内存限制:256MB描述 给定2个树A和B,保证A的节点个数>B的节点个数。 现在你需要对树A的边进行二染色。 一个好的染色方案,指不存在一个树A中的连通块,同时…

stand up meeting 12/11/2015

part组员今日工作工作耗时/h明日计划工作耗时/hUI冯晓云完成单词释义热度排序;允许用户自主添加释义;完成了button位置的修正(finally)和弹窗的美化; 6try the backup plan 6PDF Reader朱玉影 完成了pdf文件的打…

ssrf漏洞内网渗透_渗透技巧之SSRF

SSRF——服务端请求伪造,上一篇,我谈到了CSRF客户端请求伪造,这个是我们通过攻击用户,引诱客户点击我们伪造好的表单,从而达到我们攻击的目的,是从客户端发起的,那么SSRF服务端请求伪造当然是通…

Spring Insight – Web应用程序分析

您是否正在使用Spring Framework编写Web应用程序? 您是否曾经想过引擎盖下发生了什么? 为什么您的应用程序响应如此缓慢? 在您仍然等待应用程序响应的同时,为什么窗外的蜗牛如此之快地消失在远处? 您应该:)&#xff0c…

创建动态链接库时设置导出函数的方法

有两种方法1.使用模块定义文件, 2.在要导出的函数前加上 __declspec(dllexport) 我们用VS2008新建个DLL工程,工程名为“TestDLL” 把默认的源文件后缀 .CPP改为.C(C文件) int _stdcall MyFunction(int iVariant){return 0; } 1. 使用传统的模…

javascript的浏览器Bom详解,window、location、history对象

BOM(BrowserObjectModel)也叫浏览器对象模型,描述与浏览器进行交互的方法和接口。BOM由多个对象组成, 其中代表浏览器窗口的Window对象是BOM的顶层对象,其他对象都是该对象的子对象。 JavaScript由三部分组成:ECMAScript,BOM&…

MySQL的Master/Slave群集安装和配置

本文介绍MySQL的Master/Slave群集安装和配置,版本号安装最新的稳定版GA 5.6.19。 为了支持有限HA。我们用Master/Slave读写简单孤立的集群。有限HA这是当Master不可用,数据不会丢失。但在Master写的,必须手工处理故障。假设要支持更高的可用性…

动态申请二维数组

以下是动态申请a[m][n]的源代码 代码一&#xff1a; /* 编译器&#xff1a;DEV C */ #include<stdio.h> #include<stdlib.h> int main() {int **a;int i,j,m,n;scanf("%d%d",&m,&n); a (int **)malloc(sizeof(int *)*m);for (i0;i<m; i){a[i…

JavaOne正在重建动力

在JavaOne上度过了一个非常忙碌的一周&#xff0c;今年的活动有很多让人喜欢的地方。 有很多惊喜的公告&#xff0c;很多很好的内容/会议&#xff0c;并且在场地和组织上都有很多改进。 对于一直耐心等待我发表我所有演讲的人们&#xff0c;我为您的延迟表示歉意……给4个演讲一…

tensorflow http调用_《TensorFlow 内核剖析》笔记——系统架构

3 系统架构系统整体组成&#xff1a;Tensorflow的系统结构以C API为界&#xff0c;将整个系统分为前端和后端两个子系统&#xff1a;前端构造计算图后端执行计算图&#xff0c;可再细分为&#xff1a;运行时&#xff1a;提供本地模式和分布式模式计算层&#xff1a;由kernal函数…

(转)数据流图

转自:http://jingyan.baidu.com/article/4f34706eefdb04e387b56deb.html 数据流图4种图元 数据流图的实例 转载于:https://www.cnblogs.com/wrencai/p/5852389.html

MySQL中文乱码问题

项目中用到MySQL数据库时中文出现乱码问题&#xff08;中文字符都变成了&#xff1f;&#xff09;解决&#xff1a; 1、统一项目与数据库的编码&#xff0c;项目中用的是UTF-8因此我的把数据库的编码统一成UTF-8 修改方式&#xff1a;修改 MySQL根目录中的 my.ini 文件替换d…

C++实例讲解Binder通信

binder是android里面的通信机制&#xff0c;这就不说它如何如何好了&#xff0c;Goog已经说过了&#xff0c;这里不多说。binder是一个面向对象的编程方法&#xff0c;大量使用虚函数类。最近研究binder看到一网友写的&#xff0c;就借鉴一下。这个例子很好的解释里binder通信关…

回收对象以提高性能

总览 在上一篇文章中&#xff0c;我说过对象反序列化更快的原因是由于使用了回收对象。 由于两个原因&#xff0c;这可能令人惊讶&#xff1a;1&#xff09;相信如今创建对象是如此之快&#xff0c;无关紧要或与回收自己一样快&#xff0c;2&#xff09;默认情况下&#xff0c;…

oj系统格式错误_论文查重会不会检查格式?【paperpp吧】

高等学校一般都会要求大学生在毕业时需要写作毕业论文&#xff0c;并且会提前发出关于毕业论文的通知&#xff0c;在通知上一般会说明论文写作的相关要求&#xff0c;其中就会规定论文的相关格式。当然&#xff0c;学校也会在通知中说明论文查重的相关事宜&#xff0c;那么论文…

usb大容量存储设备驱动_usb无法识别怎么办 如何解决usb识别故障【详细步骤】...

usb无法识别怎么办? 随着计算机硬件飞速发展&#xff0c;外围设备日益增多&#xff0c;键盘、鼠标等早已为人所共知&#xff0c;数码相机、MP3随身听接踵而至&#xff0c;这么多的设备&#xff0c;如何接入个人计算机?USB就是基于这个目的产生的。USB是一个使计算机周边设备连…

Java EE过去,现在和云7

最近的JavaOne 2011的一个突出主题是下一个主要的Java EE 7版本。 正如主题发言中所述&#xff0c;有关工作正在进行中。 它将包含我们已经从先行者那里知道的28个规范以及一些新规范。 没人可以告诉您确切的号码&#xff0c;因为EE 7仅在“及时”完成时才会接受新的规范。 这意…

程序员都用什么来记录知识_1年前的小五都用 Python 来做什么?

↑ 点击上方 “凹凸数据” 关注 星标 ~ 每天更新&#xff0c;干货不断 (多图预警)注&#xff1a;这是小五一年前在知乎的回答&#xff0c;当时还只有凹凸数读一个公众号&#xff0c;所以很多图片都会带有数读或者知乎的水印。作为一个菜鸟数据分析师&#xff0c;只会sqlpytho…

SQL-行转列(PIVOT)实例1

--未旋转之前的查询结果 select s.Name ShiftName,h.BusinessEntityID,d.Name as DpartmentName from HumanResources.EmployeeDepartmentHistory h inner join HumanResources.Department d on h.DepartmentIDd.DepartmentIDinner join HumanResources.Shift s on s.ShiftIDh…