PL/SQL by Example / Object

Object-oriented programming is not exclusive to higher-level languages; a very similar principle can be achieved in PL/SQL using the special OBJECT type. A class, or rather an object, is defined similarly to a package, i.e., with a specification and a body.

Constructor

The way an object and its internal values are initialized is determined by the constructor. Every object always has one default constructor where the number of input parameters equals the number of variables specified in the public part. However, it is of course possible to create constructors with a different number of parameters and custom logic.

CREATE OR REPLACE TYPE Employee_T AS OBJECT(
    FullName VARCHAR2(100)
  , Salary NUMBER

  , CONSTRUCTOR FUNCTION Employee_T
      RETURN SELF AS RESULT

  , CONSTRUCTOR FUNCTION Employee_T(
        p_FirstName VARCHAR2
      , p_LastName VARCHAR2
      , p_Salary NUMBER
    ) RETURN SELF AS RESULT
);
/
CREATE OR REPLACE TYPE BODY Employee_T AS

  CONSTRUCTOR FUNCTION Employee_T
    RETURN SELF AS RESULT
  IS
  BEGIN
    FullName:='N/A';
    Salary:=0;
    RETURN;
  END;

  CONSTRUCTOR FUNCTION Employee_T(
      p_FirstName VARCHAR2
    , p_LastName VARCHAR2
    , p_Salary NUMBER
  ) RETURN SELF AS RESULT
  IS
  BEGIN
    FullName:=p_FirstName||' '||p_LastName;
    Salary:=p_Salary;
    RETURN;
  END;

END;
/

Using all three constructor types in practice. Note the absence of the NEW keyword, which introduces instantiation in other languages.

DECLARE
  l_Employee Employee_T;
BEGIN
  -- using the parameterless constructor
  l_Employee:=Employee_T();
  dbms_output.put_line(l_Employee.FullName||', '||l_Employee.Salary);
  -- N/A, 0

  -- using the implicit constructor
  l_Employee:=Employee_T('Francis Sauce', 20000);
  dbms_output.put_line(l_Employee.FullName||', '||l_Employee.Salary);
  -- Francis Sauce, 20000

  -- using the constructor with three parameters
  l_Employee:=Employee_T('Peter', 'Novak', 30000);
  dbms_output.put_line(l_Employee.FullName||', '||l_Employee.Salary);
  -- Peter Novak, 30000
END;

Functions and Procedures

In addition to constructors, it is also possible to define functions and procedures within an object. These can be primarily used for manipulating the object’s attributes, as demonstrated by the following simple example.

CREATE OR REPLACE TYPE Employee_T AS OBJECT(
    FullName VARCHAR2(100)
  , Salary NUMBER

  , MEMBER FUNCTION mf_Display(
        p_Separator CHAR:=', '
    ) RETURN VARCHAR2

  , MEMBER PROCEDURE mp_Delete
);
/
CREATE OR REPLACE TYPE BODY Employee_T AS

  MEMBER FUNCTION mf_Display(
      p_Separator CHAR:=', '
  ) RETURN VARCHAR2
  IS
  BEGIN
    IF (FullName IS NOT NULL) THEN
      RETURN FullName||p_Separator||Salary;
    ELSE
      RETURN 'N/A';
    END IF;
  END;

  MEMBER PROCEDURE mp_Delete
  IS
  BEGIN
    FullName:=NULL;
    Salary:=NULL;
  END;

END;
/

Both attributes and the object’s functions and procedures are accessed using dot notation.

DECLARE
  l_Employee Employee_T;
BEGIN
  l_Employee:=Employee_T('Francis Sauce', 20000);
  dbms_output.put_line(l_Employee.mf_Print); -- Francis Sauce, 20000

  l_Employee.mp_Clear;
  dbms_output.put_line(l_Employee.mf_Print); -- N/A
END;

Leave a reply

Your email address will not be published. Required fields are marked *