Object Tables   «Prev  Next»

Lesson 3Object-oriented terms
ObjectiveUnderstand the different terms for Oracle objects in Oracle AI Database 26ai.

Oracle 26ai Object Terms: From Types to Stored Instances

Oracle object terminology becomes easier to understand when you follow one example from its definition to its use. An address has a structure, such as a street and a city. A particular address supplies values for that structure. A customer can contain an address, and a table can store customer values. A method can perform an operation on one of those values. These are related ideas, but each has a different name and role.

This lesson uses five terms: object type, object instance, attribute, method, and object table. The four diagrams connect these terms through SQL types used from SQL and PL/SQL in Oracle AI Database 26ai. Start by separating the blueprint from the values created from it, then distinguish those values from the database structures that store them.

The word object also has a broader database meaning. Tables, indexes, packages, and stored procedures are schema objects. A customer value constructed from customer_t is an instance of a SQL object type. Both usages are valid, so context matters. Creating a stored procedure does not make it a customer instance, and creating an object type does not automatically create a populated customer table.

Object type
A named, user-defined SQL data type specifying attributes and optional methods.
Object instance
A value of that type, with actual values assigned to its attributes.
Attribute
A named component of an object type with a declared data type.
Method
A function or procedure declared for an object type to provide behavior.
Object table
A table declared OF an object type, with each row representing an instance.

1. Object types define structure and behavior

An object type is similar to a class as a teaching analogy: it describes what instances contain and what operations they can perform. Oracle defines a SQL object type as a schema object using DDL. The definition can be used by multiple programs with the appropriate privileges. It is not a local record declaration hidden inside one anonymous PL/SQL block.

An address_t blueprint with street VARCHAR2(120), city VARCHAR2(60), and an optional get_city method returning VARCHAR2, alongside its CREATE TYPE specification.
1. Define the type. A SQL object type defines attributes and optional methods. The example declares address_t using CREATE TYPE ... AS OBJECT. Its definition records metadata; actual address values belong to instances. The class analogy is useful, but Oracle object attributes are publicly accessible.

The following specification matches the first diagram. Use a practice schema with the required privileges and names that are not already in use. The examples build on one another in the order presented. Slash terminators are intended for a SQL*Plus-style script runner; other clients may submit each statement differently. These are illustrative examples, not a report of database execution.

CREATE TYPE address_t AS OBJECT (
  street VARCHAR2(120),
  city   VARCHAR2(60),
  MEMBER FUNCTION get_city RETURN VARCHAR2
);
/

address_t is the type name. street and city are its attributes. The declared function is a method, whose implementation comes later. This definition stores metadata describing the type; it does not store an address such as 10 Oak St in Boston. Those values belong to an instance.

Methods are optional. A type used mainly to carry structured values may have attributes without application-defined methods. Also, the class analogy has limits: Oracle SQL object attributes are publicly accessible to programs that can use the object. Adding a method does not establish private fields or force every assignment through that method. Validation and access control must be designed explicitly.

2. Attributes can represent scalar and composite values

Each attribute has one declared data type. Scalar examples include numbers, character strings, and timestamps. A composite attribute can itself contain an object value or a collection. This allows an application to model a customer as a structured value while keeping the types of its components explicit.

customer_t contains cust_id, first_name, last_name, full_address, phone_list, last_update, and updated_by_user. full_address uses address_t; phone_list uses a VARRAY of up to three VARCHAR2(25) values.
2. Compose a customer. Each attribute has a declared type. full_address embeds an address_t value, while phone_list uses phone_list_t, a VARRAY(3) OF VARCHAR2(25). Three is the maximum element count, not a requirement to supply three numbers. Define these dependent types before customer_t. This is composition, not inheritance; the address method is omitted from this structural view.

In the second diagram, full_address uses address_t. The customer therefore contains an address value rather than just an untyped block of text. Its phone_list attribute uses a separate collection type. Define that collection before defining the customer type that depends on it:

CREATE TYPE phone_list_t AS VARRAY(3) OF VARCHAR2(25);
/

CREATE TYPE customer_t AS OBJECT (
  cust_id         NUMBER,
  first_name      VARCHAR2(50),
  last_name       VARCHAR2(50),
  full_address    address_t,
  phone_list      phone_list_t,
  last_update     TIMESTAMP,
  updated_by_user VARCHAR2(128)
);
/

The seven attributes describe the shape of a customer value. Names such as cust_id or last_update do not create rules automatically. The first becomes a required unique identifier when the table's primary-key constraint is defined. The timestamp changes only when application code, a trigger, or another explicit mechanism sets it. Similarly, a character field holding a user name is not automatically an authenticated audit trail.

