FORALL EXECUTE IMMEDIATE + INSERT进入表SELECT

时间:2015-01-27 12:09:44

标签: oracle forall

我被困在下面并且语法错误 - 请帮助。 基本上我使用一个集合来存储几个部门ID,然后想要在FORALL语句中将数据插入到emp表中时使用这些部门ID作为过滤条件。

以下是示例代码: 虽然编译这段代码我得到错误,我的要求是使用INSERT INTO表select * from table并且无法避免它所以请建议。

create or replace Procedure abc(dblink VARCHAR2)
 CURSOR dept_id is select dept_ids from dept;
 TYPE nt_dept_detail IS TABLE OF VARCHAR2(25);
 l_dept_array nt_dept_detail;
Begin
 OPEN dept_id;
 FETCH dept_id BULK COLLECT INTO l_dept_array;
 IF l_dept_array.COUNT() > 0 THEN

    FORALL i IN 1..l_dept_array.COUNT SAVE EXCEPTIONS
      EXECUTE IMMEDIATE 'INSERT INTO stg_emp SELECT
      Dept,''DEPT_10'' FROM dept_emp'||dblink||' WHERE
      dept_id = '||l_dept_array(i)||'';      
      COMMIT;
 END IF;
 CLOSE dept_id;
 end abc;

2 个答案:

答案 0 :(得分:5)

为什么你首先要打扰使用游标,数组等?为什么你不能做一个简单的插入作为选择?

上面列出的程序问题:

  1. 您没有声明Procedure abc ()等程序 - 对于独立程序,您可以create or replace procedure abc as或在包裹中procedure abc is

    < / LI>
  2. 您引用一个名为&#34; dblink&#34;的变量。没有在任何地方宣布。

  3. 你没有在你的程序结束时放end abc;(我希望这只是一个错误的&amp; p?)

  4. 您实际上只是选择了一个简单的插入内容,但是你过度复杂了,加上你的代码性能降低了。

  5. 您尚未列出您尝试插入的列名;如果stg_emp有两列以上或者最后添加了列,那么代码就会失败。


  6. 假设你的dblink名称直到运行时才知道,那么这就是你可以做的事情:

    create Procedure abc (dblink in varchar2)
    is
    begin
      execute immediate 'insert into stg_emp select dept, ''DEPT_10'' from dept_emp@'||dblink||
                        ' where  dept_id in (select dept_ids from dept)';
      commit;
    end abc;
    /
    

    但是,如果您确实知道dblink名称,那么您只需要立即删除执行并执行:

    create Procedure abc (dblink in varchar2)
    is
    begin
      insert into stg_emp -- best to list the column names you're inserting into here
      select dept, 'DEPT_10'
      from dept_emp@dblink
      where  dept_id in (select dept_ids from dept);
      commit;
    end abc;
    /
    

答案 1 :(得分:1)

这段代码似乎有很多问题。 1)为什么执行立即?对此有明确要求吗?不,不要使用它 2)dblink变量在哪里声明? 3)正如Boneist已经说过的那样,为什么插入语句中没有简单的子选择? INSERT INTO stg_emp SELECT       部,&#39; DEPT_10&#39; FROM dept_emp @ dblink WHERE       dept_id in(从dept中选择dept_ids);

首先,它会使代码实际可读;)