问题描述
我每天都有100万条记录的完整转储。我需要将此集合获取到STG中。
因此,当我在完全转储 (源) 和STG (目标) 之间进行比较时,有软删除记录,STG中的记录总是大于源。
我已经研究了这个问题,并找到了我可以定制的有用的示例代码。
通过使用合并更新STG中存在的记录和插入STG中不存在的记录。
此外,如果未从完整转储 (源) 中找到记录,但保留在STG中,则需要将STG中的标志更新为 “无效”,因为我需要保留STG中的数据历史记录。
我的问题是我可以标记STG中的非活动记录,但是我无法更新STG中的所有其余更改记录,然后从Source.error缺少关键字。
我想在STG中获得的结果;
PK_COL,COL2,COL3,操作 _ 标志
1、A0、B1、A
2、A2、B2、I
3、A3、B3、A
致以最诚挚的问候,
因此,当我在完全转储 (源) 和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。
这样做给我的输出要求:
并且您只能设置每个列一次。
问题是你用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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




