PL/SQL   «Prev  Next»

Lesson 4Writing queries that use DEREF
ObjectiveWrite a query using DEREF to retrieve a referenced object, access its attributes in SQL, and retrieve it into a PL/SQL variable.

Writing DEREF Queries in Oracle AI Database 26ai

A table can store a reference to an object instead of copying that object's attributes into every related row. For example, an employee row can contain a reference to a department object. Reading the reference tells an application which object is associated with the employee. Dereferencing it retrieves the department value, including its name and location.

DEREF is a SQL function, also described as a dereference operator. It is not a data type. Its argument must be an expression that returns a REF; its result is the object to which that reference points. In this lesson, you will build one small example and follow the same reference through SQL queries and a PL/SQL block.

The preceding lesson examined dangling references. Here, the main task is constructing a useful query: decide whether the result needs a complete object, selected attributes, or a reference that another operation will use. That decision determines which expression belongs in the select list.

Distinguish REF, VALUE, and DEREF

Oracle provides three related operations with different inputs. REF(d) creates a reference to the row object represented by table alias d. VALUE(d) returns that row as an object value. DEREF(e.dept_ref) follows a reference stored in another row and returns the referenced object. The alias supplied to REF or VALUE is a correlation variable[1]; DEREF instead takes a REF-valued expression.

ExpressionInputResult
REF(d)Alias for an object-table rowA reference to that row object
VALUE(d)Alias for an object-table rowThe row's object value
DEREF(e.dept_ref)A REF valueThe referenced object's value

A department number is not automatically a REF. An ordinary numeric foreign key and an object reference represent relationships differently. If your existing schema uses numeric department keys, use an appropriate relational join. DEREF applies when the schema actually stores Oracle object references.

Prepare a small object-relational example

Use a practice schema with permission to create types and tables and sufficient tablespace quota. The names beginning with l4_ must be unused. Run the setup once, in the order shown. These examples are illustrative and have been reviewed against Oracle 26ai documentation; their displayed results describe the supplied sample data rather than a recorded database execution.

Oracle DDL statements commit transactions. Creating these objects is therefore not an exercise that a single ROLLBACK can undo. Keep the setup separate from unrelated work. The slash following a type definition submits its buffered definition in SQL*Plus or SQLcl; it is a client command, not part of the SQL type declaration.

1. Define the department object type

CREATE TYPE l4_dept_t AS OBJECT (
  dept_id   NUMBER,
  dept_name VARCHAR2(50),
  location  VARCHAR2(50)
);
/

The type defines three attributes. It describes a structure, but creating it does not insert a department. The default constructor accepts attribute values in declaration order. Later, l4_dept_t(10, 'Cloud Architecture', 'Austin') will create an object value with those three attributes.

2. Create an object table and a referencing table

CREATE TABLE l4_dept_tab OF l4_dept_t (
  dept_id PRIMARY KEY
);

CREATE TABLE l4_emp_tab (
  emp_id   NUMBER PRIMARY KEY,
  emp_name VARCHAR2(50),
  dept_ref REF l4_dept_t SCOPE IS l4_dept_tab
);

Each row of l4_dept_tab is a department object. The department primary key provides a unique business identifier. With this definition, Oracle still uses its default system-generated object identifiers; declaring a primary key alone does not select primary-key-based object identifiers.

The employee table is a relational table containing a REF column. Its dept_ref column refers to objects of type l4_dept_t. The SCOPE clause restricts those references to the department object table. It does not, by itself, prevent a referenced department from being deleted. Referential integrity is a separate design decision.

3. Insert a department and store its reference

INSERT INTO l4_dept_tab
VALUES (l4_dept_t(10, 'Cloud Architecture', 'Austin'));

INSERT INTO l4_emp_tab (emp_id, emp_name, dept_ref)
SELECT 101, 'Alice Rivera', REF(d)
FROM l4_dept_tab d
WHERE d.dept_id = 10;

COMMIT;

The first statement inserts the department object. The second selects that row and obtains its reference through REF(d). It stores Alice's identifier, name, and reference in the employee table. It does not copy the department name and location into the employee row.

The department primary key makes this lookup match at most one row. If department 10 is absent, INSERT SELECT inserts no employee row. This differs from a scalar SELECT INTO that raises NO_DATA_FOUND when its query returns no rows. Check the inserted-row count when adapting this setup to different sample data.

Retrieve the complete referenced object

SELECT e.emp_name,
       DEREF(e.dept_ref) AS department_object
