我有一个oracle程序,它调用了很少的其他程序。
PROCEDURE1
过程2
PROCEDURE3
..
现在发生的事情是PROCEDURE2
正在对后续程序3及之后使用的某些从属表执行DDL(EXECUTE IMMEDIATE 'DDL PROCESS'
)。这样可以正常运行,直到它PROCEDURE3
投掷ORA-06508 - Program / Unit being called not found
。
我们不能修改它不使用DDL,我们必须使用它们。我在DDL语句之后尝试重新编译,但它在ALTER PROCEDURE PROCEDURE3 RECOMPILE
或PROCEDURE1
中都不起作用(PROCEDURE2
)。
我怀疑PROCEDURE1
本身是无效的,并且编译在运行时会导致无限循环。我试过了,不行。
所以我需要使用一些技巧,可以在依赖对象上完成DDL后,在运行时再次使这些过程有效。
提前感谢参与回答的人。
答案 0 :(得分:2)
在这种情况下,与许多其他情况一样,最好是创建一个包而不是一堆独立的过程。包打破依赖链。这是一个例子:
SQL> create table tb_t(
2 col1 number
3 )
4 ;
Table created
独立程序
SQL> create or replace procedure Proc1
2 is
3 begin
4 execute immediate 'alter table tb_t add (col2 number)';
5 end;
6 /
创建了程序
SQL> create or replace procedure Proc2
2 is
3 l_var number;
4 begin
5 select count(*)
6 into l_var
7 from tb_t;
8 dbms_output.put_line(to_char(l_var));
9 end;
10 /
Procedure created
SQL> begin
2 proc1;
3 proc2;
4 end;
5 /
我们正在
ORA-06508: PL/SQL: could not find program unit being called
封装
SQL> create or replace package test_pkg
2 is
3 procedure proc1;
4 procedure proc2;
5 end;
6 /
Package created
SQL> create or replace package body test_pkg
2 is
3 procedure proc1
4 is
5 begin
6 execute immediate 'alter table tb_t add (col3 number)';
7 end;
8
9 procedure proc2
10 is
11 l_var number;
12 begin
13 select count(*)
14 into l_var
15 from tb_t;
16 dbms_output.put_line(to_char(l_var));
17 end;
18
19 end;
20 /
Package body created
SQL> begin
2 test_pkg.proc1;
3 test_pkg.proc2;
4 end;
5 /
0
PL/SQL procedure successfully completed
答案 1 :(得分:0)
alter procedure PX3 compile; -- not "recompile"
这可以按预期工作:
set serveroutput ON
create table X as select 42 A from DUAL;
create procedure PX3
as
a int;
begin
select max(A) into a from X;
dbms_output.put_line(a);
end;
/
create procedure PX2
as
begin
execute immediate 'alter table X add (B int)';
execute immediate 'alter procedure PX3 compile';
PX3;
end;
/
create procedure PX1
as
begin
PX2;
end;
/
begin
PX1;
end;
/
drop procedure PX1;
drop procedure PX2;
drop procedure PX3;
drop table X;
答案 2 :(得分:0)
如果我没弄错的话,与Oracle> = 10相比,Oracle 9对依赖和失效更为严格。
我在Oracle 9中有一些程序和/或程序包在他们依赖的表上执行DDL。 我得出的结论是,最实用的解决方案是让它们不依赖于这些表。 即而不是做静态SQL
select COL1 into my_var from MY_CHANGING_TABLE ...;
将其作为动态SQL
execute immediate 'select COL1 from MY_CHANGING_TABLE ...' into my_var;