[英]How to write procedure to copy data from one table to another table
Hello I have this situation你好我有这种情况
I have a table with 400 millions of records I want to migrate some data to another table for get better performance.我有一个包含 4 亿条记录的表我想将一些数据迁移到另一个表以获得更好的性能。
I know that the process could be slow and heavy and I want to execute something like this我知道这个过程可能会很慢很重,我想执行这样的事情
INSERT INTO TABLLE_2 SELECT NAME,TAX_ID,PROD_CODE FROM TABLE_1;
But I want this in a procedure that iterates the table from 50000 to 50000 records.但我希望在一个将表从 50000 条记录迭代到 50000 条记录的过程中执行此操作。
I saw this but it DELETE the rows and the target is SQLServer and not Oracle我看到了这个但是它删除了行并且目标是 SQLServer 而不是 Oracle
WHILE 1 = 1
BEGIN
DELETE TOP (50000) FROM DBO.VENTAS
OUTPUT
Deleted.AccountNumber,
Deleted.BillToAddressID,
Deleted.CustomerID,
Deleted.OrderDate,
Deleted.SalesOrderNumber,
Deleted.TotalDue
INTO DATOS_HISTORY.dbo.VENTAS
WHERE OrderDate >= '20130101'
and OrderDate < '20140101'
IF @@ROWCOUNT = 0 BREAK;
END;
If it's just for a one-time migration, don't paginate/iterate at all.如果只是为了一次性迁移,根本不要分页/迭代。 Just use a pdml append insert-select:
只需使用 pdml append 插入选择:
BEGIN
EXECUTE IMMEDIATE 'alter session enable parallel dml';
INSERT /*+ parallel(8) nologging append */ INTO table_2
SELECT name,tax_id,prod_code from table_1;
COMMIT;
EXECUTE IMMEDIATE 'alter session disable parallel dml';
END;
Or if the table doesn't yet exist, CTAS it to be even simpler:或者,如果该表尚不存在,CTAS 会更简单:
CREATE OR REPLACE TABLE table_2 PARALLEL (DEGREE 8) NOLOGGING AS
SELECT name,tax_id,prod_code FROM table_1;
If you absolutely must iterate due to other business needs you didn't mention, you can use PL/SQL for that as well:如果由于您未提及的其他业务需求而绝对必须迭代,您也可以使用 PL/SQL:
DECLARE
CURSOR cur_test
IS
SELECT name,tax_id,prod_code
FROM table_1;
TYPE test_tabtype IS TABLE OF cur_test%ROWTYPE;
tab_test test_tabtype;
var_limit integer := 50000;
BEGIN
OPEN cur_test;
FETCH cur_test BULK COLLECT INTO tab_test LIMIT var_limit;
LOOP
-- do whatever else you need to do
FORALL i IN tab_test.FIRST .. tab_test.LAST
INSERT INTO table_2
(name,tax_id,prod_code)
VALUES (tab_test(i).name, tab_test(i).tax_id, tab_test(i).prod_code);
COMMIT;
EXIT WHEN tab_test.COUNT < var_limit;
FETCH cur_test BULK COLLECT INTO tab_test LIMIT var_limit;
END LOOP;
CLOSE cur_test;
END;
That won't be nearly as fast, though.不过,那不会那么快。 If you need even faster, you can create a SQL object and nested table type instead of the PL/SQL types you see here and then you can do a normal INSERT /*+ APPEND */ SELECT... statement that will use direct path.
如果您需要更快,您可以创建一个 SQL object 和嵌套表类型,而不是您在此处看到的 PL/SQL 类型,然后您可以执行正常的 INSERT /*+ APPEND */ SELECT... 将使用直接路径的语句. But honestly, I doubt you really need iteration at all..
但老实说,我怀疑你是否真的需要迭代......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.