FROM l4_emp_tab e
WHERE e.emp_id = 101;
DEREF follows the employee's stored department reference and returns one object-valued result column.

The FROM clause identifies the table that holds the reference. It need not be the object table that holds the referenced department. The WHERE clause selects employee 101, while DEREF retrieves that employee's department value. The expression does not expand the object into three independent columns.

For the setup above, the result contains Alice Rivera and a department object whose values are 10, Cloud Architecture, and Austin. A client may display that object using constructor-like notation such as L4_DEPT_T(10, 'Cloud Architecture', 'Austin'). Other clients may present an expandable object. Treat this as an illustrative representation, not a fixed output format.

If you select e.dept_ref directly, the result is the reference. Some SQL clients show it as a hexadecimal representation. Do not build application logic around that display or mistake it for the department number. Use the object attributes when the result must expose business information.

Retrieve individual attributes with SQL path expressions

SELECT e.emp_name,
       e.dept_ref.dept_name AS department,
       e.dept_ref.location AS office_location
FROM l4_emp_tab e
WHERE e.dept_ref.dept_id = 10;
Alias-qualified SQL paths implicitly dereference the department REF and return selected scalar attributes.

Read e.dept_ref.dept_name from left to right: start with the employee row identified by alias e, follow its department reference, and read the department object's name attribute. Oracle supports this implicit dereferencing in SQL. Use a table alias consistently so that the parser can resolve object paths correctly.

The query returns separate employee, department, and office columns. For the initial data, their values are Alice Rivera, Cloud Architecture, and Austin. The predicate follows the same reference to test the department identifier. Multiple employees can reference department 10, so this form can return several rows once more employees are inserted.

Choose path expressions when a report needs a few fields. Choose DEREF when the consumer needs a typed object value, for example to place it in an object variable. This distinction concerns the shape of the result. It does not establish that one form is always faster; actual performance depends on the query, data, access paths, and execution plan.

Compare direct object access and reference navigation

SELECT REF(d) AS department_ref,
       VALUE(d) AS department_value,
       DEREF(REF(d)) AS dereferenced_value
FROM l4_dept_tab d
WHERE d.dept_id = 10;

This comparison begins at the department object table. The first expression returns a reference. The second returns the object directly. The third obtains a reference and immediately dereferences it, returning the same object's value in this query. The nesting demonstrates the relationship between the functions; it is unnecessary when VALUE already expresses the intended result.

You can also express the employee-to-department relationship with an explicit REF comparison:

SELECT e.emp_name, d.dept_name, d.location
FROM l4_emp_tab e
JOIN l4_dept_tab d ON e.dept_ref = REF(d)
WHERE e.emp_id = 101;

This inner join returns an employee only when the department reference matches a target row. It gives the query a department alias for selecting or filtering attributes. It does not compare dept_ref with the numeric dept_id. Those values have different types and meanings, even though both participate in identifying the relationship.

Select the form that makes the required rows and columns clear. An inner join, a path predicate, and an unfiltered DEREF projection can differ in how they retain employees whose departments are unavailable. Consider those missing-data requirements before treating two query formulations as interchangeable.

Use SELECT INTO to retrieve an object in PL/SQL

SQL path navigation through a REF does not mean that procedural PL/SQL can follow a REF with an ordinary assignment. Likewise, v_dept := DEREF(v_ref) is not a supported procedural assignment. Put DEREF inside a SQL statement and retrieve the result into a variable of the matching object type.

SET SERVEROUTPUT ON
DECLARE
  v_dept l4_dept_t;
BEGIN
  SELECT DEREF(e.dept_ref)
  INTO v_dept
  FROM l4_emp_tab e
  WHERE e.emp_id = 101;

  IF v_dept IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('Department unavailable.');
  ELSE
    DBMS_OUTPUT.PUT_LINE(
      v_dept.dept_name || ' (' || v_dept.location || ')'
    );
  END IF;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE('Employee not found.');
END;
/

The declaration creates a variable that can hold a department object value. SELECT INTO retrieves that value. After retrieval, ordinary object-variable dot notation accesses v_dept.dept_name and v_dept.location. These expressions access an object already held in PL/SQL, rather than navigate through a REF variable.

For the original sample row, the expected printed line is Cloud Architecture (Austin). SET SERVEROUTPUT ON enables display of DBMS_OUTPUT text in SQL*Plus or SQLcl. In another client, enable its DBMS_OUTPUT facility and use its appropriate script execution mode.