The example collection can hold up to three phone strings. A particular initialized collection can contain zero, one, two, or three elements. The maximum is a teaching choice, not a general recommendation for every customer system. A VARRAY preserves its element positions, whereas a SQL query still needs an appropriate ORDER BY when result ordering matters. Collections can be accessed using SQL features as well as PL/SQL operations.

Embedding an address demonstrates composition: a customer has an address value. It does not demonstrate inheritance. Inheritance uses a declared supertype and subtype relationship; composition uses an attribute whose type is another type. The address card in the composition diagram shows its attributes only. It still has the get_city method declared in the first figure.

3. Methods implement operations on objects

A method declaration states its name, parameters, and result where applicable. For a PL/SQL implementation, a type body supplies the executable code. Separating the specification and body lets programs use the public interface while the body defines how the operation works.

CREATE TYPE BODY address_t implements MEMBER FUNCTION get_city RETURN VARCHAR2 using RETURN SELF.city. Calling a.get_city() on the illustrated address returns Boston.
3. Implement and call a method. The type specification declares get_city; the type body implements it in PL/SQL. Its RETURN SELF.city; statement reads the invoking instance. For the illustrated address, a.get_city() returns Boston. Methods do not make attributes private. Oracle also supports other method forms and implementations; this example focuses on a PL/SQL member function.
CREATE TYPE BODY address_t AS
  MEMBER FUNCTION get_city RETURN VARCHAR2 IS
  BEGIN
    RETURN SELF.city;
  END;
END;
/

SELF identifies the instance invoking the member method. If the instance contains Boston in its city attribute, the function returns Boston. Another instance containing Denver returns Denver through the same implementation. The method belongs to the type, while the data used for a particular call belongs to that instance.

Here is a complete anonymous block constructing a value and calling the method. In SQL*Plus or SQLcl, enable output before running it. A worksheet in another client may require enabling its DBMS Output panel instead.

SET SERVEROUTPUT ON

DECLARE
  a address_t := address_t('10 Oak St', 'Boston');
BEGIN
  DBMS_OUTPUT.PUT_LINE(a.get_city());
END;
/

The expected output is Boston. The constructor address_t(...) initializes the two attributes in declaration order; a.get_city() invokes behavior on the resulting value. A default attribute-value constructor is supplied for this type. Applications can also define constructors for more specialized initialization requirements.

Not all methods have the same purpose. Member methods operate on instances, static methods provide operations associated with the type without a particular instance's SELF, and constructors create values. Oracle also supports specialized comparison methods. This introductory example uses only a member function, so its terminology should not be taken as a requirement that every method reads or modifies instance data.

PL/SQL is a common implementation language, but Oracle also supports other method implementations through the appropriate language facilities. Choosing those facilities requires additional deployment and security decisions. The essential distinction here is between declaring an operation and implementing it, not between database methods and ordinary application code.

Object values must be initialized

A declaration without construction is different from a constructed value whose attributes happen to be null. For example, a address_t; initially represents an atomically null object. Reading an attribute of that value evaluates to null, but assigning an individual attribute requires an initialized object. Construct the value before assigning its components or invoking its member method.

DECLARE
  a address_t;
BEGIN
  a := address_t(NULL, NULL);
  a.street := '10 Oak St';
  a.city := 'Boston';
  DBMS_OUTPUT.PUT_LINE(a.get_city());
END;
/

After construction, the two attributes can be assigned independently. Before those assignments, the initialized object exists with null attribute values. This is useful when reading errors: a missing object and a missing city value are different conditions. A null collection likewise differs from an initialized empty collection such as phone_list_t().

4. Instances can be used in variables and tables

The fourth diagram shows three places for values of the same type. A PL/SQL variable holds a temporary working value. An object table holds row objects. An ordinary relational table can contain an object-valued column alongside separate scalar columns. Defining the type does not force a particular storage choice.

Three uses of address_t: a temporary PL/SQL variable, row objects in addresses_obj, and an address column beside contact_id in a relational contacts table.
4. Use and store instances. A constructed value can reside in a PL/SQL variable or be written to a database table. CREATE TABLE addresses_obj OF address_t defines row objects; contacts instead contains an object column and a separate identifier column. The illustrated rows require inserts; table creation alone creates no address values. Explicit DML and transaction control provide persistence. An object table derives its application attributes from its declared type.

An object table uses an explicitly declared type

An object table does not create an implicit replacement for CREATE TYPE. Its declared type already defines the application's attributes. The table adds storage and table-level rules, such as a primary key on an existing attribute. For the customer type above, create a table as follows:

CREATE TABLE customer_obj_table OF customer_t (
  CONSTRAINT customer_obj_pk PRIMARY KEY (cust_id)
);

