Oracle 数据库实现数据合并:merge

1、使用update进行数据更新

  1)最简单的更新

  update tablea a set a.price=1.00

  2)带条件的数据更新

  update tablea a set a.price = 2.00  where  a.id=‘02‘

  3)两张表关联更新为固定值

  update tablea a set a.price =3.00 where exits(select 1 from tableb b where a.id=b.id)

  将a,b相同id的 a表的price 字段更新为 3.00

  4)关联更新数据来源第二张表

  update tablea a set a.price=(select price from tablec c ) where exits (select 1 from tablec c where a.id=c.id)

  将a表price字段 更新为 id和c表id相同的数据

  5)关联更新多个字段

  update tablea a set ( a.price,a.type)=(select c.price,c.type from tablec c ) where exits (select 1 from tablec c where a.id=c.id)

  更新a表的price 和 type 字段  

  6)使用视图方式更新

  update (select a.price old,c.price as new from tablea a ,tablec c where a.id=c.id) set old=new

以上为自己了解到的Update使用方式,需要注意 a.id 和c.id需要一一对应。即c表只有一条id 与a表id对应,否则会报错

ORA-01427:"single-row subquery returns more than one row"

单行查询返回多行结果。是不能进行更新的。

2、merge 更新使用

  工作中要对一个字段:次数 进行更新 表数据量在 13w+ 需要两表关联 也就是 两个 13w+ 的表进行关联。

  在使用update进行更新的时候,效率问题大大降低。加上限制条件更新 100条数据还用了6-8S,所以 update并不适用。

  查阅资料看到merge 更新,便学习记录。

  MERGE 在SQL ServerOracle数据库中可用,MySQL、PostgreSQL中不可用。可以同时进行更新和插入操作。执行效率要高于INSERT+UPDATE。

  语法:

  MERGE INTO [your table-name] [rename your table here]
  USING ( [  your query ] )[rename your query-sql and using just like a table]
  ON ([conditional expression  ] AND [...]...)
  WHEN MATHED THEN [here you can execute some update sql or something else ]
  WHEN NOT MATHED THEN [execute something else here ! ]

  示例

  merge into tablea a        ----要更新或者操作的表

  using tablec c     ----源表 using (select * from tablec ) c

  on a.id=c.id      --匹配条件

  when matched then set a.price=c.price  --当匹配时进行更新操作

  when not matched then     --不匹配进行插入操作

  insert values values(c.id,c.price)

  using 后不仅可以使用 表 也可以是 视图或者子查询 using (select * from tablec ) c

  not matched 可以没有 就是当不匹配什么也不做。

  

  总结:

  之前说的使用update更新100行数据都需要6-8S 使用merge 更新全部数据(13W+ 与13W+ 关联)只用了10S左右。更新效率可见要比update高很多。

SQL Server 2008 开始支持 MERGE语句 

-- 源表
CREATE TABLE test_from (id INT, val VARCHAR(20));

-- 目标表
CREATE TABLE test_to (id INT, val VARCHAR(20));

-- 插入源表
INSERT INTO test_from VALUES (1, ‘A‘);
INSERT INTO test_from VALUES (2, ‘B‘);

-- 合并 源表到目标表
MERGE test_to USING test_from
ON ( test_to.id = test_from.id )    -- 条件是 id 相同
WHEN MATCHED THEN UPDATE SET test_to.val = test_from.val   -- 匹配的时候,更新
WHEN NOT MATCHED THEN INSERT VALUES(test_from.id, test_from.val) -- 源表有,目标表没有,插入
WHEN NOT MATCHED BY SOURCE THEN DELETE; -- 目标表有,源表没有,目标表该数据删除.

-- 第一次检查 目标表数据.
SELECT * FROM test_to;

id          val
----------- --------------------
          1 A
          2 B

-- 更新源表
UPDATE test_from SET val = ‘A2‘ WHERE id = 1;
-- 删除源表
DELETE FROM test_from WHERE id = 2;
-- 插入源表
INSERT INTO test_from VALUES (3, ‘C‘);

-- 合并 源表到目标表
MERGE test_to USING test_from
ON ( test_to.id = test_from.id )    -- 条件是 id 相同
WHEN MATCHED THEN UPDATE SET test_to.val = test_from.val   -- 匹配的时候,更新
WHEN NOT MATCHED THEN INSERT VALUES(test_from.id, test_from.val) -- 源表有,目标表没有,插入
WHEN NOT MATCHED BY SOURCE THEN DELETE; -- 目标表有,源表没有,目标表该数据删除.

-- 再次检查 目标表数据.
SELECT * FROM test_to;

id          val
----------- --------------------
          1 A2
          3 C

Merge-数据库风格的合并
数据的合并(merge)和连接(join)是我们在数据分析和挖掘中不可或缺的,是通过一个或一个以上的键连接的。pandas的合并(merge)的的绝大功能和数据库操作类似的。具有如下参数:

pd.merge(left, right, how=’inner’, on=None, left_on=None, right_on=None, left_index=False,right_index=False, sort=False, suffixes=(‘_x’, ‘_y’), copy=True, indicator=False, validate=None)

各个参数的含义:
left、right:左右连接对象

how:连接方式,共有’inner’,’left’,right’,’outer’

on:根据连接的键

left_on、right_on:在连接的键名不同的情况下使用,left_on传入左对象的键,right_on传入右对象的键

left_index、right_index:设置索引是否作为连接的键,通常 left_on=??和right_index=True, right_on=??和left_index=True,或者left_index=True和right_index=True

sort:对连接后的结果是否排序,当数据巨大的时候为了追求效率可以设置为False

suffixes:对于不作为键的同名列,在其列名后添加的后缀

copy:将左右对象的内容复制过来,默认为True
---------------------

MERGE语句是SQL语句的一种。在SQL Server、Oracle数据库中可用,MySQL、PostgreSQL中不可用。MERGE是Oracle9i新增的语法,用来合并

UPDATE和INSERT语句。通过MERGE语句,根据一张表(原数据表,source table)或子查询的连接条件对另外一张(目标表,target table)表

进行查询,连接条件匹配上的进行UPDATE,无法匹配的执行INSERT。这个语法仅需要一次全表扫描就完成了全部工作,执行效率要高于INSERT

+UPDATE.具体来说,MERGE语句会检查原数据表记录和目标表记录。如果记录在原数据表和目标表中均存在,则目标表中的记录将被原数据表中的

记录所更新(执行Update操作);如果目标表中不存在的某(些)记录,在原数据表中存在,则原数据表的这(些)记录将被插入到目标表中(

执行Insert操作)。在Oracle 10g之前,merge语句支持匹配更新和不匹配插入两种简单的用法,在10g中Oracle对merge语句做了增强,增加了

条件选项和DELETE操作。

Merge语法

  MERGE [hint] INTO [schema ] table [t_alias]

  USING [schema ] { table | view | subquery } [t_alias]

  ON ( condition )

  WHEN MATCHED THEN merge_update_clause

  WHEN NOT MATCHED THEN merge_insert_clause;

代码及说明

  1.MERGE INTO test T1

  2.USING (SELECT OWNER, OBJECT_NAME, MAX(ID) ID FROM T GROUP BY OWNER, OBJECT_NAME) T

  3.ON (T,OWNER = T1,OWNER AND T.OBJECT_NAME = T1,TABLE_NAME)

  4.WHEN MATCHED THEN UPDATE SET T1,ID = T,ID

  5.WHEN NOT MATCHED THEN INSERT VALUES (T,ID, T,OWNER, T,OBJECT_NAME);

  第一行 命名目标表并给别名T1

  第二行 using子句提供merge操作的数据源,命名T

  第三行 on子句指定合并的条件

  第四行 when matched then 子句判定条件符合则对表T1做什么改变(或删除)

  第五行 when not matched then 子句判断条件不符合则插入的操作

上面为数据库中merge,下面为hibernate中merge和update的区别

1. 数据库记录已存在,更改person的name为一个新的name。

merge方法打印出的日志如下:
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from person person0_ where person0_.id=?
Hibernate: update person set name=? where id=?

update方法打印出的日志如下:
Hibernate: update person set name=? where id=?

2. 数据库记录已存在,更改person的name和数据库里对应id记录的name一样的值。

merge方法打印出的日志如下:
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from person person0_ where person0_.id=?
此处相对于第一种情形少了update的动作

update方法打印出的日志如下:
Hibernate: update person set name=? where id=?

3. 数据库记录不存在时,也就是你传的实体bean的ID在数据库没有对应的记录。

merge方法打印出的日志如下:
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from person person0_ where person0_.id=?
Hibernate: insert into person (name) values (?)
如果没有对应的记录,merge会把该记录当作新的记录来插入。此处我很疑惑,因为我传得person实体对象里写明了id值的,它为什么还会做插入的动作呢?

原文地址:https://www.cnblogs.com/klb561/p/10660390.html

时间: 2024-11-08 05:17:56

Oracle 数据库实现数据合并:merge的相关文章

oracle数据库删除数据Delete语句和Truncate语句的对比

oracle数据库删除数据Delete语句和Truncate语句的对比 当表中的数据不需要时,则应该删除该数据并释放所占用的空间,删除表中的数据可以使用Delete语句或者Truncate语句,下面分别介绍. 一.delete语句 (1)有条件删除    语法格式:delete [from]  table_name  [where condition]; 如:删除users表中的userid为‘001’的数据:delete from users where userid='001'; (2)无条

Oracle数据库用户数据完整备份与恢复