The block deliberately distinguishes two outcomes. An absent employee causes SELECT INTO to raise NO_DATA_FOUND. An existing employee with a null or dangling department reference produces a null object, which the IF statement handles. The primary-key predicate prevents multiple employee rows. If you replace it with a nonunique condition, SELECT INTO can raise TOO_MANY_ROWS; use a cursor or another suitable multirow approach when several rows are expected.

If a PL/SQL REF variable has already been populated, the dereferencing step can instead use SELECT DEREF(v_ref) INTO v_dept FROM DUAL;. DUAL supplies a row for evaluating the expression. Retrieving an object value into a variable does not make later assignments to that variable update the stored department automatically. Persistent changes require an appropriate database write.

Decide how to handle missing references

A null REF indicates that no reference value is stored. A dangling REF contains a reference whose target object is unavailable, for example after deletion. As Oracle's object-relational documentation explains, SQL dereferencing of a dangling REF returns a null object. It does not inevitably raise the error claimed by the older version of this lesson.

When a report should include only employees with usable department references, make that requirement explicit:

SELECT e.emp_name,
       DEREF(e.dept_ref) AS department_object
FROM l4_emp_tab e
WHERE e.dept_ref IS NOT NULL
  AND e.dept_ref IS NOT DANGLING;

The two predicates communicate separate requirements: a reference must be present, and its target must be available. This query omits employees who fail either requirement. That may be correct for a department directory, but unsuitable for a data-quality report whose purpose is to reveal incomplete relationships.

To investigate the stored references without excluding affected employees, classify them:

SELECT e.emp_id, e.emp_name,
       CASE
         WHEN e.dept_ref IS NULL THEN 'No reference'
         WHEN e.dept_ref IS DANGLING THEN 'Dangling reference'
         ELSE 'Available reference'
       END AS department_status
FROM l4_emp_tab e;

Filtering or classifying references does not repair them. It also does not create a referential integrity rule. Revisit the previous lesson when deciding how deletions should be handled. A scoped REF and a REF protected by a referential constraint have different guarantees, even when both point into the same object table.

Check the query before changing the schema

If a query fails or returns unexpected results, first inspect the declared column types and the rows selected by its predicate. Verify that the DEREF argument is actually a REF and that it targets the intended object type. Check table aliases and attribute spelling. Do not assume that a column named product_id or dept_id is a reference merely because its name suggests an identifier.

Next, separate result-shape issues from missing-data issues. An object-valued column is expected from DEREF; scalar columns are expected from attribute paths. Zero selected employee rows, a null reference, and a dangling reference are distinct situations. In PL/SQL, check both SELECT INTO cardinality and whether the resulting object is null.

Finally, verify client execution mode. A type definition and an anonymous block require suitable statement delimiters when run as a script. Use straight single quotes for text literals, and do not copy HTML line-break tags into SQL. The examples here are accessible text so you can inspect each statement before running it.

Read the sample results in context

Before extending the example, run the employee query and the department query separately. Confirm that employee 101 exists and that department 10 has the expected name and location. This establishes the starting data for interpreting the reference queries. If you rerun the inserts without resetting the practice schema, primary-key violations are expected because the identifiers already exist; they do not indicate a problem with DEREF.

Suppose another employee later references the same department object. Both employee rows can retrieve that department through their respective stored references. If the department location is changed and committed, subsequent queries can retrieve the updated location without rewriting a location value in each employee row. A previously fetched PL/SQL object variable, however, remains the value that was retrieved until your code fetches or changes it again.

Keep object identity separate from matching attribute values. Deleting a department row and inserting a new row with the same department number does not automatically reconnect existing references when system-generated object identifiers are used. The new row has a new identity. This is one reason to design deletion and integrity rules explicitly instead of treating a REF as an encoded business key.

Check your understanding

  1. Which expression returns a department object from an employee's reference? Use DEREF(e.dept_ref). Selecting the REF alone returns the reference value.
  2. How do you return just the department name in SQL? Use an alias-qualified path such as e.dept_ref.dept_name.
  3. Does SCOPE prevent dangling references? No. It restricts the target table; referential integrity requires a separate constraint design.
  4. How do you obtain that object in PL/SQL? Use SELECT DEREF(...) INTO an object variable, then access the variable's attributes.

You can now choose between returning a reference, returning an object, and projecting individual attributes. Continue to querying object tables to examine when SQL alone is sufficient and when PL/SQL is appropriate.

[1] Correlation variable: A table alias associated with a row in a query. REF and VALUE accept an object-table row alias; DEREF accepts an expression whose value is a REF.

Oracle 26ai references

SEMrush Software 4 SEMrush Banner 4