2

他のプロシージャをほとんど呼び出さない Oracle プロシージャがあります。

手順
1 手順2
手順3
..

ここで、後続の手順 3 以降で使用されるいくつかの従属テーブルに対してPROCEDURE2DDL ( ) を実行しています。EXECUTE IMMEDIATE 'DDL PROCESS'これはPROCEDURE3、投げたところに当たるまで問題なく動作しORA-06508 - Program / Unit being called not foundます。

DDL を使用しないように変更することはできません。使用する必要があります。DDL ステートメントの後で再コンパイルを試みましたが、動作しません ( ALTER PROCEDURE PROCEDURE3 RECOMPILE) どちらPROCEDURE1でもPROCEDURE2.

PROCEDURE1それ自体が無効になり、実行時にコンパイルすると無限ループが発生するのではないかと思います。私は試しましたが、動作しません。

したがって、依存オブジェクトに対して DDL が実行された後、実行時にこれらのプロシージャを再度有効にするためのトリックを使用する必要があります。

参加してくださった方、回答ありがとうございます。

4

3 に答える 3

2

In this case, as in many other cases, would be better to create a package instead of a bunch of stand-alone procedures. Packages break dependency chain. Here is an example:

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

    Table created
  1. Stand-alone procedures

    SQL> create or replace procedure Proc1
      2  is
      3  begin
      4    execute immediate 'alter table tb_t add (col2 number)';
      5  end;
      6  /
    

    Procedure created

    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  /
    

and we are getting

     ORA-06508: PL/SQL: could not find program unit being called
  1. Package

    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 9 は Oracle >=10 に比べて依存性と無効化に関してより厳密です。

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;
于 2012-12-06T12:06:00.693 に答える