Oracle PL/SQL:如何在没有for循环的情况下将表类型中的所有记录插入到另一个表中

Oracle PL/SQL:如何在没有for循环的情况下将表类型中的所有记录插入到另一个表中,oracle,plsql,collections,Oracle,Plsql,Collections,我可能有一个很小的问题,但我不能完全正确地理解逻辑 我有以下几种: create or replace TYPE test_rec FORCE AS OBJECT (ref_id NUMBER (20) ,ref_type VARCHAR2 (4)); 和实际表格 CREATE TABLE my_tbl ( id number(10) NOT NULL, ref_id varchar2(20) NOT NULL, ref_type varchar2(4)

我可能有一个很小的问题,但我不能完全正确地理解逻辑

我有以下几种:

create or replace TYPE test_rec FORCE
   AS OBJECT (ref_id NUMBER (20)
             ,ref_type VARCHAR2 (4));
和实际表格

CREATE TABLE my_tbl
( id number(10) NOT NULL,
  ref_id varchar2(20) NOT NULL,
  ref_type varchar2(4),
  CONSTRAINT my_pk PRIMARY KEY (id)
);
现在,在一个过程中,我得到了带有数据的变量
test\u ref\u tbl
,我必须将所有内容插入
my\u tbl
,id也应该从序列中生成

我用for循环很容易做到这一点

FOR i IN 1 .. test_ref_tbl.COUNT LOOP
  INSERT INTO my_tbl(id
                    ,ref_id
                    ,ref_type)
  VALUES (my_test_sequence.NEXTVAL
         ,test_ref_tbl(i).ref_id
         ,test_ref_tbl(i).ref_type
);
END LOOP;
一切都很好,但我在for循环中插入数据时受到了很多抨击,我不是plsql开发人员,所以我的同事们可能只是为了让我的工作更难

但要回到主题上来,有没有一种不用for循环就能做到这一点的方法


谢谢

是的,有。下面是一个例子:

首先创建测试用例:

SQL> CREATE OR REPLACE TYPE test_rec FORCE AS OBJECT
  2  (
  3     ref_id NUMBER (20),
  4     ref_type VARCHAR2 (4)
  5  );
  6  /

Type created.

SQL> CREATE OR REPLACE TYPE test_ref_tbl FORCE AS TABLE OF test_rec;
  2  /

Type created.

SQL> CREATE TABLE my_tbl
  2  (
  3     id         NUMBER (10) NOT NULL,
  4     ref_id     VARCHAR2 (20) NOT NULL,
  5     ref_type   VARCHAR2 (4),
  6     CONSTRAINT my_pk PRIMARY KEY (id)
  7  );

Table created.

SQL> CREATE SEQUENCE my_test_sequence;

Sequence created.
作为数据源,我使用Scott的
DEPT

SQL> DECLARE
  2     l_tab  test_ref_tbl;
  3  BEGIN
  4     SELECT test_rec (deptno, SUBSTR (dname, 1, 4))
  5       BULK COLLECT INTO l_tab
  6       FROM dept;
  7
  8     -- this is what you're looking for
  9     INSERT INTO my_tbl (id, ref_id, ref_type)
 10        SELECT my_test_sequence.NEXTVAL, t.*
 11          FROM TABLE (l_tab) t;
 12  END;
 13  /

PL/SQL procedure successfully completed.

SQL> SELECT * FROM my_tbl;

        ID REF_ID               REF_
---------- -------------------- ----
         1 10                   ACCO
         2 20                   RESE
         3 30                   SALE
         4 40                   OPER

SQL>
SQL> DECLARE
  2     l_tab  test_ref_tbl;
  3  BEGIN
  4     SELECT test_rec (deptno, SUBSTR (dname, 1, 4))
  5       BULK COLLECT INTO l_tab
  6       FROM dept;
  7
  8     -- this is what you're looking for
  9     INSERT INTO my_tbl (id, ref_id, ref_type)
 10        SELECT my_test_sequence.NEXTVAL, t.*
 11          FROM TABLE (l_tab) t;
 12  END;
 13  /

PL/SQL procedure successfully completed.

SQL> SELECT * FROM my_tbl;

        ID REF_ID               REF_
---------- -------------------- ----
         1 10                   ACCO
         2 20                   RESE
         3 30                   SALE
         4 40                   OPER

SQL>