【问题标题】:FORALL INSERT Not Inserting RowsFORALL INSERT 不插入行
【发布时间】:2017-04-14 23:21:54
【问题描述】:

我有以下代码 sn-p 将行插入到 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;

【问题讨论】:

  • 您在迭代 vrt_t1 时将批量收集到 l_emp_no。不好。
  • 正如你所说,你没有填充目标表的所有列..当你使用vrt_t1..它继承了表 t1 的所有列。在插入时它会失败
  • 检查我的编辑..它的工作和测试。

标签: oracle stored-procedures plsql oracle11g


【解决方案1】:

您应该使用光标来实现您的要求。见下文:

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:如果两个表的列数相同,上述代码将起作用;

编辑..如果您将特定行插入到表中,那么您需要创建一个记录来执行此操作。请参见下面的示例。您的代码失败,因为您试图一次插入多个集合。在您的情况下,第一个集合将是插入,而其他集合应该是更新。

 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

【讨论】:

  • 没有游标可以吗?
  • 当你有更好的方法时,你为什么要这样做。
  • 我创建变量的原因是我要插入的列,这意味着表中的所有列都不会被填充。
  • 你能把你的代码贴在有错误的问题中吗\
  • PLSQL 与 SQL 不同。当您编写 PLSQL 块 2 引擎播放。 1 个 SQL 和另一个 PLSQL。这 2 条记录之间存在上下文切换,因此 5 分钟对于这么多记录来说似乎没问题
猜你喜欢
  • 2017-12-24
  • 2018-11-13
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2014-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多