使用 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 INTO
syntax中已经提到,不需要在UPDATE
和INSERT
子句中再次指定表名。 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 语句