问题
I have a huge table that I need to transfer into a new table, my resources do not allow me to that and I need to do that by chunking of data like this:
DECLARE
TYPE prod_tab IS TABLE OF dba_tab_partitions%ROWTYPE;
products_tab prod_tab := prod_tab();
start_time number; end_time number;
BEGIN
SELECT * BULK COLLECT INTO products_tab FROM dba_tab_partitions WHERE table_name = 'TBLX'
EXECUTE IMMEDIATE 'TRUNCATE TABLE dba_tab_partitions2';
EXECUTE IMMEDIATE 'TRUNCATE TABLE tbl2';
FOR i in products_tab.first .. products_tab.last LOOP
EXECUTE IMMEDIATE 'ALTER SESSION FORCE PARALLEL DML PARALLEL 24';
INSERT /* PARALLEL(24) NOLOGGING */ INTO tbla2 NOLOGGING
(
"ID", datetime, ...)
SELECT /* PARALLEL(24) NOLOGGING */ * FROM tbl1 PARTITION(products_tab(i).partition_name);
COMMIT;
END LOOP;
COMMIT;
END;
Could anybody help me to correct it?
回答1:
As already stated in my comments I think PARALLEL does not make any sense (but I am not sure about that) and running each partition one by one is also useless when you copy entire table.
Anyway, your code should work when you write it like this:
FOR i in products_tab.first .. products_tab.last LOOP
EXECUTE IMMEDIATE 'ALTER SESSION FORCE PARALLEL DML PARALLEL 24';
EXECUTE IMMEDIATE 'INSERT /*+ APPEND PARALLEL(24) */ INTO tbla2
("ID", datetime, ...)
SELECT *
FROM tbl1 PARTITION ('||products_tab(i).partition_name||)';
COMMIT;
END LOOP;
I don't know your requirements but maybe Exchanging Partitions and Subpartitions could be an option for you.
来源:https://stackoverflow.com/questions/46959197/how-to-use-partition-name-as-a-parameter-in-the-select-statement