使用 if exists 使用合并 oracle sql 逻辑插入或更新

Posted

技术标签:

【中文标题】使用 if exists 使用合并 oracle sql 逻辑插入或更新【英文标题】:insert or update using if exists using merge oracle sql logic 【发布时间】:2020-05-08 09:52:19 【问题描述】:

我正在从事务系统后端 oracle db 中获取数据,这是我的源和目标也是一对一的同一张表

我需要编写一个合并语句来检查基于新值的插入或更新

源交易表

create table product 
(
product_id pk VARCHAR2(3 BYTE),
product_nm VARCHAR2(100 CHAR),
product_cd VARCHAR2(10 CHAR),
product_dec VARCHAR2(500 CHAR),
insert_ts date,
update_ts date,
version NUMBER(38,0),
product_interval_strt NUMBER(38,0),- these are some numeric values
product_interval_end NUMBER(38,0) - these are some numeric values
)

因为 etl (PDI) 抛出错误

无法从数据库结果集中获取值 'Integer(38)',索引 11 数值溢出

所以我使用了以下内容,以便 PDI 将其读取为 Bignumber 37

CAST (product_interval_strt AS number(37,0)) INTERVAL_START , CAST (product_interval_strt AS number(37,0)) product_interval_end

目标交易表

create table product_stg 
(
product_id pk VARCHAR2(3 BYTE),
product_nm VARCHAR2(100 CHAR),
product_cd VARCHAR2(10 CHAR),
product_dec VARCHAR2(500 CHAR),
insert_ts date,
update_ts date,
version NUMBER(38,0),
product_interval_strt NUMBER(38,0),- these are some numeric values
product_interval_end NUMBER(38,0) - these are some numeric values
)

所以我使用了以下内容,以便 PDI 将其读取为 Bignumber 37

CAST (product_interval_strt AS number(37,0)) INTERVAL_START ,
CAST (product_interval_strt AS number(37,0)) product_interval_end

所以我需要准备一个合并 sql 语句来检查 product_id 是否存在 do update 不存在 do insert ,但我不确定我只需要使用下面的

如果值存在更新或插入,我需要准备一个简单的合并语句

如果以下骨架/结构正确,请纠正我

merge into MY_TABLE tgt
using (select [expressions]
         from dual ) src
   on (src.key_condition = tgt.key_condition)
when matched then 
     update tgt
        set tgt.column1 = src.column1 [,...]
when not matched then 
     insert into tgt
        ([list of columns])
     values
        (src.column1 [,...]);

【问题讨论】:

PDI 是 pentho 吗? @Digvijay - 是的 @Lalith Kumar 什么不正确/更新了 - 来自查询? 【参考方案1】:
when matched then  
     update tgt --> Incorrect syntax
        set tgt.column1 = src.column1 [,...]
when not matched then 
     insert into tgt --> Incorrect syntax

MERGE 语句的语法不正确。目标表名在MERGE INTOsyntax中已经提到,不需要在UPDATEINSERT子句中再次指定表名。 update 和 insert 子句的正确语法是:

WHEN MATCHED THEN 
    UPDATE SET TGT.product_nm = SRC.product_nm
WHEN NOT MATCHED THEN 
    INSERT (TGT.product_id, TGT.product_nm .....)
    VALUES (SRC.product_id, SRC.product_nm .....);

【讨论】:

@Lalith - 非常适合纠正我的误解 @rakesh 不客气,请将其标记为已回答。 @Lalith - 为什么更新条件下没有 ID 列? @Lalith - 我错过了一点,这两个服务器都是差异服务器,在这种情况下如何处理? @rakesh 你的意思是你在两个不同的数据库中有源表和目标表?然后你需要在它们之间创建一个数据库链接。【参考方案2】:

试试这个

MERGE INTO product TGT
   USING (SELECT product_id
,product_nm
,product_cd
,product_dec
,insert_ts
,update_ts
,version
,CAST (product_interval_strt AS number(37,0)) INTERVAL_START 
,CAST (product_interval_strt AS number(37,0)) product_interval_end
FROM product_stg 
) SRC
   ON (SRC.product_id = TGT.product_id)
   WHEN MATCHED THEN UPDATE SET TGT.product_nm=SRC.product_nm ......)
   WHEN NOT MATCHED THEN INSERT (TGT.product_id, TGT.product_nm .....)
     VALUES (SRC.product_id, SRC.product_nm .....);

【讨论】:

@Digvijjay 我正在尝试,但如果错误,您能看到示例结构吗? 你是对的,感谢您对代码的快速建议 @Digvijjay - 为什么在匹配条件中不考虑 ID 列? 你正在匹配基于ID的权利。它已经存在于表中。

以上是关于使用 if exists 使用合并 oracle sql 逻辑插入或更新的主要内容,如果未能解决你的问题,请参考以下文章

删除表如果它存在于 Oracle (IF EXIST) [重复]

检查架构中的 IF 表 EXISTS 时发生 Oracle PL/SQL 过程错误 [重复]

markdown Oracle Drop If Exists.md

oracle insert if not exists 语句

SQLSERVER 和 ORACLE的if not exist 用法

IF EXISTS 和 MERGE 语句