User-Defined Oracle Data Types

We've already seen in the first tutorial on Oracle data types that the data types supported by Oracle fall into one of several categories:-

  • built-in data types
  • Oracle-supplied types
  • user-defined types
  • ANSI, DB2, SQL/DS types

As we've already discussed the built-in data types, this tutorial will look in more detail at the user-defined types. 

User-defined types

User-defined Oracle data types can be categorised as
  • object types
  • REF data types
  • varrays
  • and nested tables

Object types

An Oracle database is an object-relational hybrid which means that it supports both objects and the traditional relational database features - tables and columns.

By providing support for objects in the database Oracle eliminates the need for object-oriented applications to translate their object data models into relational models as well as the need at run-time to map object access requests to relational table access.


Oracle Tips & Tricks to SKYROCKET Your Career!

If you're not already a subscriber you're  missing out on a myriad of tips and techniques to help you become a better, faster, smarter developer.Subscribe now and ignite your career.


An Oracle data type that is an object has 3 parts:

  • a name (which must be unique within the schema)
  • attributes (which define the object's properties and may be of built-in or other user-defined types)
  • and methods which are procedures or functions written in PL/SQL that implement operations that the object can perform.

New object types are created using the CREATE OR REPLACE TYPE statement in SQL. This defines the name of the object and its attributes. Methods are defined as part of the CREATE TYPE BODY statement;

For example to create new type called PERSON you might define it like this:

CREATE OR REPLACE TYPE person IS OBJECT
   (first_name VARCHAR2(30);
    last_name VARCHAR2(30);

    address address_type,
    MEMBER FUNCTION name RETURN VARCHAR2);


Where address_type is another user-defined type and the function name is a method the detail of which is defined by the CREATE TYPE BODY statement like this:

CREATE TYPE BODY person IS
    MEMBER FUNCTION name RETURN VARCHAR2 IS
    BEGIN
        RETURN first_name||' '||last_name;
    END;
END;

The methods that can be defined for object Oracle data types include:

  • CONSTRUCTOR function which is used to instantiate an object of that type at run-time
  • MAP function which returns the relative position of a given object instance in the ordering of all instances of the object (i.e. this person is #3)
  • an ORDER function which returns a value of -1, 0 or 1 to indicate that the object instance is less than, equal to,  or greater than another specified object instance
  • STATIC methods (these cannot reference implicitly the object with which they are associated)
  • MEMBER methods (these can reference implicitly the object with which they are associated)

Note that an object type can have either a MAP function or an ORDER function, not both.

It is also worth noting that object types can be used in relational tables as well as object tables.

For example, we could use the Oracle data type Person that we've just defined in a relational table declaration like this:

CREATE TABLE customers (cust_id Number(12), cust person);

To create an object table using this type the declaration would be like this:

CREATE TABLE customers OF person;

In this case, each row of the table contains an instance of type Person. The instance is automatically assigned a unique, system-generated object identifier when a row is inserted.

Nested Tables

Nested table Oracle data types are useful where you have a master-detail/parent-child relationship between 2 entities and where the number of detail records is unknown. A good example of this is invoices and invoice lines.

For example, to create, an invoice table with a nested invoice-line table, first define the object type for the invoice details:

CREATE OR REPLACE TYPE inv_dtl AS OBJECT 
(
     Inv_line_id NUMBER(5), 
     Item_desc   VARCHAR2(120),
     Item_Amt    NUMBER(6,2)
);

Next, define the table type based on the object type:

CREATE OR REPLACE TYPE inv_dtl_tab AS TABLE OF inv_dtl;

Finally define the parent table with the nested table:

CREATE TABLE invoice(
     Invoice_id NUMBER(5),
     Cust_id    NUMBER(6),
     Total      NUMBER(9,2),
     Lines      inv_dtl_tab
                    )

NESTED TABLE lines STORE AS invoice_lines;

The STORE AS clause defines the name of the segment used to hold the nested table and is necessary because nested tables are stored in a different segment to (but in the same tablespace as) the main table.

To access a nested table, you have to un-nest the table:

SELECT invoice_id, inv_line_id, item_desc, item_amt 
FROM invoice i, TABLE(i.lines)
WHERE invoice_id = 1;

VARRAYS

A VARRAY is an Oracle data type that is useful when the maximum number of detail records is small and is known in advance (such as a list of phone numbers for a customer e.g. office, home and mobile). Note that there is no storage clause for the varray, because they are stored in line.

CREATE TYPE phone_no_type AS OBJECT
        ( Desc     VARCHAR2(20)
         ,Phone_no VARCHAR2(20)
        );

CREATE TYPE phone_no_list AS VARRAY(3) OF phone_no_type;

CREATE OR REPLACE TYPE cust
          AS OBJECT (
              Cust_id   NUMBER(12)
             ,Name      VARCHAR2(75)
             ,Phone_nos phone_no_list)
          );

The elements of a varray cannot be accessed individually using SQL, but they can be accessed in PL/SQL and 3GLs.

REF Data Types

The REF Oracle data type is used to establish a relationship from one object to another by storing the object identifier (the object's unique identifier) of another object. This relationship is defined by means of a reference in the object table definition. This acts like a foreign key, linking one object to another object in the database (via the unique object identifier – the object’s primary key). Oracle uses the link automatically to perform the same function as a join between relational tables.

For example consider a new object called inv which in a relational database would have a foreign key relationship to the customer table. In object terms this becomes a new object referencing an existing object as follows:

CREATE OR REPLACE TYPE inv AS OBJECT
(

Invoice_id NUMBER(12)
,Client    REF cust
,Total     NUMBER(9,2)); 

CREATE TABLE invoice OF inv (id PRIMARY KEY);

When a REF value points to a nonexistent object, the REF is said to be "dangling" (not the same as a null REF). The condition IS [NOT] DANGLING is used to determine whether or not a REF is dangling.

For example, using the object Oracle data type CUST as just defined and the table INVOICE the following statement would retrieve all of the names of customers who have a record in the table.

SELECT i.client.name
FROM   invoice i

WHERE  i.client IS NOT DANGLING;


Looking for Oracle training?

With our partners we offer instructor-led Oracle training on or off site in the UK as well as training via the Internet. See here for Oracle training in the UK. Or contact us for details of our self-led on-line training courses.


Return from user-defined Oracle data types to Oracle tutorials

Return to asktheoracle.net home page