create or replace procedure p1(p_deptno in number)
is
type t is table of emp%rowtype
index by binary_integer;
v_emp t;
begin
execute immediate 'create table test as select * from emp where ename is null';
select * bulk collect into v_emp from emp where deptno=p_deptno;
for i in v_emp.first..v_emp.last
loop
insert into test(empno, ename, job, mgr, hiredate, sal, comm, deptno) values (v_emp(i).empno, v_emp(i).ename, v_emp(i).job, v_emp(i).mgr, v_emp(i).hiredate, v_emp(i).sal, v_emp(i).comm, v_emp(i).deptno);
end loop;
exception
when value_error then
dbms_output.put_line('Give proper deptno');
end p1;
/
我收到此错误:
PL / SQL:忽略SQL语句
PL / SQL:ORA-00942:表或视图不存在
答案 0 :(得分:2)
如果您在运行时创建表,则必须使用动态SQL来执行插入。另一个问题是,您将该数据吸入内存表,然后逐个执行插入。我建议像:
create or replace procedure p1(p_deptno in number) is
type t is table of emp%rowtype
index by binary_integer;
v_emp t;
begin
execute immediate 'create table test as select * from emp where ename is null';
execute immediate
'insert into test
select *
from emp
where deptno = :1' USING p_deptno;
exception
when value_error then
dbms_output.put_line('Give proper deptno');
end p1;
您仍然可以使用动态SQL逐个进行插入,但这似乎是浪费时间和精力。
祝你好运。
答案 1 :(得分:0)
在Oracle中创建存储过程时,在编译时会事先检查该存储过程中的所有引用对象(在您的案例表" test"和#34; emp")中是否有适当的授权/引用对象的所有权。作为对象"测试"在编译时不存在,自然没有存储过程的所有者的任何适当的授予/所有权,并且您得到您指定的错误。为了解决这种情况,你可以将insert语句放在" EXECUTE IMMEDIATE"就像@Bob Jarvis所说的那样,这种方式检查不会在编译时发生,但是在运行时检查会成功,因为对象是在运行时创建的,并且与适当的授权/所有权一起存在。
execute immediate 'insert into test select * from emp where deptno = '|| p_deptno;