Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling private function within package body

Tags:

oracle

plsql

According to Oracle documentation one can make items private in packages by declaring them in the body but not in the specification.

I have a procedure in this package that needs to call a function that should not be accessed outside of this package. Oracle SQL Developer returns PLS-00313 'ADD_STUDENT' not declared in this scope

Declaration:

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

Body:

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

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

I can't find an example of calling internal functions/procedures and whether the package declaration is needed ex:SCHOOL.ADD_STUDENT()

like image 677
Thor Avatar asked Mar 10 '17 15:03

Thor


2 Answers

The issue you have (assuming that you are calling the correctly named procedure/function in the correct manner) is that you are trying to invoke a call to a function that hasn't yet been declared. There are two ways around this, assuming you want to keep the function private:

  1. Declare the ADD_STUDENT function before any procedures/functions that invoke it.
  2. Use forward declaration to declare the function before it is invoked.

So, for option 1, your example code would look like:

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

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

And for option 2 your code would look like:

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;
/

Personally, I favour option 1, as it means there's less stuff cluttering up the package body, but option 2 might be necessary if you have two modules that reference each other.

like image 129
Boneist Avatar answered Nov 22 '22 15:11

Boneist


You need to define the private function before it is referenced in the body.

Simply define the function and then the procedure.

The package declaration is not needed - just call it with the name in the body as that name is already in scope.

like image 24
BriteSponge Avatar answered Nov 22 '22 13:11

BriteSponge