Oracle:更新旧行时创建新行

Posted

技术标签:

【中文标题】Oracle:更新旧行时创建新行【英文标题】:Oracle:Create new Row while updating old row 【发布时间】:2020-10-04 16:49:13 【问题描述】:

您好,我正在尝试在下面创建一个新行,同时更新旧行值。

我有一个名为 TestCustomer 的下表,我想将现有行状态更新为“I”,如果插入时 customer_id 匹配,则使用新的 email_Id 和状态“A”创建一个新行;

create table TestCustomer(customer_id varchar(18),emai_id varchar(18),email_stat char(1))

Insert Into TestCustomer(customer_id,emai_id,email_stat)values('223459','12345','A');
Insert Into TestCustomer(customer_id,emai_id,email_stat)values('223458','123456','I');
Insert Into TestCustomer(customer_id,emai_id,email_stat)values('223459','123457','A');

输入:

customer_id=223459 emai_id='23678'

输出:

输出

【问题讨论】:

通过基于值的插入语句来实现具有挑战性。为了理想地实现这一点,您应该将传入的源数据放在临时表或类似的东西中。 我不知道你想做什么。在您的示例数据中,customer_id 223458 发生了什么? “如果插入时客户 ID 匹配”是什么意思?匹配什么? 我正在为给定的客户更新一个新的 email_id,在本例中为 223459。因此与客户关联的旧 email_id 将处于非活动状态,而新的电子邮件 ID 将处于活动状态。 【参考方案1】:

您可以使用merge 语句在using 子句中使用两行来获取它:第一行用于update,第二行用于insert

merge into TestCustomer t
using (
      select
         c,
         223459  as customer_id,
         '23678' as emai_id
      from dual
           ,(select 'A' c from dual union all select 'X' c from dual)
) v
on (v.c='X' and t.customer_id=v.customer_id)
when matched then update
    set email_stat='I'
when not matched then
    insert (customer_id,emai_id,email_stat)
    values(v.customer_id,v.emai_id,v.c)
    where v.c='A';

如您所见,带有“X”的行用于更新,带有“A”的行。

完整示例:https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=4f014283e5eff2e4cc81d09f0bbfca9b

【讨论】:

以上是关于Oracle:更新旧行时创建新行的主要内容,如果未能解决你的问题,请参考以下文章

插入行时 UDF 不更新

如何创建不更新旧数据的增量视图?

oracle触发器在表中插入新行时更新新的视图行

在 Oracle SQL 中查询不返回单行时更新

创建、编辑或删除新行后表格不更新

使用不存在的 hbase 行键更新行?