【问题标题】:compiling invalid oracle procedures编译无效的 oracle 程序
【发布时间】:2012-09-06 17:07:52
【问题描述】:

我有一个包装程序(proc_main),它在其中调用一些程序。

create or replace Procedure proc_main
as
begin

proc_child1;

proc_child2;

proc_child3;

proc_compile_invalids; -- This invokes "alter procedure <procedure_name> compile" statement for all the invalids.

end;
/

proc_child 过程应用一些处理逻辑,其中涉及一些步骤来重命名其中的表。

这会使程序无效,这就是我让 proc_compile_invalids 程序再次将它们设置为有效状态的原因。

我的问题是:当我执行 proc_main 过程时,它使主过程以及内部子过程无效。 因此,当最后一步调用 proc_compile_invalids 时,它会挂起,因为它试图重新编译主调用过程。

显然,如果我删除最后一步并单独执行它,这不是问题。

我知道我可以通过注释编译过程并将其作为独立的执行来将它们分离为 2 个不同的调用。 而且我也知道这是一个装饰步骤,因为 oracle 会在下次执行之前尝试编译一个过程。所以,不管怎样,无效者变得有效。 但是,当天执行结束时,他们都处于无效状态,我被权力质疑是否可以避免!

所以,我只是想知道我是否可以避免分离调用并仍然将其保留为主过程的最后一步。

非常感谢任何想法/指针。

【问题讨论】:

  • 最好一开始就避免重命名表。

标签: oracle plsql oracle11g


【解决方案1】:

Oracle 11g 以后

您可以在主过程中使用dbms_utility包的compile_schema过程而不是proc_compile_ivalids来重新编译指定架构中的所有无效过程、函数、包和触发器

create or replace Procedure proc_main
as
begin
  Proc_child1;
  proc_child2;
  proc_child3;
  dbms_utility.compile_schema(schema, false);
end;

【讨论】:

  • 如果 dbms_utility.compile_schema 在运行时尝试编译 proc_main 会挂起,不是吗?
  • 不,它不会挂起。因为要让 proc_main 运行,它必须已经编译且没有错误。 comile_schema 的第二个参数设置为 false,这意味着我们将只考虑无效对象而不是有效对象。并且 Proc_main 必须有效才能开始重新编译过程。
  • proc_child 过程之一将使proc_main 无效。 dbms_utility.compile_schema 将尝试重新编译 proc_main,这将挂起,因为该过程仍在运行,至少在 9iR2 上。但是,该行为似乎在以后的版本中发生了变化:在 11gR2 中,compile_schema 过程不会重新编译proc_main,因此不会挂起。 proc_main 过程将失效。
  • 是的文森特,我默认 RDBMS 的版本是 11g 以后的版本,这是分歧的问题。
  • 看到版本之间的微小变化总是很有趣 :) 我赞成你的回答,但它仍然没有真正回答 OP 的问题,即其程序最终无效。
【解决方案2】:

你可以使用dynamic SQL来打破依赖:

CREATE OR REPLACE PROCEDURE proc_main AS
BEGIN

   EXECUTE IMMEDIATE 'BEGIN proc_child1; END;';

   EXECUTE IMMEDIATE 'BEGIN proc_child2; END;';

   EXECUTE IMMEDIATE 'BEGIN proc_child3; END;';

   proc_compile_invalids;  -- This invokes 
                           -- "alter procedure <procedure_name> compile" 
                           -- statement for all the invalids.

END;

【讨论】:

  • OP:我的问题是:当我执行 proc_main 过程时,它使主过程以及内部子过程无效。 - 这个解决方案如何避免调用过程的失效?
  • proc_main 过程如果像这样编码不会失效,因为它不依赖于修改的对象。
  • 谢谢!它进行了细微的调整。您的帖子中缺少“END”末尾的分号 (;)。它应该是 EXECUTE IMMEDIATE 'BEGIN proc_child3;结尾;';但是,谢谢你的回答。
猜你喜欢
  • 1970-01-01
  • 2020-01-30
  • 1970-01-01
  • 1970-01-01
  • 2017-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多