使用PLSQL-Developer工具可以快速便捷地完成Oracle数据库用户.表的备份恢复. Oracle数据库用户数据完整备份与恢复 1. 备份 1.1   PL/SQL->工具->导出用户对象,选项如图 常用的用户对象包括: TABLE,SEQUENCE,VIEW,PACKAGE,TYPE,FUNCTION,PROCEDURE,PACKAGE BODY,TREGGER 选择需要导入的用户对象,导出.sql文件,此步骤导出的是建表语句,包括存储过程.触发器.视图等 . 1.2  PL/SQ

C#连接Oracle数据库查询数据

C#连接Oracle数据库可以实现许多我们需要的功能,下面介绍的是C#连接Oracle数据库查询数据的方法,如果您对C#连接Oracle数据库方面感兴趣的话,不妨一看. using System; using System.Collections.Generic; using System.ComponentModel using System.Data.OracleClient;;//这行和下一行都要先在引用中填加system.data.oracleclient using System.Da

Oracle数据库批量数据导出工具开发

Oracle数据库批量数据导出工具开发 需求 最近工作中遇到一个需求,用户频繁要求从后台批量导出大量数据.目前的导出方式是使用PL/SQL Developer工具连接Oracle数据库,编写SQL语句,使用PL/SQL Developer工具自带的导出Excel文件的功能进行导出. 编写SQL查询结果 2.选择导出Excel文件 选择导出Excel文件时可以选择导出XLS.XLSX两种格式的文件. 遇到的问题:当用户要求导出的数据条数太大,超过XLS或者XLSX两种文件可以存储的最大行数时即导出

Oracle数据库备份数据缺失的问题

项目中一直在使用Oracle数据库,由于我之前更多的是关注ORM映射框架,几乎没有关注过Oracle特性的东西,很多东西都不知道,而且项目中换数据库的概率几乎为零,所以有必要好好研究一下Oracle.正所谓,不怕不知道,就怕不知道嘛.不然遇到问题,都不知道从哪里下手. 这两天的Oracle学习,收获不小.前几天测试中遇到很多的稀奇古怪的问题,都被很好的解释了.这里就一个典型的例子谈一谈. 就是在测试阶段,看着经理熟练的操作Oracle的各个指令,内心就已经有了一点不平静.经理就是经理,这都是多少

Oracle数据库,数据的增、删、改、查

oracle数据库中,数据的增.删.改.查,通过SQL语句实现 SQL:结构化查询语言: 特点:不区分大小写:字符串用单引号引起来:语句结束用分号表示结束: 行注释,在语句的最前面加"--" 块注释,分别在语句的前后加    /*  和  */ SQL中常用的几类: 一.数据定义语言 DDL:创建.修改.删除数据库语言. create table Student ( sno varchar2(3) not null, sname varchar2(8) not null, ssex v

北亚案例:oracle数据库误删除数据的恢复方法

学习数据库时,我们只是以学习的态度,考虑如何使用数据库命令语句,并未想过工作中,如果误操作一下,都可能导致无可挽回的损失.当我在工作中真正遇到这些问题时,我开始寻找答案. 今天主要以oracle数据库为例,介绍关于表中数据删除的解决办法.(不考虑全库备份和利用归档日志) 删除表中数据有三种方法: ·delete(删除一条记录) ·drop或truncate删除表格中数据 1.delete误删除的解决方法 原理:利用oracle提供的闪回方法,如果在删除数据后还没做大量的操作(只要保证被删除数据的

从SQL Server数据库转到Oracle数据库的数据脚本处理

在我们很多情况下的开发,为了方便或者通用性的考虑,都首先考虑SQL Server数据库进行开发,但有时候客户的生产环境是Oracle或者其他数据库,那么我们就需要把对应的数据结构和数据脚本转换为对应的数据库,数据结构一般来说,语法都遵循了SQL92的标准,或者我们根据不同的PowerDesigner文件进行生成对应的结构脚本即可,但是实际数据的脚本我们就需要进行一定的处理,以及文本的替换处理了,本文结合Notepad++的文本正则表达式替换,实现一些如日期较为特殊的数据脚本调整,把它从SQL S

恢复oracle数据库误删除数据的方法汇总

学习数据库时,我们只是以学习的态度,考虑如何使用数据库命令语句,并未想过工作中,如果误操作一下,都可能导致无可挽回的损失.当我在工作中真正遇到这些问题时,我开始寻找答案.今天主要以oracle数据库为例,介绍关于表中数据删除的解决办法.(不考虑全库备份和利用归档日志) 删除表中数据有三种方法:·delete(删除一条记录)·drop或truncate删除表格中数据 1.delete误删除的解决方法    原理:利用oracle提供的闪回方法,如果在删除数据后还没做大量的操作(只要保证被删除数据的