Packages

A package is a construct that allows to store together a set or related objects, such as functions, procedures, type definitions, exceptions, cursors, etc. Basically, anything that can go to a declarative section of a block can go in a package. One advantage to put all these things in one package is the ability to reference them from other PL/SQL blocks inside the same package; that is, packages provide global variables.

Any package has two separate parts :

  • specification
  • and body
    Each of these parts are stored separately in the data dictionary.

    Package specification

    The package specification or package header contains information about the objects this package includes (at least those we would like to make visible for users). This part of a package does not contain any code. The general syntax for creating a package header is
    create or replace package PackageName {as | is}
     type_definition |
     procedure_declarations |
     function_declaration |
     variable_declaration |
     exception_declaration | 
     cursor_declaration |
     pragma_declaartion
    end PackageName; 
    
    The elements within the package are the same as they would be in the declarative section of a PL/SQL block. The following syntax rules are applied:

    Package body

    The package body is a separate object, which cannot be successfully compiled until the package header is compiled. The package body contains the code for all function declared in the package header. It also can contain additional declarations. These additionally declared objects are global for the whole package, but are not visible from outside the package. The general syntax to create a package body is very similar to the creation of package header
    create or replace package body PackageName {is | as}
       [PRAGMA SERIALLY_REUSABLE;]
       [collection_type_definition ...]
       [record_type_definition ...]
       [subtype_definition ...]
       [collection_declaration ...]
       [constant_declaration ...]
       [exception_declaration ...]
       [object_declaration ...]
       [record_declaration ...]
       [variable_declaration ...]
       [cursor_body ...]
       [function_spec ...]
       [procedure_spec ...]
       [call_spec ...]
    [
    begin
       sequence_of_statements
    ]
    end PackageName;
    
    Package body is optional. That is, if the package does not contain any procedure or function (only variables and constants), then we do not have to have the package body. As you can notice, the package body can also have an code section (the one starting with the keyword begin). This section will be discussed later.

    Here you can find an example from Scott Urman book.

    Package scope

    Any object declared in the package header is visible outside the package. To use this object outside the package we need to use the object name prefixed by the package name. For example, to call the RemoveStudent procedure from the StudentDB package we need to use
    call StudentDB.RemoveStudent(12134);
    
    Inside the package body, objects declared in the header are referenced without the package name. All objects defined in the body of the package are local for the package and cannot be referenced from outside.

    Overloading

    Inside a package, procedures and functions can be overloaded. That is, we may have more than one procedure with the same name, but with different arguments. For example, we can create procedure RemoveStudent that takes the student ID as an argument and another procedure with the same name that takes first and last name of the student. See Scott Urman example.

    Overloading is subject to the following restrictions:

    All user defined types are considered different types even if they actually the same.

    Package initialization

    As we saw above, the package body has optional code section. The first time a package subprogram is called, or any other reference to a package variable or type is made, this code is executed. This is called package initialization. This means that the package is read from disk into the memory, memory is allocated for the variables declared in the package, and the code the package body contain between begin and end (initialization code) is executed.

    Please see this example from Scott Urman's book.


    References: