2

我有一个 oracle 程序,它调用了一些其他程序。

程序
1 程序 2
程序 3
..

现在发生的是在后续过程 3 及以后的过程中使用的一些从属表上PROCEDURE2执行 DDL ( )。EXECUTE IMMEDIATE 'DDL PROCESS'这运行良好,直到它击中PROCEDURE3它抛出的地方ORA-06508 - Program / Unit being called not found

我们不能修改它以不使用 DDL,我们必须使用它们。我曾尝试在 DDL 语句之后重新编译,但它不起作用(ALTER PROCEDURE PROCEDURE3 RECOMPILE)无论是 inPROCEDURE1还是 in PROCEDURE2.

我怀疑它PROCEDURE1本身变得无效并且在运行时编译它会导致无限循环。我试过了,不行。

所以我需要使用一些技巧,在对依赖对象完成 DDL 之后,使这些过程在运行时再次有效。

提前感谢参与回答的人。

4

3 回答 3

2

在这种情况下,与许多其他情况一样,创建一个包而不是一堆独立的程序会更好。包打破依赖链。这是一个例子:

    SQL> create table tb_t(
     2    col1 number
     3  )
     4  ;

    Table created
  1. 独立程序

    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
  1. 包裹

    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
    
于 2012-12-06T08:56:45.087 回答
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;
于 2012-12-06T08:49:44.240 回答
0

如果我没记错的话,与 Oracle >=10 相比,Oracle 9 在依赖和失效方面更加严格。

我在 Oracle 9 中遇到过一些在它们所依赖的表上执行 DDL 的过程和/或包的案例。我得出的结论是,最实用的解决方案是让它们依赖于这些表。ie而不是做静态SQL

select COL1 into my_var from MY_CHANGING_TABLE ...;

将其作为动态 SQL

execute immediate 'select COL1 from MY_CHANGING_TABLE ...' into my_var;
于 2012-12-06T12:06:00.693 回答