【问题标题】:Oracle PL/SQL package compilation with interdependent procedure具有相互依赖过程的 Oracle PL/SQL 包编译
【发布时间】:2015-02-10 16:33:54
【问题描述】:

如果我有过程 Proc1 和另一个过程 Proc2 ,其中 proc1 依赖于 proc2 而 proc2 依赖于 proc1 。我需要用这两个程序编译包 pkg1。

Oracile 9i。 我怎样才能实现它?需要任何特定的关键字吗?

【问题讨论】:

  • 你需要把功能分离出来,这样对象就没有这种循环依赖了。
  • 我需要有相互依赖的程序。我希望我可以像艾伦评论的那样编译,但想检查我是否需要使用任何其他命令/关键字
  • 从技术上讲,您应该能够按照 Allan 的建议进行编译,可以在各个级别执行此操作(例如,编译架构对象),但是这种设计对于一些基于依赖的脚本会造成混淆.
  • 如果两者都包含在包规范中,你应该没问题。如果不是,我认为您可以包含一个虚拟定义,例如PROCEDURE PROC2(SOME_ARG NUMBER); 位于包体顶部,以便PROC1 可以看到 PROC2 的定义(假设 PROC1 出现在包体的第一个位置)。祝你好运。

标签: oracle plsql compilation package procedure


【解决方案1】:

如果这两个过程都在规范中,只需编译包即可:

alter package your_package compile;

当然,这假设您的包是有效的。

如果规范中没有一个(或两个)过程,最好将其列为包体开头的前向声明。

【讨论】:

    【解决方案2】:

    我认为这些都是私有过程,也就是说,它们都没有出现在包规范中。

    如果这两个过程都出现在规范中就没有问题,因为主体是根据公共声明编译的。

    同样,如果一个过程出现在规范中,那么再次没有问题:只需将私有过程写在公共过程之前的主体中。

    但是如果两个过程都是私有的,那么你需要使用前向声明。这仅仅意味着在包的顶部声明过程的签名。就像把它们放在规范中一样,只是私有的。这是一个规范...

    create or replace package pkg as
        procedure main (n0 in out number);
    end;
    /
    

    ...和身体...

    create or replace package body pkg as
        -- forward declarations
        procedure p1 (n1 in out number);
        procedure p2 (n2 in out number);
    
        -- actual declarations    
        procedure p1 (n1 in out number)
        is
        begin
            dbms_output.put_line('P1='||n1);
            if n1 < 3 then
                p2(n1);
            end if;
        end p1;
        procedure p2 (n2 in out number)
        is
        begin
            dbms_output.put_line('P2='||n2);
            n2 := n2+1;
            if n2 < 3 then
                p1(n2);
            end if;
        end p2;
    
        procedure main (n0 in out number)
        is
        begin
            if n0 < 0 then 
                p1(n0);
            else
                p2(n0);
            end if;
        end main;
    
    end pkg;
    /
    

    “我需要有相互依赖的程序”

    你真的应该想办法避免循环依赖。这是一种非常糟糕的编程习惯。很难理解这些过程是如何相互关联的,我们必须管理递归并确保两个过程最终肯定会退出而不调用另一个。请记住,这不仅仅是您遇到的问题:它是您将传递给代码的未来维护者的遗产。

    【讨论】:

      【解决方案3】:

      您可以通过使用包并在编译包主体之前编译所有包规范来打破依赖链。规范将全部编译而不考虑依赖关系,然后在编译主体时,它们可以按任何顺序进行,因为它们将引用已经编译的规范。通常,您将存储带有 *.pks 后缀的包规范和带有 *.pkb 后缀的主体以及某种编译它们的构建脚本。像这样

      /* Master Package Build Script */
      
      -- Specs
      @package_a.pks
      @package_b.pks
      @package_c.pks
      
      -- Bodies
      @package_a.pkb
      @package_b.pkb
      @package_c.pkb
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-23
        • 1970-01-01
        • 1970-01-01
        • 2014-03-08
        • 1970-01-01
        • 2021-09-29
        相关资源
        最近更新 更多