【问题标题】:PLSQL cycle formed in methodsPLSQL循环在方法中形成
【发布时间】:2020-07-28 01:39:47
【问题描述】:

在一个包中,我有一些程序调用其他程序并形成循环并得到“PLS-00313: 'Checklist' not declared in this scope”错误。

Checklist procedure -> Task method.
Task method -> Step Checklist method.
Step Checklist method -> Checklist method.

如何解决这个问题? plsql有类似c++原型的东西吗?

【问题讨论】:

  • 我不知道原型。您是否将所有这些程序都放入了包装规范中?如果没有,请执行此操作并重试。
  • 为什么要在"procedure""method"之间切换?术语的不一致是否与架构相关?

标签: oracle stored-procedures plsql


【解决方案1】:

有两种方法可以解决这个问题。

第一种方法是通过在包规范中包含checklist() 来“修复”范围错误(使其公开,因此可以被正文中定义的任何过程引用)或使用前向声明来定义过程包体的顶部(允许后续过程引用它们,而不管过程的编写顺序如何)。 These are the solutions given by @hotfix

但是,这种方法存在一个问题:您的代码执行这样的递归循环

Checklist -> Task -> Step Checklist -> Checklist

因此,您必须在checklist()step checklist() 中编写一些代码,这会打破循环并展开代码。需要这样做是一个危险信号,表明您的设计存在问题。

因此,第二种方法是退后一步,考虑是否有另一种方法可以在没有循环依赖的情况下实现您的业务逻辑。循环依赖在软件架构中是一件坏事,应尽可能避免。通常的解决方案是隔离公共依赖项——在这种情况下,checklist()step checklist() 都需要执行的操作——并将其提取到一个新的子例程中。然后更改两个过程以调用新过程。

这可能容易实现,也可能难以实现,具体取决于常见依赖的性质:修复一段纯代码会更容易,而修复底层数据模型中的递归则更难。无论哪种方式,都值得花时间消除循环依赖。非循环依赖图不那么脆弱,更易于理解和维护。

【讨论】:

    【解决方案2】:

    如果您的包中有您想要调用的私有过程或函数。

    私有函数和过程是规范中未定义的函数和过程

    备选方案 1: 被调用的过程总是在包体的顶部或调用者的顶部。

    例如: 清单是公开的

    create OR REPLACE PACKAGE mypck AS 
      procedure Checklist procedure;
      procedure main;
    end;
    /
    CREATE OR REPLACE PACKAGE BODY mypck AS 
    
      -- private procedures
    
      procedure Step Checklist is ... -- should be here because is called from  Task method, calls public checklist procedure
    
      procedure Task is ... -- should be here,because it calls private Step Checklist procedure and is called from  Checklist
    
     -- public procedures
    
      procedure Checklist is ... -- calls private Task procedure
    
      procedure main is ... -- calls public Checklist procedure
    
    END mypck; 
    / 
    

    备选方案 2: 使用前向声明,通过输入整个包体的签名,使包体中的所有私有过程可见

    create OR REPLACE PACKAGE mypck AS 
      procedure main;
    end;
    /
    CREATE OR REPLACE PACKAGE BODY mypck AS 
    
      -- forward declaration here of all private signature
    
      procedure Task ;
      procedure Step Checklist;
      procedure Checklist;
    
      -- define implementation of private procedures
    
      -- use in order you want to use it
      procedure Step Checklist is ... -- calls private Checklist procedure 
    
      procedure Task is ...  -- calls private Step Checklist procedure
    
      procedure Checklist is ...  -- calls private Task procedure
    
    
      -- public procedure
    
      procedure main is -- calls private Checklist procedure
    
    END mypck; 
    / 
    

    【讨论】:

    • 我已经编辑了您的代码以阐明第二个实现。前向声明的要点是所有例程都保持私有。我们以任意顺序声明签名,然后以任意顺序定义过程(尽管最好使用与前向声明相同的顺序)。
    猜你喜欢
    • 2023-03-25
    • 2014-05-25
    • 1970-01-01
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多