《Oracle SQL疑难解析》——1.16 基于条件的插入或修改

1.16 基于条件的插入或修改

Oracle SQL疑难解析

1.16.1 要解决的问题

我们需要在表中插入一条记录,插入前根据KEY标识符判断。如果标识符不存在,则插入新记录;如果标识符已经存在,则根据语句中所给的新值对原记录中的字段进行更新。

1.16.2 解决方法

MERGE语句的功能是将新数据插入一个表中。记录是否存在,由主(PRIMARY)键进行判断。如果主键不存在于表中,则插入该行。如果主键匹配表中已有的行,则通过匹配键的其他详细信息更新该行。

在示例中,假设要把NEW_COUNTRIES 表中一些国家的信息添加到HR.COUNTIES表中:

merge into hr.countries c
using
 (select country_id, country_name
  from hr.new_countries) nc
on (c.country_id = nc.country_id)
when matched then
 update set c.country_name = nc.country_name
when not matched then
 insert (c.country_id, c.country_name)
 values (nc.country_id, nc.country_name);

1.16.3 数据库如何工作

如果直接把HR.NEW_COUNTRIES中的源数据插入HR.COUNTRIES目标表中,有可能会失败,由于HR.COUNTRIES表中可能已经有此国家的记录,因此造成主键值重复而插入失败。MERGE语句可以通过逻辑分支子句的ON来处理存在和不存在这两种情况。

通常,ON子句指定如何在源表和目标表之间匹配主键或唯一键。在本例句中,用COUNTRY_ID来匹配:

on (c.country_id = nc.country_id)

ON 子句后面跟着另两个子句,当键值相匹配时,执行“WHEN MATCHED CLAUSE”子句内容,当键值不匹配时,执行“WHEN NOT MATCHED”子句,会把新的记录插入目标表中。

match和not-match子句都可以包含更多的筛选条件,当满足删除条件时,也可以删除记录:

merge into hr.countries c
using
 (select country_id, country_name, region_id
  from hr.new_countries) nc
on (c.country_id = nc.country_id)
when matched then
 update set c.country_name = nc.country_name,
  c.region_id = nc.region_id
 delete where nc.region_id = 4
when not matched then
 insert (c.country_id, c.country_name, c.region_id)
 values (nc.country_id, nc.country_name, nc.region_id)
 where (nc.region_id != 4);

在这个修改后的版本中,除了REGION_ID的新值是4的行,其他根据COUNTRY_ID匹配的HR.CONTRIES的行都会修改COUNTR_NAME的值,而REGION_ID是4的行最终会删除。没有匹配上的行,除了REGION_ID的值是4的行,其他行都会被插入HR.COUNTRIES中,而REGION_ID的值是4的行会被忽略。

时间: 2024-08-02 09:16:49

《Oracle SQL疑难解析》——1.16 基于条件的插入或修改的相关文章

《Oracle SQL疑难解析》导读

前言 Oracle SQL疑难解析 欢迎阅读本书.现在你手中的这本书,对在Oracle数据库中编写SQL时经常碰到的问题提供了现成的解决方法.这本书写给那些迫切需要解决某个特定问题的人.本书每一节讨论一个特定的问题,并为这一问题提供了一个有效的解决方法.对于解决方法感兴趣的人,每一节还扩展讨论了解决方法,有些还提供了替代解决方法. 我们精心编写了这本书,是为了让你掌握如何为Oracle编写SQL,至少可以让你了解Oracle的SQL.虽然我们把内容分割成有逻辑的章节,例如,数据类型或生成报表,但

《Oracle SQL疑难解析》——1.7 改变行记录的值

1.7 改变行记录的值 Oracle SQL疑难解析 1.7.1 要解决的问题 修改表中一行或多行的值. 1.7.2 解决方法 就像命令的字面意义一样,UPDATE语句是用来修改数据的.假定我们想给部门代码为50的每个员工增加5%的薪水,就可以用下面这个UPDATE语句: update hr.employees set salary = salary * 1.05 where department_id = 50; 1.7.3 数据库如何工作 基本的UPDATE语句设计就以UPDATE子句开始:

