在 ORACLE 中使用 MERGE 语句删除和插入

Posted

技术标签:

【中文标题】在 ORACLE 中使用 MERGE 语句删除和插入【英文标题】:DELETE and INSERT using MERGE statement in ORACLE 【发布时间】:2020-01-30 11:11:40 【问题描述】:

我有实体 Employee,它有一个字段 List<String> accountIds.

所以表结构是这样的:

CREATE TABLE EMPLOYEE (
ID varchar2(255) not null,
OBJ_ID varchar2(36), 
NAME varchar2(255),
VER_NBR number(19,0),
CREATEID varchar2(255) not null,
CREATETIME timestamp (6) not null,
UPDATEID varchar2(255),
UPDATETIME timestamp (6),
primary key (ID));

为了存储 AccountIds 我还有另一个表

CREATE TABLE EMPLOYEE_ACCOUNT_IDS(
        EMP_ID varchar2(255),
        ACC_ID varchar2(255),
        primary key (EMP_ID, ACC_ID)
);

更新操作:EMPLOYEE 表中的 ACCOUNT_IDS

现在,在应用程序中,我正在删除与该员工相关的所有帐户 ID,然后重新插入所有帐户。

提高性能并减少数据库查询的数量。这可能与“合并”声明有关吗?

【问题讨论】:

EMPLOYEE 表中没有ACCOUNT_ID 列。 【参考方案1】:

是的。这是可能的,不确定是否比删除和插入更快。我不知道你的输入是什么样子的,所以你如何执行插入会很好。无论如何,您可以连接现有数据和新值并将此查询用作源表。

merge into employee_account_ids tgt
using (  
  with new_data(acc_id) as (select * from table(sys.odcivarchar2list('NEW01', 'NEW02', 'ACC13')))
    select '001' emp_id, nvl(a.acc_id, n.acc_id) acc_id, rwd,
           case when n.acc_id is null then 'del' end dsc
      from new_data n 
      full join (select e.*, rowid rwd from employee_account_ids e where emp_id = '001') a 
        on a.acc_id = n.acc_id ) src
on (src.emp_id = tgt.emp_id and src.rwd = tgt.rowid)
when matched then update set tgt.acc_id = tgt.acc_id delete where dsc = 'del'
when not matched then insert values (src.emp_id, src.acc_id)

dbfiddle

问题是您的第二个表没有我可以触摸以执行删除的虚拟列,因为 Oracle 需要先更新才能删除行。所以我使用了rowid,被骗更新(tgt.acc_id = tgt.acc_id),它可以工作。

【讨论】:

以上是关于在 ORACLE 中使用 MERGE 语句删除和插入的主要内容,如果未能解决你的问题,请参考以下文章

我们如何在 Oracle Merge 语句中使用 use parallel (10) 提示

在 Oracle Merge 语句的 Using 子句中指定参数

Oracle 使用MERGE INTO 语句更新数据

oracle merge into用法

Oracle MERGE语句

mybatis 使用oracle merge into 语句踩坑实录