0

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

以下是示例代码:在编译此代码时出现错误,我的要求是使用 INSERT INTO table 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;
4

2 回答 2

5

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

上面列出的程序问题:

  1. 您不会像这样声明过程Procedure abc ()- 对于独立过程,您会这样做create or replace procedure abc as,或者在包中:procedure abc is

  2. 您引用了一个未在任何地方声明的名为“dblink”的变量。

  3. 你没有把end abc;你的程序结束(我希望那只是一个错误的c&p?)

  4. 您实际上是在做一个简单的插入作为选择,但是您过于复杂了,而且您正在降低代码的性能。

  5. 您还没有列出要插入的列名;如果 stg_emp 有两个以上的列或最终添加了列,则您的代码将失败。


假设您的 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;
/
于 2015-01-27T12:32:48.767 回答
1

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

一方面,它会使代码真正可读;)

于 2015-01-27T14:29:54.167 回答