《Oracle SQL疑难解析》——1.12 查询的WHERE子句基于另一个查询的结果

1.12 查询的WHERE子句基于另一个查询的结果 Oracle SQL疑难解析 1.12.1 要解决的问题 我们要从某张表中查询数据,但查询条件依赖当时另一张表中的数据情况,所以不能直接把条件固定到语句中.具体地说,我们现在要做一个报告,把所有办公场所在北美的部门列出来. 1.12.2 解决方法 在HR SCHEMA中,DEPARTMENT表中有部门的信息,LOCATIONS表中有办公场所的信息: select department_name from hr.departments where

《Oracle SQL疑难解析》——.13 在语句中找到和消除空值

1.13 在语句中找到和消除空值 Oracle SQL疑难解析 1.13.1 要解决的问题 我们需要统计出公司中,有多少员工的薪酬里含销售提成(commission percentage),有多少员工的薪酬是固定工资.我们可以用HR.EMPLOYEES表中的COMMISSION_PCT字段来获得数据. 1.13.2 解决方法 HR.EMPLOYEES表的结构允许COMMISSION_PCT字段为空值.有两个查询语句可以分别查找commission percent为空值的人和为非空值的人.首先,查

《Oracle SQL疑难解析》——1.15 启用其他排序和比较选项

1.15 启用其他排序和比较选项 Oracle SQL疑难解析 1.15.1 要解决的问题 文本数据由大.小写字母和句子(英文句子,指第一个字母大写,后续字母小写)组成,我们希望对之进行不区分大小写的比较.排序等操作. 1.15.2 解决方法激活Oracle的语言比较逻辑,就能按人类的习惯来查询数据,摆脱大小写负担: alter session set NLS_COMP='LINGUISTIC'; select first_name, last_name from hr.employees wh

《Oracle SQL疑难解析》——1.14 排序

1.14 排序 Oracle SQL疑难解析 1.14.1 要解决的问题 我们的文本数据混合了大写.小写字母和句子(英文句子,指第一个字母大写,后续字母小写).我们希望把这些数据按字母顺序.大小写顺序进行排列. 1.14.2 解决方法 我们先在HR.EMPLOYEES表中创建一些混合大小写的数据.运行下面的UPDATE语句,把William Smith's的姓(last_name)改为大写: update hr.employees set last_name = 'SMITH' where em

《Oracle SQL疑难解析》——1.1 从表中查询数据

1.1 从表中查询数据 Oracle SQL疑难解析 1.1.1 要解决的问题 如何从一个表中查询特定行和列的数据. 1.1.2 解决方法 用包含WHERE子句的SELECT语句.下面的SELECT 语句可以从数据库表中查询符合条件的行的列值: select employee_id, first_name, last_name, hire_date, salary from hr.employees where department_id = 50 and salary < 7500; 上述SE

《Oracle SQL疑难解析》——1.6 批量地从一个表中复制数据到另一个表

1.6 批量地从一个表中复制数据到另一个表 Oracle SQL疑难解析 1.6.1 要解决的问题 如何从一个表中一次性复制多行记录到另一个表. 1.6.2 解决方法 INSERT INTO... SELECT... 方法可以插入多行记录,关键是用SELECT语句选择多行记录时一定要用对选择条件.我们把以前的SELECT语句做一点修改,就可以选择多行记录了: 当然,前提是存在HR.CANDIDATES表,在做练习前,应确保你的HR.CANDIDATES表和例子中的表是一致的. 1.6.3 数据库

《Oracle SQL疑难解析》——1.8 在一个语句中修改多个字段值

1.8 在一个语句中修改多个字段值 Oracle SQL疑难解析 1.8.1 要解决的问题 需要在一个表中修改一行或多行的多个字段值. 1.8.2 解决方法 UPDATE语句可以让我们轻松地修改一行或多行的数据,我们也可以在UPDATE语句中用多个"column=value"子句来修改多个字段的值.例如,我们可以用下面的单个UPDATE语句来修改James Marlow(其EMPLOYEE_ID为131)的电话号码.工作角色和薪水: update hr.employees set jo