下面的可以没有问题的完成吗?其中,只要将记录插入到目标表中,就可以从源表中删除该记录。很明显,这条记录在循环中的内存中,你能看到它有什么问题吗,或者可以用不同的方式来做。
我知道你们所有人都会说,只需使用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;发布于 2017-02-03 06:32:39
如果两个表具有相同的列,则有一种更简单的方法可以在根本不复制数据的情况下完成此操作。您可以创建一个分区表,其列与这两个表相同,并且只有一个分区。然后,您可以使用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。
https://stackoverflow.com/questions/42010316
复制相似问题