我卡在下面并得到语法错误 - 请帮忙。基本上,我使用集合来存储几个部门 ID,然后想将这些部门 ID 用作过滤条件,同时将数据插入 FORALL 语句中的 emp 表中。
下面是示例代码:在编译此代码时出现错误,我的要求是使用插入表从表中选择 *,无法避免,所以请提出建议。
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;
你为什么要费心使用游标、数组等?为什么你不能做一个简单的插入作为选择?
上面列出的程序问题:
-
您不会像
Procedure abc ()
那样声明过程 - 对于独立过程,您将执行create or replace procedure abc as
,或者在包中执行:procedure abc is
-
您引用了一个名为"dblink"的变量,该变量未在任何地方声明。
-
你没有把
end abc;
放在程序结束时(我希望这只是一个错误的c&p?)
您 实际上是在以选择方式执行简单的插入操作,但是您使它过于复杂,而且您使代码的性能降低。
您尚未列出要插入的列名;如果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;
/
这段代码似乎有很多问题。1)为什么立即执行?对此有什么明确的要求吗?不,而不是不使用它2) dblink 变量在哪里声明?3)正如Boneist已经说过的,为什么不在插入语句中一个简单的子选择呢?插入到stg_emp选择 部门,"DEPT_10"从dept_emp@dblink哪里 dept_id(从部门选择dept_ids);
首先,它将使代码实际上可读;)