暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 使用合并更新数据2次

ASKTOM 2019-05-29
204

问题描述

我每天都有100万条记录的完整转储。我需要将此集合获取到STG中。
因此,当我在完全转储 (源) 和STG (目标) 之间进行比较时,有软删除记录,STG中的记录总是大于源。

我已经研究了这个问题,并找到了我可以定制的有用的示例代码。
通过使用合并更新STG中存在的记录和插入STG中不存在的记录。
此外,如果未从完整转储 (源) 中找到记录,但保留在STG中,则需要将STG中的标志更新为 “无效”,因为我需要保留STG中的数据历史记录。

我的问题是我可以标记STG中的非活动记录,但是我无法更新STG中的所有其余更改记录,然后从Source.error缺少关键字。

create table test_tmp2
(
pk_col int,
col2 char(2),
col3 char(2),
action_flag char(1),
CONSTRAINT test_tmp2_PK PRIMARY KEY (pk_col)
);

create table test_stg2
(
pk_col int,
col2 char(2),
col3 char(2),
action_flag char(1),
CONSTRAINT test_stg2_PK PRIMARY KEY (pk_col)
);

insert into test_tmp2 values (1,'A1','B1','A');
insert into test_tmp2 values (3,'A3','B3','A');

insert into test_stg2 values (1,'A0','B1','A');
insert into test_stg2 values (2,'A2','B2','A');

merge /*+ append */ into test_stg2 O
using (
  select * from (
    select PK_COL,COL2,COL3,操作 _ 标志,
      COUNT(*) over(partition by PK_COL) - SUM(Z##_CNT) Z##IUD_FLAG
    from (
      select PK_COL, COL2, COL3, action_flag,
        -1 Z##_CNT
      from test_stg2 O
      union all
      select PK_COL,COL2,COL3,操作 _ 标志,
        1 Z##_CNT
      from test_tmp2 N
    )
    group by PK_COL,COL2,COL3,操作 _ 标志
    having SUM(Z##_CNT) != 0
  )
  where Z##IUD_FLAG < 3
) N
on (O.PK_COL=N.PK_COL)

when matched then update set
  o.action_flag = case when N.Z##IUD_FLAG = 2 then 'i' else null end
  update set COL2=N.COL2, COL3=N.COL3, action_flag=N.action_flag; -- Here is my issue.

when not matched then insert (PK_COL, COL2, COL3, action_flag)
  values(N.PK_COL, N.COL2, N.COL3, N.action_flag);
复制


我想在STG中获得的结果;
PK_COL,COL2,COL3,操作 _ 标志
1、A0、B1、A
2、A2、B2、I
3、A3、B3、A

致以最诚挚的问候,

专家解答

你不能在一次合并中有两个更新子句!

并且您只能设置每个列一次。

问题是你用Z # # IUD_FLAG设置行!= 2到null。在我看来,您需要做的就是在案例的else子句中返回源action_flag。

这样做给我的输出要求:

merge into test_stg2 O
using (
  select * from (
    select PK_COL, COL2, COL3,action_flag,
      COUNT(*) over(partition by PK_COL) - SUM(Z##_CNT) Z##IUD_FLAG
    from (
      select PK_COL, COL2, COL3, action_flag,
        -1 Z##_CNT
      from test_stg2 O
      union all
      select PK_COL, COL2, COL3,action_flag,
        1 Z##_CNT
      from test_tmp2 N
    )
    group by PK_COL, COL2, COL3,action_flag
    having SUM(Z##_CNT) != 0
  )
  where Z##IUD_FLAG < 3
) N
on (O.PK_COL=N.PK_COL)
when matched then update set
  o.action_flag = case when N.Z##IUD_FLAG = 2 then 'I' else N.action_flag end,
  COL2=N.COL2, COL3=N.COL3
when not matched then insert (PK_COL, COL2, COL3, action_flag)
  values(N.PK_COL, N.COL2, N.COL3, N.action_flag);
  
select * from test_stg2;

PK_COL    COL2    COL3    ACTION_FLAG   
        1 A1      B1      A              
        2 A2      B2      I              
        3 A3      B3      A  
复制

文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论