在包体内调用私有函数

问题描述 投票:2回答:3

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

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

宣言:

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

身体:

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

    FUNCTION ADD_STUDENT(...)
        ...
    END ADD_STUDENT;
END SCHOOL;

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

oracle plsql
3个回答
8
投票

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

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

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

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

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

对于选项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;
/

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


2
投票

您需要在body中引用private函数之前定义它。

只需定义功能,然后定义程序。

不需要包声明 - 只需在主体中使用名称调用它,因为该名称已在范围内。


0
投票

在包规范中,您正在定义函数ADD_STUDENT当您调用ADD_STUDENTS()时;

请删除'S'并再次编译。

© www.soinside.com 2019 - 2024. All rights reserved.