FORALL 插入目标表,然后从源表中删除 FORALL
Posted
技术标签:
【中文标题】FORALL 插入目标表,然后从源表中删除 FORALL【英文标题】:FORALL insert destination table then a FORALL delete from source table 【发布时间】:2017-02-02 19:04:15 【问题描述】:Cam 以下是否可以顺利完成?只要将记录插入目标表,您就可以从源表中删除该记录。显然,这条记录在循环中的内存中,你能看到这有什么问题吗?或者可以用不同的方式完成。
我知道你们所有人都会说只需使用 APPEND 进行直接 SQL 插入,然后截断源表。
我只是好奇地把问题抛在那里。
PROCEDURE copy_records_back IS
TYPE t_act_plus_triggers_copy1 IS TABLE OF act_plus_triggers_copy1%ROWTYPE; v_act_plus_triggers_copy1 t_act_plus_triggers_copy1;
CURSOR c_act_plus_triggers_copy1 IS SELECT * FROM act_plus_triggers_copy;
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE act_plus_triggers1';
OPEN c_act_plus_triggers_copy1; LOOP
FETCH c_act_plus_triggers_copy1 BULK COLLECT INTO v_act_plus_triggers_copy LIMIT 10000;
FORALL i IN 1..v_act_plus_triggers_copy.COUNT
INSERT /*+ APPEND_VALUES */ INTO act_plus_triggers1 values v_act_plus_triggers_copy(i);
FORALL i IN 1..v_act_plus_triggers_copy.COUNT
DELETE FROM act_plus_triggers_copy
where surr_id = v_act_plus_triggers_copy(i).surr_id
COMMIT;
EXIT WHEN c_act_plus_triggers_copy1%NOTFOUND;
END LOOP;
CLOSE c_act_plus_triggers_copy1;
END copy_records_back;
【问题讨论】:
是的,这很有可能。当普通的 INSERT-SELECT 不是一个选项时,这与我在某些数据加载中使用的基本相同的“模式”。 【参考方案1】:如果两个表具有相同的列,则有一种更简单的方法可以做到这一点,而无需复制数据。您可以创建一个分区表,其中包含与两个表相同的列并且只有一个分区。然后你可以使用ALTER TABLE EXCHANGE PARTITION
将表与分区交换,然后你可以用相同的方式将分区与目标表交换(如果其中一张表是分区的,你只需要做一次交换)。如果数据需要改变表空间(或者其他一些物理属性),可以在最后发出ALTER TABLE MOVE
来完成这个任务。
在您的情况下,交换两个表的语句如下所示:
-- initialization (do only once)
CREATE TABLE temp_part_table PARTITION BY HASH (surr_id) (PARTITION single) AS
SELECT * FROM act_plus_triggers_copy WHERE 1=0
/
-- swapping act_plus_triggers_copy with act_plus_triggers1
ALTER TABLE temp_part_table EXCHANGE PARTITION single WITH TABLE act_plus_triggers1
WITHOUT VALIDATION
/
ALTER TABLE temp_part_table EXCHANGE PARTITION single WITH TABLE act_plus_triggers_copy
WITHOUT VALIDATION
/
ALTER TABLE temp_part_table EXCHANGE PARTITION single WITH TABLE act_plus_triggers1
WITHOUT VALIDATION
/
如果您想交换两个表,则有三个交换。如果你知道temp_part_table
(临时分区表)和act_plus_triggers1
(目标表)最初都是空的,你可以跳过第一个ALTER
。
【讨论】:
嗨@mik 有这样做的例子吗?这些表确实有相同的列,但我不确定如何在上面的这个场景中使用分区,但在性能方面它确实听起来更快。任何人都可以帮助我确定这样做的方向吗?? @ShaunKinnair,我在答案中添加了一个示例。以上是关于FORALL 插入目标表,然后从源表中删除 FORALL的主要内容,如果未能解决你的问题,请参考以下文章