【发布时间】:2020-07-08 14:29:24
【问题描述】:
我必须在 plsql 中编写一个程序来使用游标逐行读取数据,如果有任何重复记录,则在 stg 表中将其标记为重复...谁能帮我编写程序从 stg 表中选择数据然后逐行检查是否有重复,然后插入有效记录。
【问题讨论】:
标签: for-loop plsql duplicates cursor
我必须在 plsql 中编写一个程序来使用游标逐行读取数据,如果有任何重复记录,则在 stg 表中将其标记为重复...谁能帮我编写程序从 stg 表中选择数据然后逐行检查是否有重复,然后插入有效记录。
【问题讨论】:
标签: for-loop plsql duplicates cursor
这是一个简单的例子。
有几种方法可以做到这一点。
-- Create test table
create table stg ( id number, is_dup varchar2(1) );
-- Insert data with dups
insert into stg ( id ) values ( 1 );
insert into stg ( id ) values ( 1 );
insert into stg ( id ) values ( 2 );
insert into stg ( id ) values ( 3 );
insert into stg ( id ) values ( 4 );
insert into stg ( id ) values ( 5 );
insert into stg ( id ) values ( 4 );
-- Check data
select * from stg;
ID I
---------- -
1
1
2
3
4
5
4
7 rows selected.
使用 CURSOR 的方法是:
DECLARE
CURSOR c1 IS
SELECT id, COUNT(1) nc
FROM stg
GROUP BY id;
BEGIN
FOR r1 IN c1 LOOP
IF r1.nc = 1 THEN
-- Insert valid
INSERT INTO tab ( cols )
SELECT cols
FROM stg
WHERE id = r1.id;
ELSE
-- Update dup
UPDATE stg SET is_dup = 'Y' WHERE id = r1.id;
END IF;
END LOOP;
COMMIT;
END;
/
我更喜欢基于集合的方法:
-- apply UPDATE to mark duplicates with Y
update stg s
set s.is_dup = 'Y'
where s.id in ( select s2.id from stg s2 group by s2.id having count(1) > 1 )
4 rows updated.
--Check again - ids 1 and 4 should be marked as duplicates
select * from stg;
ID I
---------- -
1 Y
1 Y
2
3
4 Y
5
4 Y
7 rows selected.
-- Now insert
INSERT INTO tab ...
SELECT ....
FROM stg
WHERE is_dup IS NULL;
【讨论】:
id 列上的唯一性,上述答案给出了一般性指导。在我的回答中看到id 在哪里,您可以将其扩展到不止一列,因为逻辑将保持不变。