merge语句使用_使用SQL:2003 MERGE语句的奥术魔术
merge语句使用
- 我们必须至少发表两个声明
- 我们必须考虑性能
- 我们必须考虑比赛条件
- 我们必须在[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语句的奥术魔术相关推荐
- sql select 语句_学习SQL:SELECT语句
sql select 语句 The SELECT statement is probably the most important SQL command. It's used to return r ...
- mysql sql语句 引号_关于sql:何时在MySQL中使用单引号,双引号和反引号
我正在尝试学习编写查询的最佳方法. 我也理解保持一致的重要性. 到现在为止,我已经随机使用单引号,双引号和反引号而没有任何实际想法. 例: $query = 'INSERT INTO table (i ...
- 加sql查询语句导出_搞不懂这些查询语句,SQL简单查询也无法从入门到熟练
大纲: 一.基本的查询语句 二.指定查询条件 三.注释和SQL语句注意事项 四.运算符 五.谓词 一.基本的查询语句 从表中选取数据时需要使用select语句,也就是只从表中选出(select)必要数 ...
- mysql经典sql语句大全_经典SQL语句大全
下列语句部分是Mssql语句,不可以在access中使用. SQL分类: DDL-数据定义语言(CREATE,ALTER,DROP,DECLARE) DML-数据操纵语言(SELECT,DELETE, ...
- mysql 查询语句超时_解决SQL查询总是 超时已过期
1.由于数据库设计问题造成SQL数据库新增数据时超时 症状: Microsoft OLE DB Provider for SQL Server 错误 '80040e31' ([ODBC SQL Ser ...
- mysql的经典sql语句大全_经典SQL语句大全_基础篇_提升篇_技巧篇_开发经典篇
一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- ...
- mysql语句编码_使用SQL语句操作MYSQL字符编码
-- 查看所有的字符编码 SHOW CHARACTER SET; -- 查看创建数据库的指令并查看数据库使用的编码 show create database dbtest; -- 查看数据库编码: s ...
- sql镶嵌查询_标准SQL嵌套查询语句
展开全部 1.简单子查询62616964757a686964616fe78988e69d8331333433626530 select name,age from person where age & ...
- mysql 处理一条语句卡死_一条MySQL查询语句,卡死机器,不知道为什么,求高手指点!...
你的位置: 问答吧 -> MySQL -> 问题详情 一条MySQL查询语句,卡死机器,不知道为什么,求高手指点! 我的这条查询语句有什么问题吗?为什么一运行,机器就卡死了!N久查询不出结 ...
最新文章
- 网络推广下叮咚买菜已完成D轮融资,生鲜电商下一次融资又在何方?
- 网站制作与运营离不开几个重要部分
- hdu 4503 湫湫系列故事——植树节
- Delphi中预想不到的代码楼主zswang(伴水清清)(专家门诊清洁工)2002-05-16 14:20:38 在 Delphi / VCL组件开发及应用 提问
- 【渝粤题库】陕西师范大学700005 遗传学
- 朱啸虎:自己来说可以把一小部分资产购买比特币,作为资产配置是可以考虑的
- 2019 年,Rust 与 WebAssembly 将让 Web 开发更美好
- 数据结构与算法(C#)入门 --- 线性表
- HTML_简单JQ的AJAX响应式交互
- 有一种方法叫“重启”
- VMware Tools手动安装
- 迅雷离线下载分享网站
- 【华为机试真题 Python实现】勾股数元祖
- 从20s优化到500ms,我用了这三招
- DFS(深度优先搜索算法)
- 小马哥----高仿三星note3 n9002 9006主板型号A202 刷机后修复返回键失灵实例说明
- 为什么OFDM抗多径?
- c++ string容器
- 国外cpa广告联盟emu项目最新介绍
- JAVA-打印圆形三种代码
热门文章
- 输入框限定保留三位小数点
- set注意点map遍历
- 希尔排序+移位法(吊打交换法)
- android之微信分享文本
- android拦截短信获取短信内容,《英雄联盟手游》先锋测试招募说明:仅安卓用户...
- php oracle 无查询结果,php - Oracle Insert查询不起作用,也不会抛出任何错误 - 堆栈内存溢出...
- 登录系统 提示框_实物资产管理软件操作手册(职员和系统用户)
- (转)如何查看java本地方法
- commons cli_从Commons CLI迁移到picocli
- oracle中悲观锁定_如何使用悲观锁定修复乐观锁定竞争条件