在包体内调用私有函数

时间:2017-03-10 15:37:58

标签: oracle plsql

根据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()

3 个答案:

答案 0 :(得分:8)

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

  1. 在调用它的任何过程/函数之前声明ADD_STUDENT函数。
  2. 使用forward declaration在调用函数之前声明该函数。
  3. 因此,对于选项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。

答案 1 :(得分:2)

您需要先定义私有函数,然后才能在正文中引用它。

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

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

答案 2 :(得分:0)

在包规范中,您定义的功能为ADD_STUDENT 在您调用ADD_STUDENTS();

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