Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle PL/SQL—如何使用Oracle集合将大量数据从一个表复制到另一个表_Sql_Database_Oracle_Plsql - Fatal编程技术网

Oracle PL/SQL—如何使用Oracle集合将大量数据从一个表复制到另一个表

Oracle PL/SQL—如何使用Oracle集合将大量数据从一个表复制到另一个表,sql,database,oracle,plsql,Sql,Database,Oracle,Plsql,这是测试每个oracle集合(关联数组、变量数组和嵌套表)的处理速度的任务的一部分,但我不确定如何实现这一点——我对PL/SQL和oracle一般来说都是新手 所以我创建了两个表——一个包含三列,有300多万条记录,另一个是空的。如何使用collection方法将数据从填充表复制到空表 提前感谢-如果我没有提供足够的信息,请原谅-我对这一点相当陌生 理查德 /* package header */ CREATE OR REPLACE PACKAGE perfrormance_test AS

这是测试每个oracle集合(关联数组、变量数组和嵌套表)的处理速度的任务的一部分,但我不确定如何实现这一点——我对PL/SQL和oracle一般来说都是新手

所以我创建了两个表——一个包含三列,有300多万条记录,另一个是空的。如何使用collection方法将数据从填充表复制到空表

提前感谢-如果我没有提供足够的信息,请原谅-我对这一点相当陌生

理查德

/* package header */
CREATE OR REPLACE PACKAGE perfrormance_test AS

    PROCEDURE nested_table;
    PROCEDURE associative_array;

END perfrormance_test;


/* package body */
CREATE OR REPLACE PACKAGE BODY perfrormance_test AS

    PROCEDURE nested_table
    AS
        /* select all records from source table */
        CURSOR big_table_cur IS
            SELECT  col1
            ,       col2
            ,       col3
            FROM    big_table;

        /* create nested table type and variable that will hold BIG_TABLE's records */
        TYPE big_table_ntt IS TABLE OF big_table_cur%ROWTYPE;
        l_big_table  big_table_ntt;
    BEGIN
        /* open pointer to SELECT statement */
        OPEN  big_table_cur;
        /* collect data in the collection */
        FETCH big_table_cur BULK COLLECT INTO l_big_table;
        /* close the pointer */
        CLOSE big_table_cur;

        /* print size of the collection */
        DBMS_OUTPUT.PUT_LINE('Nested table holds: ' || TO_CHAR(l_big_table.COUNT) || ' records.');

        /* write data down to target table */
        FORALL indx IN l_big_table.FIRST..l_big_table.LAST
            INSERT  INTO big_table_target(col1, col2, col3)
            VALUES  (l_big_table(indx).col1, l_big_table(indx).col2, l_big_table(indx).col3);
        /*
        **  or you can use it this way:
        **
        **  VALUES  (l_big_table(indx));
        */

        /* print number of rows inserted */
        DBMS_OUTPUT.PUT_LINE('Number of rows inserted ' || SQL%ROWCOUNT || ' rows');

        /* save changes */
        COMMIT;

        /* or if you want undo changes  */
        /* ROLLBACK; */
    END nested_table;

    PROCEDURE associative_array
    AS
        /* create record (row) type */
        TYPE strings_rec IS RECORD
        (
            one   VARCHAR2(4000)
        ,   two   VARCHAR2(4000)
        ,   three VARCHAR2(4000)
        );

        /* create collection of records: type and variable */
        TYPE strings_aat IS TABLE OF strings_rec INDEX BY VARCHAR2(4000);
        l_strings  strings_aat;
    BEGIN
        /* populate collection with 3 000 000 rows */
        /* looping can take some time */
        FOR indx IN 1..3000000 LOOP
            l_strings('indx_' || TO_CHAR(indx)).one   := 'column one   indx ' || TO_CHAR(indx);
            l_strings('indx_' || TO_CHAR(indx)).two   := 'column two   indx ' || TO_CHAR(indx);
            l_strings('indx_' || TO_CHAR(indx)).three := 'column three indx ' || TO_CHAR(indx);
        END LOOP;

        /* print size of the collection */
        DBMS_OUTPUT.PUT_LINE('Assoc table holds: ' || TO_CHAR(l_strings.COUNT) || ' records.');

        /*
        ** CREATE TABLE aat_target
        ** (
        **     t_id  VARCHAR(4000)
        ** ,   one   VARCHAR(4000)
        ** ,   two   VARCHAR(4000)
        ** ,   three VARCHAR(4000)
        ** );
        */

        /* insert rows */
        FORALL indx IN l_strings.FIRST..l_strings.LAST
            INSERT  INTO aat_target(t_id, one, two, three)
            VALUES  (l_strings(indx), l_strings(indx).one, l_strings(indx).two, l_strings(indx).three);

        /* print number of rows inserted */
        DBMS_OUTPUT.PUT_LINE('Number of rows inserted ' || SQL%ROWCOUNT || ' rows');

        COMMIT;
    END associative_array;

END perfrormance_test;
从命令行运行SQL*PLUS:

sqlplus user/pass@db_name
类型:

它没有经过测试,所以你必须纠正小的打字错误


我不使用VARRAY。

欢迎来到stackoverflow。虽然你的问题目前过于宽泛,无法客观地回答(请看一看),但你应该从研究开始,一旦你进一步缩小了你的问题范围,我相信这个网站会更有用。为什么不使用
插入。。是否改为选择…
?这将比PL/SQL中的任何批量操作都要快得多。最好使用:创建表为select*from tableAs@a_horse_,名称为:
insert into。。选择…
是最快的方法。添加
append
提示和
nologging
子句,了解与可恢复性相关的问题。另外,在插入完成后,而不是在复制之前,向表中添加索引。使用集合意味着读取一批数据、上下文切换到plsql、再次写回等等。除非您需要进行一些重要的转换和日志记录,否则我认为您不想使用集合。请指出,虽然纯SQL解决方案的性能确实更高,但我认为OP正在尝试对三种类型的PL/SQL集合进行基准测试。非常感谢,我用每个方法创建了单独的过程,并使用了一个包含dbms_utility.get_time的匿名块来获取执行时间。再次感谢你,slk-你的上帝!Np问题。这是处理集合(大容量收集和大容量DML)的最快方法。其他有用的提示:从PL/SQL运行SQL是好的,但不能反过来运行。祝你好运
SQL> SET SERVEROUTPUT ON
SQL> SET TIMING ON
SQL> BEGIN
2    perfrormance_test.nested_table;
3    END;
-- exec time will be displayed here

SQL> BEGIN
2    perfrormance_test.associative_array;
3    END;
-- exec time will be displayed here