INSERT INTO customer_obj_table VALUES (
  customer_t(
    101, 'Avery', 'Lee',
    address_t('10 Oak St', 'Boston'),
    phone_list_t('617-555-0100'),
    TIMESTAMP '2026-10-09 09:00:00',
    'DEMO_USER'
  )
);

COMMIT;

The insert supplies all seven constructor arguments, including an address object and a one-element phone collection. The explicit timestamp and user string are demonstration values. Creating the table alone produces no customer row. The insert changes database data, and the commit completes that transaction. A local variable does not become a stored row merely because its type is also used by a table.

Row objects can be examined through their attributes, or retrieved as complete object values. Use an alias to make object attribute navigation clear:

SELECT c.cust_id, c.first_name, c.full_address.city
FROM customer_obj_table c
WHERE c.cust_id = 101;

SELECT VALUE(c)
FROM customer_obj_table c
WHERE c.cust_id = 101;

The first query projects selected components. The second returns the customer object value with VALUE(c). Both describe the same stored row from different perspectives. Familiar relational operations remain available; an object table is still managed using SQL and database transaction rules.

An object table's row objects have object identifiers, or OIDs, which support object references. Oracle normally supplies system-generated OIDs unless the table is configured to use primary-key-based identifiers. The primary key in this example enforces business-key uniqueness; declaring it does not by itself switch the OID to a primary-key-based form. Keep business identifiers and object identity distinct.

A relational table can contain a column object

A different design stores an address value in one column of an ordinary table. Other columns remain independent table columns, as the fourth diagram illustrates:

CREATE TABLE contacts (
  contact_id NUMBER PRIMARY KEY,
  address    address_t
);

INSERT INTO contacts VALUES (
  101, address_t('10 Oak St', 'Boston')
);
COMMIT;

SELECT c.contact_id, c.address.city, c.address.get_city()
FROM contacts c
WHERE c.contact_id = 101;

Here contact_id belongs to the table, while street and city belong to its address value. The embedded address is a column object, not an independently referenceable row object with its own OID. A customer's embedded address has the same distinction. This is why “an object table can have any extra attributes” is misleading: separate ordinary columns are a feature of this relational-table design.

Choose storage according to relationships, lifecycle, queries, and integrity requirements. Object types can express useful structured interfaces, but they do not guarantee faster queries or better normalization. A conventional relational design can represent the same customer domain. Measure important workloads and use constraints to enforce the rules that matter.

Schemas, privileges, and object terminology

A schema is a namespace owned by a database user. If a practice user creates address_t, the type belongs to that user's schema. Another schema can define its own type with the same unqualified name. Schema qualification identifies which definition a statement means, while privileges determine whether the operation is permitted.

The analogy of separate rooms can help explain ownership, but those rooms are not completely invisible. Accessible dictionary views can expose metadata according to their rules. Seeing metadata is different from having permission to read table rows or execute a program. Administrative privileges are not the only way to obtain authorized access to another schema's objects.

For example, an owner can grant SELECT on a table or EXECUTE on a type or program. These privileges serve different operations. An execute grant on a type does not automatically grant access to every table that uses it. Synonyms make names convenient but do not grant privileges. Apply permissions to the actual task and its dependencies.

Stored PL/SQL adds an execution-rights context. The AUTHID property influences runtime name resolution and privilege checks. AUTHID DEFINER is the default; AUTHID CURRENT_USER selects invoker rights. Ordinary session roles are disabled during definer-rights execution, so referenced cross-schema privileges normally need direct grants. Specialized roles granted to program units are a separate facility. Compilation also has privilege requirements, so changing AUTHID is not a shortcut around missing grants.

The important connection to this lesson is that ownership, access permissions, and object-instance structure answer different questions. A publicly accessible attribute in a type definition does not mean every database user can read stored customer data. Database access controls still govern the types, tables, and programs involved.

Check your understanding

When reading an unfamiliar example, identify the definition, the value, and the storage separately. In this lesson, address_t is a type; a is a variable holding an instance; city is an attribute; get_city is a method; and customer_obj_table stores row objects. full_address demonstrates composition, while phone_list demonstrates a collection-valued attribute.

You should be able to explain why CREATE TYPE creates no customer rows, why a method body needs its declaration, and why VALUE(c) returns something different from a single attribute projection. You should also distinguish an initialized object with null attributes from an atomically null variable. These distinctions prepare you for the next lesson, which develops the techniques for querying object tables.

For details, consult Oracle's object-relational model overview, object methods reference, collection types guide, and PL/SQL execution-rights documentation.

SEMrush Software 3 SEMrush Banner 3