FORALL INSERT不插入行

时间:2016-11-30 15:07:05

标签: oracle stored-procedures plsql oracle11g

我有以下代码片段将行插入到t1表中,但是当我执行该过程时,在t1表中没有填充任何行。

CREATE OR REPLACE PROCEDURE my_proc
IS
   TYPE rt_t1 IS TABLE OF t1%ROWTYPE
                    INDEX BY BINARY_INTEGER;

   vrt_t1        rt_t1;

   TYPE t_emp_no_list IS TABLE OF t1.emp_no%TYPE
                            INDEX BY BINARY_INTEGER;

   TYPE t_emp_name_list IS TABLE OF t1.emp_name%TYPE
                              INDEX BY BINARY_INTEGER;

   TYPE t_loc_name_list IS TABLE OF t1.loc_name%TYPE
                              INDEX BY BINARY_INTEGER;

   TYPE t_hire_date_list IS TABLE OF t1.hire_date%TYPE
                               INDEX BY BINARY_INTEGER;


   l_emp_no      t_emp_no_list;
   l_emp_name    t_emp_name_list;
   l_loc_name    t_loc_name_list;
   l_hire_date   t_hire_date_list;
BEGIN
   SELECT empno,
          ename,
          loc,
          hiredate
     BULK COLLECT INTO l_emp_no,
          l_emp_name,
          l_loc_name,
          l_hire_date
     FROM (SELECT empno,
                  ename,
                  dept.loc,
                  emp.hiredate
             FROM emp JOIN dept ON emp.deptno = dept.deptno);

   FORALL i IN vrt_t1.FIRST .. vrt_t1.LAST
      INSERT INTO t1 (emp_no,
                      emp_name,
                      loc_name,
                      hire_date)
           VALUES (l_emp_no (i),
                   l_emp_name (i),
                   l_loc_name (i),
                   l_hire_date (i));


   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      RAISE;
END;

1 个答案:

答案 0 :(得分:2)

您应该使用游标来满足您的要求。见下文:

CREATE OR REPLACE PROCEDURE my_proc
IS
   TYPE rt_t1 IS TABLE OF t1%ROWTYPE
      INDEX BY BINARY_INTEGER;

   vrt_t1        rt_t1;   

   cursor cur is 
   SELECT empno,
                  ename,
                  dept.loc,
                  emp.hiredate
             FROM emp JOIN dept ON emp.deptno = dept.deptno;


BEGIN

   OPEN cur;
   fetch cur BULK COLLECT INTO vrt_t1;   
   close cur;

   FORALL i IN 1 .. vrt_t1.count
      INSERT INTO t1 
           VALUES vrt_t1(i);


   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      RAISE;
END;

PS:如果两个表的列数相同,上面的代码将起作用;

编辑 ..如果要向表中插入特定行,则需要创建一个RECORD来执行此操作。见下面的例子。你的代码失败了因为你试图一次性插入多个集合。在你的情况下,第一个colelction将是一个插入,其他应该是一个更新。

 CREATE TABLE t1
(
   emp_no      NUMBER,
   emp_name    VARCHAR2 (30),
   loc_name    VARCHAR2 (30),
   hire_date   DATE
);

--------------


SQL> select * from t1;

     no rows selected
CREATE OR REPLACE PROCEDURE my_proc
IS

   TYPE TBL IS RECORD
   (
     emp_no  number,
     emp_name varchar2(100),
     loc_name varchar2(100),
     hire_date date
   );

   TYPE t_emp IS TABLE OF TBL INDEX BY PLS_INTEGER;

   var_emp_det  t_emp; 


BEGIN
   SELECT ENO,
          ENAME,
          JOB,
          HIREDATE           
     BULK COLLECT INTO var_emp_det
   from emp_sal;  

   FORALL i IN 1..var_emp_det.count
      INSERT INTO t1 (emp_no,
                     emp_name,
                     loc_name,
                     hire_date)
         values  (var_emp_det(i).emp_no,
                  var_emp_det(i).emp_name,
                  var_emp_det(i).loc_name,
                  var_emp_det(i).hire_date);         

   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      RAISE;
END;

输出:

SQL> execute my_proc;

PL/SQL procedure successfully completed.

SQL> select * from t1;

    EMP_NO EMP_NAME                       LOC_NAME
---------- ------------------------------ ------------------------------
HIRE_DATE
---------
         2 Thomas                         IT
03-JAN-14