在包体内调用私有函数

Tho*_*hor 5 oracle plsql

根据Oracle文档,可以通过在正文中声明项目而不是在规范中将项目设置为私有.

我在这个包中有一个程序需要调用一个不应该在这个包之外访问的函数.Oracle SQL Developer返回PLS-00313 'ADD_STUDENT' not declared in this scope

宣言:

PACKAGE SCHOOL AS
    PROCEDURE ADD_PEOPLE(...);
END SCHOOL;
Run Code Online (Sandbox Code Playgroud)

身体:

PACKAGE BODY SCHOOL AS
    PROCEDURE ADD_PEOPLE(...)
        ...
        ADD_STUDENT();
    END ADD_PEOPLE;

    FUNCTION ADD_STUDENT(...)
        ...
    END ADD_STUDENT;
END SCHOOL;
Run Code Online (Sandbox Code Playgroud)

我找不到调用内部函数/过程的示例以及是否需要包声明:SCHOOL.ADD_STUDENT()

Bon*_*ist 11

您遇到的问题(假设您以正确的方式调用正确命名的过程/函数)是您尝试调用尚未声明的函数.假设您希望保持私有功能,有两种方法:

  1. 在调用它的任何过程/函数之前声明ADD_STUDENT函数.
  2. 使用forward声明在调用函数之前声明它.

因此,对于选项1,您的示例代码如下所示:

PACKAGE BODY SCHOOL AS
    FUNCTION ADD_STUDENT(...)
        ...
    END ADD_STUDENT;

    PROCEDURE ADD_PEOPLE(...)
        ...
        some_var := ADD_STUDENT();
    END ADD_PEOPLE;
END SCHOOL;
/
Run Code Online (Sandbox Code Playgroud)

对于选项2,您的代码看起来像:

PACKAGE BODY SCHOOL AS
    -- forward declared function
    FUNCTION ADD_STUDENT(...);

    PROCEDURE ADD_PEOPLE(...)
        ...
        some_var := ADD_STUDENT();
    END ADD_PEOPLE;

    FUNCTION ADD_STUDENT(...)
        ...
    END ADD_STUDENT;
END SCHOOL;
/
Run Code Online (Sandbox Code Playgroud)

就个人而言,我赞成选项1,因为这意味着包装体的混乱更少,但如果你有两个相互引用的模块,则可能需要选项2.

  • 我原以为这不太可能; 我相信编译器会将代码转换为更简化的代码,因此当您查看包体的文本时,您看到的不一定是数据库代码所看到的内容. (2认同)