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;