Oracle Application Developer's Guide - Object-Relational Features
Oracle Application Developer's Guide - Object-Relational Features
December 2003
Oracle Database Application Developer's Guide - Object-Relational Features, 10g Release 1 (10.1)
Contributors: Geeta Arora, Eric Belden, Chandrasekharan Iyer, Geoff Lee, Anand Manikutty, Valarie
Moore, Magdi Morsi, Helen Yeh, Adiel Yoaz, Qin Yu
The Programs (which include both the software and documentation) contain proprietary information of
Oracle Corporation; they are provided under a license agreement containing restrictions on use and
disclosure and are also protected by copyright, patent and other intellectual and industrial property
laws. Reverse engineering, disassembly or decompilation of the Programs, except to the extent required
to obtain interoperability with other independently created software or as specified by law, is prohibited.
The information contained in this document is subject to change without notice. If you find any problems
in the documentation, please report them to us in writing. Oracle Corporation does not warrant that this
document is error-free. Except as may be expressly permitted in your license agreement for these
Programs, no part of these Programs may be reproduced or transmitted in any form or by any means,
electronic or mechanical, for any purpose, without the express written permission of Oracle Corporation.
If the Programs are delivered to the U.S. Government or anyone licensing or using the programs on
behalf of the U.S. Government, the following notice is applicable:
Restricted Rights Notice Programs delivered subject to the DOD FAR Supplement are "commercial
computer software" and use, duplication, and disclosure of the Programs, including documentation,
shall be subject to the licensing restrictions set forth in the applicable Oracle license agreement.
Otherwise, Programs delivered subject to the Federal Acquisition Regulations are "restricted computer
software" and use, duplication, and disclosure of the Programs shall be subject to the restrictions in FAR
52.227-19, Commercial Computer Software - Restricted Rights (June, 1987). Oracle Corporation, 500
Oracle Parkway, Redwood City, CA 94065.
The Programs are not intended for use in any nuclear, aviation, mass transit, medical, or other inherently
dangerous applications. It shall be the licensee's responsibility to take all appropriate fail-safe, backup,
redundancy, and other measures to ensure the safe use of such applications if the Programs are used for
such purposes, and Oracle Corporation disclaims liability for any damages caused by such use of the
Programs.
Oracle is a registered trademark, and Oracle9i, Oracle Store, PL/SQL, Pro*C, Pro*C/C++, and SQL*Plus
are trademarks or registered trademarks of Oracle Corporation. Other names may be trademarks of their
respective owners.
Contents
Preface........................................................................................................................................................... xv
Audience ............................................................................................................................................... xvi
Organization......................................................................................................................................... xvi
Related Documentation ..................................................................................................................... xvii
Conventions........................................................................................................................................ xviii
Documentation Accessibility ............................................................................................................. xxi
iii
Object Tables .......................................................................................................................... 1-8
Row Objects and Column Objects....................................................................................... 1-9
Object Views........................................................................................................................... 1-9
References ............................................................................................................................... 1-9
Collections ............................................................................................................................ 1-12
Language Binding Features....................................................................................................... 1-13
iv
Redefining Methods............................................................................................................ 2-21
Restrictions on Overriding Methods ................................................................................ 2-22
Dynamic Method Dispatch ....................................................................................................... 2-23
Substituting Types in a Type Hierarchy ................................................................................. 2-24
Column and Row Substitutability............................................................................................ 2-25
Using OBJECT_VALUE and OBJECT_ID with Substitutable Rows............................ 2-26
Subtypes Having Supertype Attributes ........................................................................... 2-27
REF Columns and Attributes............................................................................................. 2-28
Collection Elements............................................................................................................. 2-28
Creating Subtypes After Creating Substitutable Columns................................................... 2-28
Dropping Subtypes After Creating Substitutable Columns................................................. 2-29
Turning Off Substitutability in a New Table.......................................................................... 2-29
Constraining Substitutability.................................................................................................... 2-30
Modifying Substitutability ........................................................................................................ 2-31
Restrictions on Modifying Substitutability............................................................................. 2-31
Assignments Across Types ....................................................................................................... 2-32
Objects and REFs to Objects............................................................................................... 2-32
Collection Assignments...................................................................................................... 2-34
Comparisons of Objects, REF Variables, and Collections..................................................... 2-34
Comparing Object Instances .............................................................................................. 2-34
Comparing REF Variables.................................................................................................. 2-35
Functions and Operators Useful with Objects............................................................................ 2-35
CAST............................................................................................................................................. 2-35
CURSOR....................................................................................................................................... 2-36
DEREF .......................................................................................................................................... 2-36
IS OF type .................................................................................................................................... 2-36
REF................................................................................................................................................ 2-38
SYS_TYPEID................................................................................................................................ 2-38
TABLE()........................................................................................................................................ 2-39
TREAT .......................................................................................................................................... 2-39
VALUE ......................................................................................................................................... 2-41
v
Constructor Methods for Collections......................................................................................... 3-2
Varrays ........................................................................................................................................... 3-3
Nested Tables ................................................................................................................................ 3-4
Specifying a Tablespace When Storing a Nested Table .......................................................... 3-6
Varray Storage............................................................................................................................... 3-6
Increasing the Size and Precision of VARRAYs and Nested Tables ..................................... 3-7
Increasing VARRAY Limit Size .................................................................................................. 3-8
Creating a Varray Containing LOB References........................................................................ 3-8
Multilevel Collection Types ........................................................................................................ 3-9
Nested Table Storage Tables for Multilevel Collection Types ........................................ 3-9
Assignment and Comparison of Multilevel Collections................................................ 3-11
Constructors for Multilevel Collections ........................................................................... 3-11
Operations on Collection Datatypes ............................................................................................. 3-12
Querying Collections.................................................................................................................. 3-12
Nesting Results of Collection Queries .............................................................................. 3-12
Unnesting Results of Collection Queries ......................................................................... 3-13
Unnesting Queries Containing Table Expression Subqueries ...................................... 3-14
Unnesting Queries with Multilevel Collections.............................................................. 3-15
Performing DML Operations on Collections.......................................................................... 3-15
Performing DML on Multilevel Collections .................................................................... 3-16
Comparisons of Collections ...................................................................................................... 3-17
Equal and Not Equal Comparisons .................................................................................. 3-17
In Comparisons.................................................................................................................... 3-18
Subset of Multiset Comparison ......................................................................................... 3-18
Member of a Nested Table Comparison .......................................................................... 3-18
Empty Comparison ............................................................................................................. 3-19
Set Comparison.................................................................................................................... 3-19
Multisets Operations .................................................................................................................. 3-19
CARDINALITY.................................................................................................................... 3-19
COLLECT.............................................................................................................................. 3-20
MULTISET EXCEPT............................................................................................................ 3-20
MULTISET INTERSECTION ............................................................................................. 3-20
MULTISET UNION............................................................................................................. 3-21
POWERMULTISET ............................................................................................................. 3-22
POWERMULTISET_BY_CARDINALITY........................................................................ 3-22
vi
SET ......................................................................................................................................... 3-22
vii
Querying SQLJ Objects ....................................................................................................... 4-20
Inserting Java Objects.......................................................................................................... 4-20
Updating SQLJ Objects ....................................................................................................... 4-20
Defining User-Defined Constructors in Java .......................................................................... 4-20
XML ..................................................................................................................................................... 4-21
viii
System Privileges for Object Types............................................................................................ 6-2
Schema Object Privileges............................................................................................................. 6-2
Using Types in New Types or Tables ........................................................................................ 6-3
Example: Privileges on Object Types......................................................................................... 6-3
Privileges on Type Access and Object Access .......................................................................... 6-4
Dependencies and Incomplete Types ............................................................................................ 6-5
Completing Incomplete Types .................................................................................................. 6-7
Manually Recompiling a Type.................................................................................................... 6-8
Type Dependencies of Substitutable Tables and Columns ................................................... 6-8
The FORCE Option ............................................................................................................... 6-9
Synonyms for User-Defined Types.................................................................................................. 6-9
Creating a Type Synonym........................................................................................................... 6-9
Using a Type Synonym.............................................................................................................. 6-10
Describing Schema Objects That Use Synonyms............................................................ 6-10
Dependents of Type Synonyms ........................................................................................ 6-11
Restriction on Replacing a Type Synonym...................................................................... 6-11
Dropping Type Synonyms ................................................................................................. 6-11
Renaming Type Synonyms ................................................................................................ 6-12
Public Type Synonyms and Local Schema Objects ........................................................ 6-12
Performance Tuning ......................................................................................................................... 6-12
Tools Providing Support for Objects ............................................................................................ 6-13
Utilities Providing Support for Objects ....................................................................................... 6-14
ix
Type Evolution..................................................................................................................................... 7-7
Changes Involved When a Type Is Altered .............................................................................. 7-9
Steps to Change a Type.............................................................................................................. 7-10
Validating a Type........................................................................................................................ 7-11
If a Type Change Validation Fails ............................................................................................ 7-15
ALTER TYPE Statement for Type Evolution .......................................................................... 7-15
ALTER TABLE Statement for Type Evolution ....................................................................... 7-19
The Attribute-Value Constructor ............................................................................................. 7-19
Constructors and Type Evolution ............................................................................................ 7-19
Advantages of User-Defined Constructors............................................................................. 7-20
Defining and Implementing User-Defined Constructors ..................................................... 7-20
Overloading and Hiding Constructors.................................................................................... 7-22
Calling User-Defined Constructors.......................................................................................... 7-22
Constructors for SQLJ Object Types ........................................................................................ 7-24
Transient and Generic Types .......................................................................................................... 7-25
User-Defined Aggregate Functions ............................................................................................... 7-28
Partitioning Tables That Contain Oracle Objects ...................................................................... 7-29
How Locators Improve the Performance of Nested Tables ................................................. 7-30
x
Using Procedures and Functions in Unnesting Queries................................................ 8-12
Storage Considerations for Varrays ......................................................................................... 8-13
Propagating VARRAY Size Change ................................................................................. 8-13
Performance of Varrays Versus Nested Tables...................................................................... 8-14
Design Considerations for Nested Tables............................................................................... 8-14
Nested Table Storage .......................................................................................................... 8-14
Nested Table Indexes.......................................................................................................... 8-17
Nested Table Locators ........................................................................................................ 8-18
Optimizing Set Membership Queries............................................................................... 8-19
Design Considerations for Multilevel Collections................................................................. 8-19
Design Considerations for Methods............................................................................................. 8-24
Choosing a Language for Method Functions ......................................................................... 8-25
Static Methods............................................................................................................................. 8-27
Using SELF IN OUT NOCOPY with Member Procedures .................................................. 8-28
Function-Based Indexes on the Return Values of Type Methods ....................................... 8-28
Writing Reusable Code Using Invoker Rights............................................................................ 8-29
Replicating Object Tables and Columns...................................................................................... 8-31
Replicating Columns of Object, Collection, or REF Type ..................................................... 8-31
Replicating Object Tables .......................................................................................................... 8-32
Constraints on Objects..................................................................................................................... 8-33
Considerations Related to Type Evolution .................................................................................. 8-33
Pushing a Type Change Out to Clients ................................................................................... 8-33
Changing Default Constructors................................................................................................ 8-34
Altering the FINAL Property of a Type .................................................................................. 8-34
Parallel Queries with Oracle Objects .......................................................................................... 8-34
Design Consideration Tips and Techniques ............................................................................... 8-35
Deciding Whether to Evolve a Type or Create a Subtype Instead ...................................... 8-35
How ANYDATA Differs from User-Defined Types ............................................................. 8-36
Polymorphic Views: An Alternative to an Object View Hierarchy .................................... 8-36
The SQLJ Object Type ................................................................................................................ 8-37
The Intended Use of SQLJ Object Types .......................................................................... 8-37
Actions Performed When Creating a SQLJ Object Type ............................................... 8-38
Uses of SQLJ Object Types ................................................................................................. 8-38
Uses of Custom Object Types ............................................................................................ 8-38
Differences Between SQLJ and Custom Object Types Through JDBC........................ 8-39
xi
Miscellaneous Tips ..................................................................................................................... 8-39
Column Substitutability and the Number of Attributes in a Hierarchy ..................... 8-39
Circular Dependencies Among Types.............................................................................. 8-40
Index
xii
Send Us Your Comments
Oracle Database Application Developer's Guide - Object-Relational Features, 10g Release 1
(10.1)
Part No. B10799-01
Oracle Corporation welcomes your comments and suggestions on the quality and usefulness of this
publication. Your input is an important part of the information used for revision.
■ Did you find any errors?
■ Is the information clearly presented?
■ Do you need more information? If so, where?
■ Are the examples correct? Do you need more examples?
■ What features did you like most about this manual?
If you find any errors or have any other suggestions for improvement, please indicate the title and
part number of the documentation and the chapter, section, and page number (if available). You can
send comments to us in the following ways:
■ Electronic mail: [email protected]
■ FAX: (650) 506-7227 Attn: Server Technologies Documentation Manager
■ Postal service:
Oracle Corporation
Server Technologies Documentation
500 Oracle Parkway, Mailstop 4op11
Redwood Shores, CA 94065
USA
If you would like a reply, please give your name, address, telephone number, and electronic mail
address (optional).
If you have problems with the software, please contact your local Oracle Support Services.
xiii
xiv
Preface
xv
Audience
Oracle Database Application Developer's Guide - Object-Relational Features is intended
for programmers developing new applications or converting existing applications
to run in the Oracle environment. The object-relational features are often used in
content management, data warehousing, data/information integration, and similar
applications that deal with complex structured data. The object views feature can be
valuable when writing new C++, Java, or XML applications on top of an existing
relational schema.
This guide assumes that you have a working knowledge of application
programming and that you are familiar with the use of Structured Query Language
(SQL) to access information in relational database systems.
Organization
This document contains:
xvi
Chapter 6, "Managing Oracle Objects"
Explains how to perform essential operations with objects and object types.
Related Documentation
For more information, see these Oracle resources:
■ PL/SQL User's Guide and Reference for information on PL/SQL, the procedural
language extension to Oracle SQL
■ Oracle Database Application Developer's Guide - Fundamentals for general
information about developing applications
■ Oracle XML DB Developer's Guide and Oracle XML Developer's Kit Programmer's
Guide for information about developing applications with XML
■ Oracle Database JDBC Developer's Guide and Reference and Oracle Database Java
Developer's Guide to use Oracle object-relational features through Java
■ Oracle Call Interface Programmer's Guide and Oracle C++ Call Interface
Programmer's Guide for information on using the Oracle Call Interface (OCI) and
Oracle C++ Call Interface to build third-generation language (3GL) applications
that access the Oracle Server
■ Pro*C/C++ Programmer's Guide for information on Oracle's Pro* series of
precompilers, which allow you to embed SQL and PL/SQL in 3GL application
programs written in Ada, C, C++, COBOL, or FORTRAN
■ Oracle Database SQL Reference and Oracle Database Administrator's Guide for
information on SQL
■ Oracle Database Concepts for information on basic Oracle concepts
xvii
Many of the books in the documentation set use the sample schemas of the seed
database, which is installed by default when you install Oracle. Refer to Oracle
Database Sample Schemas for information on how these schemas were created and
how you can use them yourself.
Printed documentation is available for sale in the Oracle Store at
http://oraclestore.oracle.com/
If you already have a username and password for OTN, then you can go directly to
the documentation section of the OTN Web site at
http://otn.oracle.com/documentation/
Conventions
This section describes the conventions used in the text and code examples of this
documentation set. It describes:
■ Conventions in Text
■ Conventions in Code Examples
Conventions in Text
We use various conventions in text to help you more quickly identify special terms.
The following table describes those conventions and provides examples of their use.
xviii
Convention Meaning Example
UPPERCASE Uppercase monospace typeface indicates You can specify this clause only for a NUMBER
monospace elements supplied by the system. Such column.
(fixed-width) elements include parameters, privileges,
You can back up the database by using the
font datatypes, RMAN keywords, SQL
BACKUP command.
keywords, SQL*Plus or utility commands,
packages and methods, as well as Query the TABLE_NAME column in the USER_
system-supplied column names, database TABLES data dictionary view.
objects and structures, usernames, and
Use the DBMS_STATS.GENERATE_STATS
roles.
procedure.
lowercase Lowercase monospace typeface indicates Enter sqlplus to open SQL*Plus.
monospace executables, filenames, directory names,
The password is specified in the orapwd file.
(fixed-width) and sample user-supplied elements. Such
font elements include computer and database Back up the datafiles and control files in the
names, net service names, and connect /disk1/oracle/dbs directory.
identifiers, as well as user-supplied
The department_id, department_name,
database objects and structures, column
and location_id columns are in the
names, packages and classes, usernames
hr.departments table.
and roles, program units, and parameter
values. Set the QUERY_REWRITE_ENABLED
initialization parameter to true.
Note: Some programmatic elements use a
mixture of UPPERCASE and lowercase. Connect as oe user.
Enter these elements as shown.
The JRepUtil class implements these
methods.
lowercase Lowercase italic monospace font You can specify the parallel_clause.
italic represents placeholders or variables.
Run Uold_release.SQL where old_
monospace
release refers to the release you installed
(fixed-width)
prior to upgrading.
font
The following table describes typographic conventions used in code examples and
provides examples of their use.
xix
Convention Meaning Example
[ ] Brackets enclose one or more optional DECIMAL (digits [ , precision ])
items. Do not enter the brackets.
{ } Braces enclose two or more items, one of {ENABLE | DISABLE}
which is required. Do not enter the
braces.
| A vertical bar represents a choice of two {ENABLE | DISABLE}
or more options within brackets or braces. [COMPRESS | NOCOMPRESS]
Enter one of the options. Do not enter the
vertical bar.
... Horizontal ellipsis points indicate either: CREATE TABLE ... AS subquery;
■ That we have omitted parts of the
code that are not directly related to SELECT col1, col2, ... , coln FROM
the example employees;
■ That you can repeat a portion of the
code
. Vertical ellipsis points indicate that we SQL> SELECT NAME FROM V$DATAFILE;
. have omitted several lines of code not NAME
. directly related to the example. ---------------------------------
/fsl/dbs/tbs_01.dbf
/fs1/dbs/tbs_02.dbf
.
.
.
/fsl/dbs/tbs_09.dbf
9 rows selected.
Other notation You must enter symbols other than acctbal NUMBER(11,2);
brackets, braces, vertical bars, and ellipsis acct CONSTANT NUMBER(4) := 3;
points as shown.
Italics Italicized text indicates placeholders or CONNECT SYSTEM/system_password
variables for which you must supply
particular values. DB_NAME = database_name
UPPERCASE Uppercase typeface indicates elements SELECT last_name, employee_id FROM
supplied by the system. We show these employees;
terms in uppercase in order to distinguish
them from terms you define. Unless terms SELECT * FROM USER_TABLES;
appear in brackets, enter them in the
order and with the spelling shown.
DROP TABLE hr.employees;
However, because these terms are not
case sensitive, you can enter them in
lowercase.
xx
Convention Meaning Example
lowercase Lowercase typeface indicates SELECT last_name, employee_id FROM
programmatic elements that you supply. employees;
For example, lowercase indicates names
of tables, columns, or files. sqlplus hr/hr
Note: Some programmatic elements use a
mixture of UPPERCASE and lowercase. CREATE USER mjones IDENTIFIED BY ty3MU9;
Enter these elements as shown.
Documentation Accessibility
Our goal is to make Oracle products, services, and supporting documentation
accessible, with good usability, to the disabled community. To that end, our
documentation includes features that make information available to users of
assistive technology. This documentation is available in HTML format, and contains
markup to facilitate access by the disabled community. Standards will continue to
evolve over time, and Oracle is actively engaged with other market-leading
technology vendors to address technical obstacles so that our documentation can be
accessible to all of our customers. For additional information, visit the Oracle
Accessibility Program Web site at
http://www.oracle.com/accessibility/
xxi
xxii
What's New in Object-Relational Features?
This section describes the new object-relational features of Oracle 10g Release 1
(10.1). New features information from previous releases is also retained to help
those users upgrading to the current release.
The following sections describe the new features in Oracle object-relational features:
■ Oracle 10g Release 1 (10.1) New in Object-Relational Features
■ Oracle9i Release 2 (9.2) New in Object-Relational Features
■ Oracle9i Release 1 (9.0.1) New in Object-Relational Features
xxiii
Oracle 10g Release 1 (10.1) New in Object-Relational Features
New object-relational features for Oracle 10g Release 1 (10.1) include the following
collection enhancements:
■ New functionality for nested table and varray storage, including the evolution
of varray size and specification of a tablespace when storing nested tables. See
"Creating Collection Datatypes" on page 3-2.
■ New functionality for nested table comparisons and ANSI SQL multiset
operations for nested tables. See "Operations on Collection Datatypes" on
page 3-12.
xxiv
Oracle9i Release 1 (9.0.1) New in Object-Relational Features
New object-relational features for Oracle9i release 1 (9.0.1) include:
■ SQL type inheritance
User-defined types can be specialized as subtypes in a SQL type hierarchy. See
"Inheritance in SQL Object Types" on page 2-15.
■ Object view hierarchies
Hierarchies can be created of object views based on some or all of the types in a
type hierarchy. Object view hierarchies simplify targeting a particular subtype
(and perhaps its subtypes) in queries and other operations. See "Object View
Hierarchies" on page 5-19.
■ Type evolution
User-defined SQL types and their independent objects can be changed, or
evolved, instead of having to be re-created. See "Type Evolution" on page 7-7.
■ User-defined aggregate functions
Custom aggregate functions can be defined for working with complex data. See
"User-Defined Aggregate Functions" on page 7-28.
■ Generic and transient datatypes
External procedures can be given fields or parameters of a generic type, such as
SYS.ANYTYPE, that can contain values of any scalar or user-defined type,
making it unnecessary to implement multiple versions of the same external
procedure just to handle multiple datatypes. See "Transient and Generic Types"
on page 7-25.
■ Function-based indexes
Function-based indexes can be built on type method functions. See
"Function-Based Indexes on the Return Values of Type Methods" on page 8-28.
■ Multilevel collections
Collections (varrays and nested tables) can contain elements that are themselves
collections or have attributes that are. See Chapter 3, "Support for Collection
Datatypes" and Chapter 5, "Applying an Object Model to Relational Data".
■ C++ interface to Oracle
A C++ interface (OCCI) to Oracle, built on top of OCI, enables you to use the
object-oriented features, native classes, and methods of the C++ programing
xxv
language to access the Oracle database. See "Oracle C++ Call Interface (OCCI)"
on page 4-8.
■ Java object storage
You can now create SQL types mapped to existing Java classes to provide
persistent storage for Java objects. Such SQL types are called SQL types of
Language Java, or SQLJ types. See "Java: JDBC, Oracle SQLJ, JPublisher, and
SQLJ Object Types" on page 4-12.
xxvi
1
Introduction to Oracle Objects
This chapter describes the advantages and key features of the Oracle
object-relational model. The chapter contains these topics:
■ About Oracle Objects
■ Advantages of Objects
■ Key Features of the Object-Relational Model
Advantages of Objects
In general, the object-type model is similar to the class mechanism found in C++
and Java. Like classes, objects make it easier to model complex, real-world business
entities and logic, and the reusability of objects makes it possible to develop
database applications faster and more efficiently. By natively supporting object
types in the database, Oracle enables application developers to directly access the
data structures used by their applications. No mapping layer is required between
client-side objects and the relational database columns and tables that contain the
data. Object abstraction and the encapsulation of object behaviors also make
applications easier to understand and maintain.
Below are listed several other specific advantages that objects offer over a purely
relational approach.
Object Types
An object type is a kind of datatype. You can use it in the same ways that you use
more familiar datatypes such as NUMBER or VARCHAR2. For example, you can
specify an object type as the datatype of a column in a relational table, and you can
declare variables of an object type. You use a variable of an object type to contain a
value of that object type. A value of an object type is an instance of that type. An
object instance is also called an object. Example 1–1 shows how to create a
user-defined object type named person_typ.
Object types also have some important differences from the more familiar datatypes
that are native to a relational database:
■ A set of object types does not come ready-made with the database. Instead, you
define the specific object types you want by extending built-in types with
user-defined ones as shown in Example 1–1.
■ Object types are composed of parts, called attributes and methods.
– Attributes hold the data about an object's features of interest. For example,
a student object type might have name, major, and graduation date
attributes. An attribute has a declared datatype which can in turn be
another object type. Taken together, the attributes of an object instance
contain that object's data.
– Methods are procedures or functions provided to enable applications to
perform useful operations on the attributes of the object type. Methods are
an optional element of an object type. They define the behavior of objects of
that type and determine what (if anything) that type of object can do.
– Object types are less generic than native datatypes. In fact, this is one of
their major virtues. You can define object types to model the actual
structure of the real-world entities, such as customers and purchase orders,
that application programs deal with. This can make it easier and more
intuitive to manage the data for these entities. In this respect object types
are like Java and C++ classes.
You can think of an object type as a blueprint or template which defines structure
and behavior. An instantiation of the object type creates an object built according to
the template. Object types are database schema objects, subject to the same kinds of
administrative control as other schema objects.
You can use object types to model the actual structure of real-world objects. Object
types enable you to capture the structural interrelationships of objects and their
attributes instead of flattening this structure into a two-dimensional, purely
relational schema of tables and columns. With object types you can store related
pieces of data in a unit along with the behaviors defined for that data. Application
code can then retrieve and manipulate these units as objects.
Objects
When you create a variable of an object type, you create an instance of the type and
the result is an object. An object has the attributes and methods defined for its type.
Because an object instance is a concrete thing, you can assign values to its attributes
and call its methods.
You use the CREATE TYPE statement to define object types. In Example 1–1, the
CREATE TYPE statement define the object type person_typ.
The indented elements idno, name, and phone in the CREATE TYPE statements are
attributes. Each has a datatype declared for it. These are simplified examples and do
not show how to specify member methods.
Defining an object type does not allocate any storage. After they are defined, object
types can be used in SQL statements in most of the same places you can use types
like NUMBER or VARCHAR2.
For example, you might define a relational table to keep track of your contacts:
CREATE TABLE contacts (
contact person_typ,
contact_date DATE );
The contacts table is a relational table with an object type as the datatype of one
of its columns. Objects that occupy columns of relational tables are called column
objects.
Object Methods
Methods are functions or procedures that you can declare in an object type
definition to implement behavior that you want objects of that type to perform. For
example, a method is declared in Example 1–1 to allow comparisons between
person_typ objects.
The general kinds of methods that can be declared in a type definition are:
■ Member
■ Static
■ Constructor
A principal use of methods is to provide access to the data of an object. You can
define methods for operations that an application is likely to want to perform on the
data so that the application does not have to code these operations itself. To perform
the operation, an application calls the appropriate method on the appropriate
object.
For example, the following SQL statement uses the get_idno() method to display
the Id number of persons in the contacts table:
SELECT c.contact.get_idno() FROM contacts c;
You can also define static methods to compare object instances and to perform
operations that do not use any particular object's data but instead are global to an
object type.
A constructor method is implicitly defined for every object type, unless this default
constructor is over-written with a user-defined constructor. A constructor method is
called on a type to construct or create an object instance of the type.
Type Inheritance
Type inheritance adds to the usefulness of objects by enabling you to create type
hierarchies by defining successive levels of increasingly specialized subtypes that
derive from a common ancestor object type, which is called a supertype of the
derived types. Derived subtypes inherit the features of the parent object type but
extend the parent type definition. The specialized types can add new attributes or
methods, or redefine methods inherited from the parent. The resulting type
hierarchy provides a higher level of abstraction for managing the complexity of an
application model.
For example, specialized types of persons, such as a student type or a part-time
student type with additional attributes or methods, might be derived from a general
person object type. See "Inheritance in SQL Object Types" on page 2-15.
Type Evolution
Using an ALTER TYPE statement, you can modify, or evolve, an existing
user-defined type to make the following changes:
■ Add and drop attributes
■ Add and drop methods
■ Modify a numeric attribute to increase its length, precision, or scale
■ Modify a varying length character attribute to increase its length
■ Change a type's FINAL and INSTANTIABLE properties
Object Tables
An object table is a special kind of table in which each row represents an object. For
example, the following statement creates an object table for person_typ objects:
CREATE TABLE person_obj_table OF person_typ;
Object Views
An object view is a way to access relational data using object-relational features. It
lets you develop object-oriented applications without changing the underlying
relational schema.
Oracle allows the creation of an object abstraction over existing relational data
through the object view mechanism. You access objects that belong to an object view
in the same way that you access row objects in an object table. Oracle also supports
materialized view objects of user-defined types from data stored in relational
schemas and tables. By using object views, you can develop object-oriented
applications without having to modify existing relational database schemas.
Object views also let you exploit the polymorphism that a type hierarchy makes
possible. A polymorphic expression can take a value of the expression's declared
type or any of that type's subtypes. If you construct a hierarchy of object views that
mirrors some or all of the structure of a type hierarchy, you can query any view in
the hierarchy to access data at just the level of specialization you are interested in. If
you query an object view that has subviews, you can get back polymorphic
data—rows for both the type of the view and for its subtypes.
References
A REF is a logical pointer to a row object that is constructed from the object
identifier (OID) of the referenced object and is an Oracle built-in datatype. REFs and
collections of REFs model associations among objects, particularly many-to-one
relationships, thus reducing the need for foreign keys. REFs provide an easy
mechanism for navigating between objects. You can use the dot notation to follow
the pointers. Oracle does joins for you when needed, and in some cases can avoid
doing joins.
You can use a REF to examine or update the object it refers to. You can also use a
REF to obtain the object it refers to. You can change a REF so that it points to a
different object of the same object type hierarchy or assign it a null value.
The following example illustrates a simple use of a REF.
See Also:
■ "Rules for REF Columns and Attributes" on page 2-6
■ "Design Considerations for REFs" on page 8-8
Scoped REFs
In declaring a column type, collection element, or object type attribute to be a REF,
you can constrain it to contain only references to a specified object table. Such a REF
is called a scoped REF. Scoped REF types require less storage space and allow more
efficient access than unscoped REF types.
The following example shows REF column contact_ref scoped to person_obj_
table which is an object table of type person_typ.
CREATE TABLE contacts_ref (
contact_ref REF person_typ SCOPE IS person_obj_table,
contact_date DATE );
FROM person_obj_table p
WHERE p.idno = 1;
A REF can be scoped to an object table of the declared type (person_typ in the
example) or of any subtype of the declared type. If scoped to an object table of a
subtype, the REF column is effectively constrained to hold references only to
instances of the subtype (and its subtypes, if any) in the table.
Dangling REFs
It is possible for the object identified by a REF to become unavailable through either
deletion of the object or a revoking of privileges. Such a REF is called dangling.
Oracle SQL provides a predicate (called IS DANGLING) to allow testing REFs for
this condition.
Dangling REFs can be avoided by defining referential integrity constraints. See
"Rules for REF Columns and Attributes" on page 2-6.
Dereferencing REFs
Accessing the object referred to by a REF is called dereferencing the REF. Oracle
provides the DEREF operator to do this. Dereferencing a dangling REF returns a null
object. For example:
SELECT DEREF(c.contact_ref), c.contact_date FROM contacts_ref c;
Oracle also provides implicit dereferencing of REFs. For example, to access the
manager's name for an employee, you can use a SQL expression similar to the
following:
SELECT e.name, e.manager.name FROM emp_person_obj_table
WHERE e.name = 'Bob Jones';
In the example, e.manager.name follows the pointer from the person's manager,
and retrieves the manager's name. Following the REF like this is allowed in SQL,
but not in PL/SQL.
Obtaining REFs
You can obtain a REF to a row object by selecting the object from its object table and
applying the REF operator. For example, you can obtain a REF to the person with
identification number 1 as follows:
DECLARE
Collections
For modeling multi-valued attributes and many to many relationships, Oracle
supports two collection datatypes: varrays and nested tables. Collection types can
be used anywhere other datatypes can be used. You can have object attributes of a
collection type in addition to columns of a collection type. For example, you might
give a purchase order object type a nested table attribute to hold the collection of
line items for a given purchase order.
You use the CREATE TYPE statement to define collection types. In Example 1–3, the
CREATE TYPE statements define the object types people_typ and dept_
persons_typ.
External Procedures
Database functions, procedures, or member methods of an object type can be
implemented in PL/SQL, Java, or C as external procedures. External procedures are
best suited for tasks that are more quickly or easily done in a low-level language
such as C, which is more efficient at machine-precision calculation. External
procedures are always run in a safe mode outside the address space of the RDBMS
server. Generic external procedures can be written that declare one or more
parameters to be of a system-defined generic type. The generic type permits a
procedure that uses it to work with data of any built-in or user-defined type.
Client-Side Cache
Oracle provides an object cache for efficient access to persistent objects stored in the
database. Copies of objects can be brought into the object cache. Once the data has
been cached in the client, the application can traverse through these at memory
speed. Any changes made to objects in the cache can be committed to the database
by using the object extensions to Oracle® Call Interface programmatic interfaces.
See Also: "Oracle Call Interface (OCI)" on page 4-2 and "Oracle
C++ Call Interface (OCCI)" on page 4-8
Utility. Pro*C supports the use of C bind variables for Oracle object types.
Furthermore, Pro*C provides new simplified syntax to allocate and free objects of
SQL types and access them by either SQL DML, or through the navigational
interface. Thus, it provides application developers many benefits, including
compile-time type checking of (client-side) bind variables against the schema in the
server, automatic mapping of object data in an Oracle server to program bind
variables in the client, and simple ways to manage and manipulate database objects
in the client process.
This chapter provides basic information about working with objects. It explains
what object types, methods, and collections are and describes how to create and
work with a hierarchy of object types that are derived from a shared root type and
are connected by inheritance.
This chapter contains these topics:
■ SQL Object Types and References
■ Object Methods
■ Inheritance in SQL Object Types
■ Functions and Operators Useful with Objects
The statement
INSERT INTO contacts VALUES (
person_typ (NULL, NULL, NULL),
'24 Jun 2003' );
NULL,
'24 Jun 2003' );
In both cases, Oracle allocates space in contacts for a new row and sets its DATE
column to the value given. But in the first case, Oracle allocates space for an object
in the contact column and sets each of the object's attributes to NULL. In the
second case, Oracle sets the person_typ field itself to NULL and does not allocate
space for an object.
In some cases, you can omit checks for null values. A table row or row object cannot
be null. A nested table of objects cannot contain an element whose value is NULL.
A nested table or array can be null, so you do need to handle that condition. A null
collection is different from an empty one, that is, a collection containing no
elements.
For CHAR and VARCHAR2 attributes whose length is specified without a char
qualifier (for example, the phone attribute), the default unit of measure characters
or bytes is determined by whether the NLS_LENGTH_SEMANTICS initialization
parameter is set to CHAR or BYTE.
The department_mgrs table in the next example has a column whose type is the
object type location_typ defined in the previous example. The example defines
constraints on scalar attributes of the location_typ objects that appear in the
dept_loc column of the table.
CREATE TABLE department_mgrs (
dept_no NUMBER PRIMARY KEY,
dept_name CHAR(20),
dept_mgr person_typ,
dept_loc location_typ,
CONSTRAINT dept_loc_cons1
UNIQUE (dept_loc.building_no, dept_loc.city),
CONSTRAINT dept_loc_cons2
CHECK (dept_loc.city IS NOT NULL) );
Wherever Oracle expects a column name in an index definition, you can also specify
a scalar attribute of an object column.
Name Resolution
Oracle SQL lets you omit qualifying table names in some relational operations. For
example, if dept_addr is a column in the department_loc table and old_
office is a column in the movement table, you can write:
SELECT * FROM department_loc WHERE EXISTS
(SELECT * FROM movement WHERE dept_addr = old_office);
In some cases, object-relational features require you to specify the table aliases.
Object Methods
Methods are functions or procedures that you can declare in an object type
definition to implement behavior that you want objects of that type to perform. An
application calls the methods to invoke the behavior.
For example, you might declare a method get_sum() to get a purchase order
object to return the total cost of its line items. The following line of code calls such a
method for purchase order po and returns the amount into sum_line_items:
sum_line_items = po.get_sum();
In SQL, the parentheses are required for all method calls. Unlike with PL/SQL
functions and procedures, SQL requires parentheses for method calls that do not
have arguments.
Methods can be written in PL/SQL or virtually any other programming language.
Methods written in PL/SQL or Java are stored in the database. Methods written in
other languages, such as C, are stored externally.
The topics described in this section are:
■ Member Methods
■ Methods for Comparing Objects
■ Static Methods
■ Constructor Methods
■ External Implemented Methods
Member Methods
Member methods are the means by which an application gains access to an object
instance's data. You define a member method in the object type for each operation
that you want an object of that type to be able to perform. For example, the method
get_sum() that sums the total cost of a purchase order's line items operates on the
data of a particular purchase order and is a member method.
Member methods have a built-in parameter named SELF that denotes the object
instance on which the method is currently being invoked. Member methods can
reference the attributes and methods of SELF without a qualifier. This makes it
simpler to write member methods. For example, the following code shows a
method declaration that takes advantage of SELF to omit qualification of the
attributes num and den:
CREATE TYPE rational_typ AS OBJECT (
num INTEGER,
den INTEGER,
MEMBER PROCEDURE normalize_proc);
/
SELF does not need to be explicitly declared, although it can be. It is always the first
parameter passed to the method.
■ In member functions, if SELF is not declared, its parameter mode defaults to
IN.
■ In member procedures, if SELF is not declared, its parameter mode defaults to
IN OUT. The default behavior does not include the NOCOPY compiler hint.
You can invoke a member method using the dot notation object_
variable.method(). This notation specifies the object on which to invoke the
method, then the method to call. Any parameters must be placed inside the
required parentheses.
Map Methods
A map method is an optional kind of method that provides a basis for comparing
objects by mapping object instances to one of the scalar types DATE, NUMBER,
VARCHAR2 or to an ANSI SQL type such as CHARACTER or REAL. With a map
method, you can order any number of objects by calling each object's map method
once to map that object to a position on the axis used for the comparison, such as a
number or date. Example 1–1 on page 1-4 contains a simple map method.
From the standpoint of writing one, a map method is simply a parameter-less
member function that uses the MAP keyword and returns one of the datatypes just
listed. What makes a map method special is that, if an object type defines one, the
method is called automatically to evaluate such comparisons as obj_1 > obj_2
and comparisons implied by the DISTINCT, GROUP BY, UNION, and ORDER BY
clauses which require sorting by rows.
Where obj_1 and obj_2 are two object variables that can be compared using a
map method map(), the comparison:
obj_1 > obj_2
is equivalent to:
obj_1.map() > obj_2.map()
And similarly for other relational operators besides the greater than (>) operator.
The following example defines a map method area() that provides a basis for
comparing rectangle objects by their area:
CREATE TYPE rectangle_typ AS OBJECT (
len NUMBER,
wid NUMBER,
MAP MEMBER FUNCTION area RETURN NUMBER);
/
An object type can declare at most one map method or one order method. A
subtype can declare a map method only if its root supertype declares one.
See Also: "Equal and Not Equal Comparisons" on page 3-17 for
the use of map methods when comparing collections that contain
object types
Order Methods
Order methods make direct object-to-object comparisons. Unlike map methods,
they cannot map any number of objects to an external axis. They simply tell you
that the current object is less than, equal to, or greater than the other object that it is
being compared to, with respect to the criterion used by the method.
An order method is a function with one declared parameter for another object of the
same type. The method must be written to return either a negative number, zero, or
a positive number. The return signifies that the object picked out by the SELF
parameter is respectively less than, equal to, or greater than the other parameter's
object.
As with map methods, an order method, if one is defined, is called automatically
whenever two objects of that type need to be compared.
Order methods are useful where comparison semantics may be too complex to use a
map method. For example, to compare binary objects such as images, you might
create an order method to compare the images by their brightness or number of
pixels.
An object type can declare at most one order method or one map method. Only a
type that is not derived from another type can declare an order method; a subtype
cannot define one.
The following example shows an order method that compares locations by building
number:
CREATE TYPE location_typ AS OBJECT (
building_no NUMBER,
city VARCHAR2(40),
ORDER MEMBER FUNCTION match (l location_typ) RETURN INTEGER );
/
CREATE TYPE BODY location_typ AS
ORDER MEMBER FUNCTION match (l location_typ) RETURN INTEGER IS
BEGIN
IF building_no < l.building_no THEN
RETURN -1; -- any negative number will do
ELSIF building_no > l.building_no THEN
RETURN 1; -- any positive number will do
ELSE
RETURN 0;
END IF;
END;
END;
/
See Also:
■ "Inheritance in SQL Object Types" on page 2-15
■ "Inheriting, Overloading, and Overriding Methods" on
page 2-20
Static Methods
Static methods are invoked on the object type, not its instances. You use a static
method for operations that are global to the type and do not need to reference the
data of a particular object instance. A static method has no SELF parameter.
You invoke a static method by using the dot notation to qualify the method call
with the name of the object type, such as:
type_name.method()
Constructor Methods
Every object type has a constructor method implicitly defined for it by the system.
A constructor method is a function that returns a new instance of the user-defined
type and sets up the values of its attributes.
The system implicitly defines a constructor function called the attribute value
constructor for all object types that have attributes.
You can also define constructor functions of your own called user-defined
constructors to create and initialize objects of such types. Attribute value
constructors are convenient to use because they already exists, but user-defined
constructors have some important advantages with respect to type evolution.
The name of the constructor method is just the name of the object type, as shown in
the following simple example:
person_typ (1, 'John Smith', '1-800-555-1212'),
single supertype: it cannot derive jointly from more than one. A supertype can have
multiple sibling subtypes, but a subtype can have at most one direct parent
supertype. In other words, Oracle supports only single inheritance, not multiple
inheritance.
A subtype is derived from a supertype by defining a specialized variant of the
supertype. For example, from a person_typ object type you might derive the
specialized types student_typ and employee_typ. Each of these subtypes is still
at bottom a person_typ, but a special kind of person. What makes a subtype
special and distinguishes it from its parent supertype is some change made in the
subtype to the attributes or methods that the subtype received from its parent.
A
Supertype of all
B D
Subtype of A; Subtype of A;
supertype of C
C
Subtype of B
An object type's attributes and methods make the type what it is: they are its
essential, defining features. If a person_typ object type has the three attributes
idno, name, and phone and the method get_idno(), then any object type that is
derived from person_typ will have these same three attributes and a method
get_idno(). A subtype is a special case of its parent type, not a totally different
kind of thing. As such, it shares with its parent type the features that make the
general type what it is.
You can specialize the attributes or methods of a subtype in these ways:
■ Add new attributes that its parent supertype does not have.
For example, you might specialize student_typ as a special kind of person_
typ by adding to its definition an attribute for major. A subtype cannot drop
or change the type of an attribute it inherited from its parent; it can only add
new attributes.
■ Add entirely new methods that the parent does not have.
■ Change the implementation of some of the methods a subtype inherits from its
parent so that the subtype's version executes different code from the parent's.
For example, a shape object type might define a method calculate_area().
Two subtypes of shape, rectilinear_shape, and circular_shape, might
each implement this method in a different way. See "Inheriting, Overloading,
and Overriding Methods" on page 2-20.
Attributes and methods that a subtype gets from its parent type are said to be
inherited. This means more than just that the attributes and methods are patterned
on the parent's when the subtype is defined. With object types, the inheritance link
remains live. Any changes made later on to the parent type's attributes or methods
are also inherited so that the changes are reflected in the subtype as well. Unless a
subtype reimplements an inherited method, it always contains the same core set of
attributes and methods that are in the parent type, plus any attributes and methods
that it adds.
Remember, a child type is not a different type from its parent; it is a particular kind
of that type. If the general definition of person_typ ever changes, the definition of
student_typ changes also.
The inheritance relationship that holds between a supertype and its subtypes is the
source of both much of the power of objects and much of their complexity. It is a
very powerful feature to be able to change a method in a supertype and have the
change take effect in all the subtypes downstream just by recompiling. But this
same capability means that you have to think about such things as whether you
want to allow a type to be specialized or a method to be redefined. Similarly, it is a
powerful feature for a table or column to be able to contain any type in a hierarchy,
but then you must decide whether to allow this in a particular case, and you may
need to constrain DML statements and queries so that they pick out from the type
hierarchy just the range of types that you want. The following sections address
these aspects of working with objects.
idno NUMBER,
name VARCHAR2(30),
phone VARCHAR2(20))
NOT FINAL;
/
The preceding statement declares person_typ to be a not final type such that
subtypes of person_typ can be defined. By default, an object type is declared as
final and subtypes cannot be derived from it.
You can change a final type to a not final type and vice versa with an ALTER TYPE
statement. For example, the following statement changes person_typ to a final
type:
ALTER TYPE person_typ FINAL;
You can alter a type from NOT FINAL to FINAL only if the target type has no
subtypes.
Methods, too, can be declared to be final or not final. If a method is declared to be
final, subtypes cannot override it by providing their own implementation. Unlike
types, methods are not final by default and must be explicitly declared to be final.
The following statement creates a not final type containing a final member function:
CREATE TYPE person_typ AS OBJECT (
idno NUMBER,
name VARCHAR2(30),
phone VARCHAR2(20)
FINAL MAP MEMBER FUNCTION get_idno RETURN NUMBER)
NOT FINAL;
/
Creating Subtypes
You create a subtype using a CREATE TYPE statement that specifies the immediate
parent of the subtype with an UNDER parameter:
CREATE TYPE student_typ UNDER person_typ (
dept_id NUMBER,
major VARCHAR2(30))
NOT FINAL;
/
A subtype can be defined under another subtype. Again, the new subtype inherits
all the attributes and methods that its parent type has, both declared and inherited.
For example, the following statement defines a new subtype part_time_
student_typ under student_typ. The new subtype inherits all the attributes
and methods of student_typ and adds another attribute.
CREATE TYPE part_time_student_typ UNDER student_typ (
number_hours NUMBER);
/
A method can also be declared to be not instantiable. Use this option when you
want to declare a method in a type without implementing the method there. A type
that contains a non-instantiable method must itself be declared not instantiable. For
example:
You can alter an instantiable type to a non-instantiable type only if the type has no
columns, views, tables, or instances that reference that type, either directly, or
indirectly through another type or subtype.
You cannot declare a non-instantiable type to be FINAL, which would be pointless
anyway.
Giving a type multiple methods with the same name is called method overloading.
Redefining an inherited method to customize its behavior in a subtype is either
overriding, in the case of member methods, or hiding, in the case of static methods.
Overloading Methods
Overloading is useful when you want to provide a variety of ways of doing
something. For example, a shape object might overload a draw() method with
another draw() method that adds a text label to the drawing and contains an
argument for the label's text.
When a type has several methods with the same name, the compiler uses the
methods' signatures to tell them apart. A method's signature is a sort of structural
profile. It consists of the method's name and the number, types, and order of the
method's formal parameters (including the implicit self parameter). Methods that
have the same name but different signatures are called overloads (when they exist
in the same type).
In the following example, Subtype MySubType_typ creates an overload of
draw():
CREATE TYPE MyType_typ AS OBJECT (...,
MEMBER PROCEDURE draw(x NUMBER), ...) NOT FINAL;
Redefining Methods
Overriding and hiding redefine an inherited method to make it do something
different in the subtype. For example, a subtype circular_shape derived from a
shape supertype might override a member method calculate_area() to
customize it specifically for calculating the area of a circle.
Redefining a method is called overriding when the method that is redefined is a
member method; redefining is called hiding when the redefined method is a static
method. Overriding and hiding are similar in that, in either case, the version of the
method redefined in the subtype eclipses an inherited version of the same name
and signature such that the new version is executed instead of the inherited one
whenever an instance of the subtype invokes the method. If the subtype itself has
subtypes, these inherit the redefined method instead of the original version.
However, with overriding, the system relies on type information contained in the
member method s implicit self argument to dynamically choose the correct version
of the method to execute. With hiding, the correct version can be identified at
compile time, and dynamic dispatch is not necessary. See "Dynamic Method
Dispatch" on page 2-23.
It is possible that a supertype may contain overloads of a method that is redefined
in a subtype. Overloads of a method all have the same name, so the compiler uses
the signature of the subtype s method to identify the particular version in the
supertype that is superseded. This means that, to override or hide a method, you
must preserve its signature.
A subtype that overrides a member method must signal the override with the
OVERRIDING keyword in the type definition. No such special keyword is required
when a subtype hides a static method.
For example, in the following code, the subtype signals that it is overriding method
Print():
CREATE TYPE MyType_typ AS OBJECT (...,
MEMBER PROCEDURE Print(),
FINAL MEMBER FUNCTION function_mytype(x NUMBER)...
) NOT FINAL;
As with new methods, you supply the declaration for a method that hides or
overrides in a CREATE TYPE BODY statement.
Subtype of
circle_typ ellipse_type
Subtype of
sphere_typ circle_type
When such a method is invoked, the type of the object instance that invokes it is
used to determine which implementation of the method to use. The call is then
dispatched to that implementation for execution. This process of selecting a method
implementation is called virtual or dynamic method dispatch because it is done at
run time, not at compile time.
A method call is dispatched to the nearest implementation, working back up the
inheritance hierarchy from the current or specified type. If the call invokes a
member method of an object instance, the type of that instance is the current type,
and the implementation defined or inherited by that type is used. If the call invokes
a static method of a type, the implementation defined or inherited by that specified
type is used.
For example, if c1 is an object instance of circle_typ, c1.proc() looks first for
an implementation of proc() defined in circle_typ. If none is found, it looks up
the supertype chain for an implementation in ellipse_typ. The fact that
See Also:
■ "Turning Off Substitutability in a New Table" on page 2-29
■ "Constraining Substitutability" on page 2-30
A newly created subtype can be stored in any substitutable tables and columns of
its supertype, including tables and columns that existed before the subtype was
created.
Attributes in general can be accessed using the dot notation. Attributes of a subtype
of a row or column's declared type can be accessed with the TREAT function. For
example:
SELECT TREAT(contact AS student_typ).major FROM contacts;
However, columns of such types are not substitutable. Similarly, a subtype ST can
have a collection attribute whose element type is one of ST's supertypes, but, again,
columns of such types are not substitutable. For example, if student_typ had a
nested table or varray of person_typ, the student_typ column would not be
substitutable.
You can, however, define substitutable columns of subtypes that have REF
attributes that reference supertypes. For example, the composite_category_typ
subtype shown in Example 2–2 contains the subcategory_ref_list nested
table. This table contains subcategory_ref_list_typ which are REFs to
category_typ. The subtype was created as follows:
CREATE TYPE subcategory_ref_list_typ
AS TABLE OF REF category_typ;
/
Collection Elements
Collection elements are substitutable in both views and tables. For example, a
nested table of person_typ can contain object instances of person_typ or any of
its subtypes.
The following statement fails because student_typ has a supertype attribute, and
table person_obj_table has a substitutable column p of the supertype.
CREATE TYPE student_typ UNDER person_typ (
advisor person_typ);
/
To drop the type, first delete any of its instances in substitutable columns of the
supertype:
DELETE FROM person_obj_table WHERE p IS OF (student_typ);
office office_typ)
COLUMN office NOT SUBSTITUTABLE AT ALL LEVELS;
With object tables, the clause can be applied to the table as a whole, like this:
CREATE TABLE office_tab OF office_typ
NOT SUBSTITUTABLE AT ALL LEVELS;
You can specify that the element type of a collection is not substitutable using
syntax like the following:
CREATE TABLE people_tab (
people_column people_typ )
NESTED TABLE people_column
NOT SUBSTITUTABLE AT ALL LEVELS STORE AS people_column_nt;
Constraining Substitutability
You can impose a constraint that limits the range of subtypes permitted in an object
column or attribute to a particular subtype in the declared type's hierarchy. You do
this using an IS OF type constraint.
For example, the following statement creates a table of office_typ in which
occupants are constrained to just those persons who are employees:
CREATE TABLE office_tab OF office_typ
COLUMN occupant IS OF (ONLY employee_typ);
Modifying Substitutability
In an existing table, you can change an object column from SUBSTITUTABLE to NOT
SUBSTITUTABLE (or from NOT SUBSTITUTABLE to SUBSTITUTABLE) by using an
ALTER TABLE statement. To do so, you specify the clause [NOT] SUBSTITUTABLE
AT ALL LEVELS for the particular column.
You can modify substitutability only for a specific column; you cannot modify
substitutability for an object table as a whole.
The following statement makes column office substitutable:
ALTER TABLE dept_office
MODIFY COLUMN office SUBSTITUTABLE AT ALL LEVELS;
The following statement makes the column not substitutable. Notice that it also
uses the FORCE keyword. This keyword causes any hidden columns containing
typeid information or data for subtype attributes to be dropped:
ALTER TABLE dept_office
MODIFY COLUMN office NOT SUBSTITUTABLE AT ALL LEVELS FORCE;
If the FORCE keyword is not used when a column is made not substitutable, the
column and all attributes of the type must be FINAL or the ALTER TABLE statement
will fail.
A VARRAY column can be modified from SUBSTITUTABLE to NOT
SUBSTITUTABLE only if the element type of the varray is final itself and has no
embedded types (in its attributes or in their attributes, and so on) that are not final.
See "Hidden Columns for Substitutable Columns and Tables" on page 7-3 for more
information about hidden columns for typeids and subtype attributes.
The following assignments show widening. The assignments are valid unless
perscol has been defined to be not substitutable.
UPDATE T set pers_col = emp_col;
Collection Assignments
In assignments of expressions of a collection type, the source and target must be of
the same declared type. Neither widening nor narrowing is permitted. However, a
subtype value can be assigned to a supertype collection. For example, suppose we
have the following collection types:
CREATE TYPE person_set AS TABLE OF person_typ;
/
Expressions of these different collection types cannot be assigned to each other, but
a collection element of student_typ can be assigned to a collection of PersonSet
type:
DECLARE
var1 person_set;
var2 student_set;
elem1 person_typ;
elem2 student_typ;
begin
var1 := var2; /* ILLEGAL - collections not of same type */
var1 := person_set (elem1, elem2); /* LEGAL : Element is of subtype */
If a type does not define either a map method or an order method, object variables
of that type can be compared only in SQL statements and only for equality or
inequality. Two objects of the same type count as equal only if the values of their
corresponding attributes are equal.
CAST
CAST converts one built-in datatype or collection-typed value into another built-in
datatype or collection-typed value.
For example:
CREATE TYPE person_list_typ AS TABLE OF person_typ;
/
CURSOR
A CURSOR expression returns a nested cursor. This form of expression is equivalent
to the PL/SQL REF CURSOR and can be passed as a REF CURSOR argument to a
function.
DEREF
The DEREF function in a SQL statement returns the object instance corresponding to
a REF. The object instance returned by DEREF may be of the declared type of the
REF or any of its subtypes.
For example, the following statement returns person_typ objects from the table
contact_ref.
SELECT DEREF(c.contact_ref), c.contact_date
FROM contacts_ref c;
IS OF type
The IS OF type predicate tests object instances for the level of specialization of
their type.
For example, the following query retrieves all student instances (including any
subtypes of students) stored in the person_obj_table table.
SELECT VALUE(p)
FROM person_obj_table p
WHERE VALUE(p) IS OF (student_typ);
For any object that is not of a specified subtype, or a subtype of a specified subtype,
IS OF returns FALSE. Subtypes of a specified subtype are just more specialized
versions of the specified subtype. If you want to exclude such subtypes, you can use
the ONLY keyword. This keyword causes IS OF to return FALSE for all types except
the specified types.
In the following example, the statement tests objects in object table person_obj_
table, which contains persons, employees, and students, and returns REFs just to
objects of the two specified person subtypes employee_typ, student_typ, and
their subtypes, if any:
SELECT REF(p)
FROM person_obj_table p
WHERE VALUE(p) IS OF (employee_typ, student_typ);
Here is a similar example in PL/SQL. The code does something if the person is an
employee or student:
DECLARE
var person_t;
BEGIN
if var is of (employee_t, student_t) then
...
END;
The following statement returns only students whose most specific or specialized
type is student_typ. If the table or view contains any objects of a subtype of
student_typ, such as part_time_student_typ, these are excluded. The
example uses the TREAT function to convert objects that are students to student_
typ from the declared type of the view, person_typ:
SELECT TREAT(VALUE(p) AS student_typ)
FROM person_obj_table p
WHERE VALUE(p) IS OF(ONLY student_typ);
To test the type of the object that a REF points to, you can use the DEREF function to
dereference the REF before testing with the IS OF type predicate.
For example, if contact_ref is declared to be REF person_typ, you can get just
the rows for students as follows:
SELECT *
FROM contacts_ref
WHERE DEREF(contact_ref) IS OF (student_typ);
REF
The REF function in a SQL statement takes as an argument a correlation name for
an object table or view and returns a reference (a REF) to an object instance from
that table or view. The REF function may return references to objects of the declared
type of the table, view, or any of its subtypes. For example, the following statement
returns the references to all persons, including references to students and
employees, whose idno attribute is 12:
SELECT REF(p)
FROM person_obj_table p
WHERE p.idno = 12;
SYS_TYPEID
The SYS_TYPEID function can be used in a query to return the typeid of the most
specific type of the object instance passed to the function as an argument.
The most specific type of an object instance is the type to which the instance belongs
that is farthest removed from the root type. For example, if Tim is a part-time
student, he is also a student and a person, but his most specific type is part-time
student.
The function returns the typeids from the hidden type discriminant column that is
associated with every substitutable column. The function returns a null typeid for a
final, root type.
The syntax of the function is:
SYS_TYPEID( object_type_value )
Function SYS_TYPEID may be used only with arguments of an object type. Its
primary purpose is to make it possible to build an index on a hidden type
discriminant column.
All types that do belong to a type hierarchy are assigned a non-null typeid that is
unique within the type hierarchy. Types that do not belong to a type hierarchy have
a null typeid.
Every type except a final root type belongs to a type hierarchy. A final root type has
no types related to it by inheritance:
■ It cannot have subtypes derived from it because it is final
■ It is not itself derived from some other type because it is a root type, so it does
not have any supertypes.
TABLE()
Table functions are functions that produce a collection of rows, a nested table or a
varray, that can be queried like a physical database table or assigned to a PL/SQL
collection variable. You can use a table function like the name of a database table, in
the FROM clause of a query, or like a column name in the SELECT list of a query.
A table function can take a collection of rows as input. An input collection
parameter can be either a collection type, such as a VARRAY or a PL/SQL table, or a
REF CURSOR.
Use PIPELINED to instruct Oracle to return the results of a table function
iteratively. A table function returns a nested table or varray collection type. You
query table functions by using the TABLE keyword before the function name in the
FROM clause of the query.
TREAT
The TREAT function does a runtime check to confirm that an expression can be
operated on as if it were of a different specified type in the hierarchy normally, a
subtype of the expression s declared type. In other words, the function attempts to
In the next example, TREAT returns all (and only) student_typ instances from
person_obj_table of type person_typ, a supertype of student_typ. The
statement uses TREAT to modify the type of p from person_typ to student_typ.
SELECT TREAT(VALUE(p) AS student_typ)
FROM person_obj_table p;
For each p, the TREAT modification succeeds only if the most specific or specialized
type of the value of p is student_typ or one of its subtypes. If p is a person who is
not a student, or if p is NULL, TREAT returns NULL in SQL or, in PL/SQL, raises an
exception.
You can also use TREAT to modify the declared type of a REF expression. For
example:
SELECT TREAT(REF(p) AS REF student_typ)
FROM person_obj_table p;
The following query will not work because major is an attribute of student_typ
but not of person_typ, the declared type of table persons:
SELECT name, VALUE(p).major major
FROM person_obj_table p;
VALUE
In a SQL statement, the VALUE function takes as its argument a correlation variable
(table alias) for an object table or object view and returns object instances
corresponding to rows of the table or view. The VALUE function may return
instances of the declared type of the row or any of its subtypes. For example, the
following query returns all persons, including students and employees, from table
person_obj_table of person_typ:
SELECT VALUE(p) FROM person__obj_table p;
To retrieve only part time students, that is, instances whose most specific type is
part_time_student_typ, use the ONLY keyword to confine the selection:
SELECT VALUE(p) FROM person_obj_table p
WHERE VALUE(p) IS OF (ONLY part_time_student_typ);
The following example shows VALUE used to return object instance rows for
updating:
UPDATE TABLE(SELECT d.dept_emps FROM department_persons d
WHERE d.dept_no = 101) p
SET VALUE(p) = person_typ(2, 'Diane Smith', '1-800-555-1243')
WHERE p.idno = 2;
This chapter provides basic information about working with objects. It explains
what object types, methods, and collections are and describes how to create and
work with a hierarchy of object types that are derived from a shared root type and
are connected by inheritance.
This chapter contains these topics:
■ Creating Collection Datatypes
■ Operations on Collection Datatypes
See Also:
■ Oracle Database SQL Reference for information about nested
cursors
■ "Design Considerations for Nested Tables" on page 8-14 for
more information on using nested tables
The following examples show how it is used in SQL statements to insert values into
a nested table.
CREATE TABLE people_tab (
group_no NUMBER,
people_column people_typ )
NESTED TABLE people_column STORE AS people_column_nt;
When you declare a table column to be of an object type or collection type, you can
include a DEFAULT clause. This provides a value to use in cases where you do not
explicitly specify a value for the column. The default clause must contain a literal
invocation of the constructor method for that object or collection.
The following example shows how to use literal invocations of constructor methods
to specify defaults:
Note that the term people_typ() is a literal invocation of the constructor method
for an empty people_typ table.
Varrays
A varray is an ordered set of data elements. All elements of a given varray are of the
same datatype or a subtype of the declared one. Each element has an index, which
is a number corresponding to the element's position in the array. The index number
is used to access a specific element.
When you define a varray, you specify the maximum number of elements it can
contain, although you can change this number later. The number of elements in an
array is the size of the array. Oracle allows arrays to be of variable size, which is
why they are called varrays.
The VARRAYs of type email_list_arr have no more than ten elements, each of
datatype VARCHAR2(80).
Creating an array type, as with a SQL object type, does not allocate space. It defines
a datatype, which you can use as:
■ The datatype of a column of a relational table.
■ An object type attribute.
■ The type of a PL/SQL variable, parameter, or function return value.
A varray is normally stored in line, that is, in the same tablespace as the other data
in its row. If it is sufficiently large, Oracle stores it as a BLOB. See "Storage
Considerations for Varrays" on page 8-13.
You can create a VARRAY type of XMLType or of a LOB type for procedural
purposes, such as in PL/SQL or in view queries. However, database storage of a
varray of those types is not supported. This means that you cannot create an object
table or an object type column of a varray type of XMLType or of a LOB type.
Nested Tables
A nested table is an unordered set of data elements, all of the same datatype. No
maximum is specified in the definition of the table and the order of the elements is
not preserved. You select, insert, delete, and update in a nested table just as you do
with ordinary tables using the TABLE expression.
Elements of a nested table are actually stored in a separate storage table that
contains a column that identifies the parent table row or object to which each
element belongs. A nested table has a single column, and the type of that column is
a built-in type or an object type. If the column in a nested table is an object type, the
table can also be viewed as a multi-column table, with a column for each attribute
of the object type.
In Example 3–2 on page 3-5, the table type used for the nested tables is declared
with the CREATE TYPE ... IS TABLE OF statement. A table type definition does not
allocate space. It defines a type, which you can use as:
■ The datatype of a column of a relational table
■ An object type attribute
■ A PL/SQL variable, parameter, or function return type
When a column in a relational table is of nested table type, Oracle stores the nested
table data for all rows of the relational table in the same storage table. Similarly,
with an object table of a type that has a nested table attribute, Oracle stores nested
table data for all object instances in a single storage table associated with the object
table. In Example 3–2, the NESTED TABLE clause specifies the storage name for the
nested table. The example uses person_typ defined in Example 1–1 on page 1-4.
See Also: See Figure 8–2, "Nested Table Storage" on page 8-15
If the TABLESPACE clause is not specified, then the storage table of the nested table
is created in the tablespace where the parent table is created. For multilevel nested
tables, Oracle creates the child table in the same tablespace as its immediate
preceding parent table.
The user can issue ALTER TABLE MOVE statement to move a table to a different
tablespace. If the user issues ALTER TABLE MOVE statement on a table with nested
table columns, it only moves parent table, no action is taken on the nested table's
storage tables. If the user wants to move a nested table s storage table to a different
tablespace, issue ALTER TABLE MOVE on the storage table. For example:
ALTER TABLE people_tab MOVE TABLESPACE users;
Now the people_tab table is in users tablespace and nested table is stored in
the example tablespace.
Varray Storage
Multilevel varrays are stored in one of two ways, depending on whether the varray
is a varray of varrays or a varray of nested tables.
■ In a varray of varrays, the entire varray is stored inline in the row unless it is
larger than approximately 4000 bytes or LOB storage is explicitly specified.
■ In a varray of nested tables, the entire varray is stored in a LOB, with only the
LOB locator stored in the row. There is no storage table associated with nested
table elements of a varray. The entire nested table collection is stored inside the
varray.
You can explicitly specify LOB storage for varrays. The following example does this
for the varray elements of a nested table. As the example also shows, you can use
the COLUMN_VALUE keyword with varrays as well as nested tables.
CREATE TYPE email_list_arr AS VARRAY(10) OF VARCHAR2(80);
/
The following example shows explicit LOB storage specified for a varray of varray
type:
CREATE TYPE email_list_typ2 AS OBJECT (
section_no NUMBER,
emails email_list_arr);
/
When a VARRAY type is altered, changes are propagated to the dependent tables.
See "Propagating VARRAY Size Change" on page 8-13.
The preceding example can refer to the inner satellite nested table by name
because this nested table is a named attribute of an object. However, if the inner
nested table is not an attribute, it has no name. The keyword COLUMN_VALUE is
provided for this case; you use it in place of a name for an inner nested table. For
example:
CREATE TYPE inner_table AS TABLE OF NUMBER;
/
CREATE TYPE outer_table AS TABLE OF inner_table;
/
CREATE TABLE tab1 (
col1 NUMBER,
col2 outer_table)
NESTED TABLE col2 STORE AS col2_ntab
(NESTED TABLE COLUMN_VALUE STORE AS cv_ntab);
Physical attributes for the storage tables can be specified in the nested table clause.
For example:
CREATE TABLE stars (
name VARCHAR2(20),
age NUMBER,
planets nt_pl_t)
NESTED TABLE planets STORE AS planets_tab
the constructor for the satellites nested table type to create its nested table of
satellites; and the satellites nested table type constructor calls the satellite_t
constructor for each satellite instance to be created.
INSERT INTO stars
VALUES('Sun',23,
nt_pl_t(
planet_t(
'Neptune',
10,
nt_sat_t(
satellite_t('Proteus',67),
satellite_t('Triton',82)
)
),
planet_t(
'Jupiter',
189,
nt_sat_t(
satellite_t('Callisto',97),
satellite_t('Ganymede', 22)
)
)
)
);
Querying Collections
There are two general ways to query a table that contains a column or attribute of a
collection type. One way returns the collections nested in the result rows that
contain them. The other way distributes or unnests collections such that each
collection element appears on a row by itself.
nests the elements of the collection in the result row with which the collection is
associated.
For example, the following query retrieves the collection of employees. The
collection of employees is nested:
SELECT d.dept_emps
FROM department_persons d;
Results are also nested if an object-type column in the SELECT list contains a
collection attribute, even if that collection is not explicitly listed in the SELECT list
itself. For example, the query SELECT * FROM department_persons would
produce a nested result.
As the preceding example shows, a TABLE expression can have its own table alias.
In the example, a table alias for the TABLE expression appears in the SELECT list to
select columns returned by the TABLE expression.
The TABLE expression uses another table alias to specify the table that contains the
collection column that the TABLE expression references. The expression
TABLE(d.dept_emps) specifies the department_persons table as containing
the dept_emps collection column. A TABLE expression can use the table alias of
any table appearing to the left of it in a FROM clause to reference a column of that
table. This way of referencing collection columns is called left correlation.
In the example, the department_persons table is listed in the FROM clause solely
to provide a table alias for the TABLE expression to use. No columns from the
department_persons table other than the column referenced by the TABLE
expression appear in the result
The following example produces rows only for departments that have employees.
SELECT d.dept_no, e.*
FROM department_persons d, TABLE(d.dept_emps) e;
To get rows for departments that have no employees, you can use outer-join syntax:
SELECT d.dept_no, e.*
FROM department_persons d, TABLE(d.dept_emps) (+) e;
The (+) indicates that the dependent join between department_persons and
e.dept_emps should be NULL-augmented. That is, there will be rows of
department_persons in the output for which e.dept_emps is NULL or empty,
with NULL values for columns corresponding to e.dept_emps.
■ The subquery must return only a single collection; it cannot return collections
for multiple rows. For example, the subquery SELECT dept_emps FROM
department_persons succeeds in a TABLE expression only if table
department_persons contains just a single row. If the table contains more
than one row, the subquery produces an error.
Here is an example showing a TABLE expression used in the FROM clause of a
SELECT embedded in a CURSOR expression:
SELECT d.dept_no, CURSOR(SELECT * FROM TABLE(d.dept_emps))
FROM department_persons d
WHERE d.dept_no = 101;
Because no columns of the base table stars appear in the SELECT list, the query is
optimized to run directly against the satellites storage table.
Outer-join syntax can also be used with queries of multilevel collections.
Oracle does not support piecewise updates on VARRAY columns. However, VARRAY
columns can be inserted into or updated as an atomic unit.
For piecewise updates of nested table columns, the DML statement identifies the
nested table value to be operated on by using the TABLE expression.
The following DML statements demonstrate piecewise operations on nested table
columns.
INSERT INTO TABLE(SELECT d.dept_emps
FROM department_persons d
WHERE d.dept_no = 101)
VALUES (5, 'Kevin Taylor', '1-800-555-6212');
Collections as Atomic Data Items The section "Constructors for Multilevel Collections"
on page 3-11 shows an example of inserting an entire multilevel collection with an
INSERT statement. Multilevel collections can also be updated atomically with an
UPDATE statement. For example, suppose v_planets is a variable declared to be of
the planets nested table type nt_pl_t. The following statement updates stars by
setting the planets collection as a unit to the value of v_planets.
UPDATE stars s
SET s.planets = :v_planets
WHERE s.name = 'Aurora Borealis';
The following example shows a piecewise insert operation on the planets nested
table of nested tables: the example inserts a new planet, complete with its own
nested table of satellite_t:
INSERT INTO TABLE( SELECT planets FROM stars WHERE name = 'Sun')
VALUES ('Saturn', 56,
nt_sat_t(
satellite_t('Rhea', 83)
)
);
The next example performs a piecewise insert into an inner nested table to add a
satellite for a planet. Like the preceding, this example uses a TABLE expression
containing a subquery that selects the inner nested table to specify the target for the
insert.
INSERT INTO TABLE( SELECT p.satellites
FROM TABLE( SELECT s.planets
FROM stars s
WHERE s.name = 'Sun') p
WHERE p.name = 'Uranus')
VALUES ('Miranda', 31);
Comparisons of Collections
The conditions listed in this section allow comparisons of nested tables. There is no
mechanism for comparing varrays. The SQL examples in this section use the nested
tables created in Example 3–2 on page 3-5.
In this example, the nested tables contain person_typ objects which have an
associated map method. See Example 1–1 on page 1-4.
In Comparisons
The IN condition checks whether a nested table is in a list of nested tables,
returning the result as a Boolean value. NULL is returned if the nested table is a null
nested table.
For example:
SELECT p.idno, p.name
FROM students, TABLE(physics_majors) p
WHERE physics_majors IN (math_majors, chem_majors);
Empty Comparison
The IS [NOT] EMPTY condition checks whether a given nested table is empty or not
empty, regardless of whether any of the elements are NULL. If a NULL is given for
the nested table, the result is NULL. The result is returned as a Boolean value.
SELECT p.idno, p.name
FROM students, TABLE(physics_majors) p
WHERE physics_majors IS NOT EMPTY;
Set Comparison
The IS [NOT] A SET condition checks whether a given nested table is composed of
unique elements, returning a Boolean value.
For example:
SELECT p.idno, p.name
FROM students, TABLE(physics_majors) p
WHERE physics_majors IS A SET;
Multisets Operations
This section describes multiset operations with nested tables. The SQL examples in
this section use the nested tables created in Example 3–2 on page 3-5.
See Also:
■ Oracle Database SQL Reference for information about using
operators with nested tables
■ "Comparisons of Objects, REF Variables, and Collections" on
page 2-34
CARDINALITY
The CARDINALITY function returns the number of elements in a varray or nested
table. The return type is NUMBER. If the varray or nested table is a null collection,
NULL is returned.
For example:
SELECT CARDINALITY(math_majors)
FROM students;
COLLECT
The COLLECT function is an aggregate function which would create a multiset from
a set of elements. The function would take a column of the element type as input
and create a multiset from rows selected. To get the results of this function you must
use it within a CAST function to specify the output type of COLLECT.
See Also:
■ "CAST" on page 2-35 for an example of the COLLECT function
■ Oracle Database SQL Reference for syntax of the COLLECT
function
MULTISET EXCEPT
The MULTISET EXCEPT operator inputs two nested tables and returns a nested
table whose elements are in the first nested table but not in the second nested table.
The input nested tables and the output nested table are all type name equivalent.
The ALL or DISTINCT options can be used with the operator. The default is ALL.
■ With the ALL option, for ntab1 MULTISET EXCEPT ALL ntab2, all elements in
ntab1 other than those in ntab2 would be part of the result. If a particular
element occurs m times in ntab1 and n times in ntab2, the result will have (m -
n) occurrences of the element if m is greater than n otherwise 0 occurrences of
the element.
■ With the DISTINCT option, any element that is present in ntab1 which is also
present in ntab2 would be eliminated, irrespective of the number of
occurrences.
For example:
SELECT math_majors MULTISET EXCEPT physics_majors
FROM students
WHERE graduation = '01-JUN-03';
MULTISET INTERSECTION
The MULTISET INTERSECT operator returns a nested table whose values are
common in the two input nested tables. The input nested tables and the output
nested table are all type name equivalent.
There are two options associated with the operator: ALL or DISTINCT. The default
is ALL. With the ALL option, if a particular value occurs m times in ntab1 and n
times in ntab2, the result would contain the element MIN(m, n) times. With the
DISTINCT option the duplicates from the result would be eliminated, including
duplicates of NULL values if they exist.
For example:
SELECT math_majors MULTISET INTERSECT physics_majors
FROM students
WHERE graduation = '01-JUN-03';
MULTISET UNION
The MULTISET UNION operator returns a nested table whose values are those of the
two input nested tables. The input nested tables and the output nested table are all
type name equivalent.
There are two options associated with the operator: ALL or DISTINCT. The default
is ALL. With the ALL option, all elements that are in ntab1 and ntab2 would be
part of the result, including all copies of NULLs. If a particular element occurs m
times in ntab1 and n times in ntab2, the result would contain the element (m + n)
times. With the DISTINCT option the duplicates from the result are eliminated,
including duplicates of NULL values if they exist.
For example:
SELECT math_majors MULTISET UNION DISTINCT physics_majors
FROM students
WHERE graduation = '01-JUN-03';
POWERMULTISET
The POWERMULTISET function generates all non-empty submultisets from a given
multiset. The input to the POWERMULTISET function could be any expression which
evaluates to a multiset. The limit on the cardinality of the multiset argument is 32.
For example:
SELECT * FROM TABLE(POWERMULTISET( people_typ (
person_typ(12, 'Bob Jones', '1-800-555-1212'),
person_typ(31, 'Sarah Chen', '1-800-555-2212'),
person_typ(45, 'Chris Woods', '1-800-555-1213'))));
POWERMULTISET_BY_CARDINALITY
The POWERMULTISET_BY_CARDINALITY function returns all non-empty
submultisets of a nested table of the specified cardinality. The output would be rows
of nested tables.
POWERMULTISET_BY_CARDINALITY(x, l) is equivalent to
TABLE(POWERMULTISET(x)) p where CARDINALITY(value(p)) = l, where x
is a multiset and l is the specified cardinality.
The first input parameter to the POWERMULTISET_BY_CARDINALITY could be any
expression which evaluates to a nested table. The length parameter should be a
positive integer, otherwise an error will be returned. The limit on the cardinality of
the nested table argument is 32.
For example:
SELECT * FROM TABLE(POWERMULTISET_BY_CARDINALITY( people_typ (
person_typ(12, 'Bob Jones', '1-800-555-1212'),
person_typ(31, 'Sarah Chen', '1-800-555-2212'),
person_typ(45, 'Chris Woods', '1-800-555-1213')),2));
SET
The SET function converts a nested table into a set by eliminating duplicates, and
returns a nested table whose elements are DISTINCT from one another. The nested
table returned is of the same named type as the input nested table.
For example:
SELECT SET(physics_majors)
FROM students
WHERE graduation = '01-JUN-03';
In Oracle you can create object types with SQL data definition language (DDL)
commands, and you can manipulate objects with SQL data manipulation language
(DML) commands. Object support is built into Oracle application programming
environments.
This chapter discusses the following topics:
■ SQL
■ PL/SQL
■ Oracle Call Interface (OCI)
■ Pro*C/C++
■ Oracle C++ Call Interface (OCCI)
■ Oracle Objects For OLE (OO4O)
■ Java: JDBC, Oracle SQLJ, JPublisher, and SQLJ Object Types
■ XML
SQL
Oracle SQL DDL provides the following support for object types:
■ Defining object types, nested tables, and arrays
■ Specifying privileges
■ Specifying table columns of user-defined types
■ Creating object tables
Oracle SQL DML provides the following support for object types:
■ Querying and updating objects and collections
■ Manipulating REFs
PL/SQL
Object types and subtypes can be used in PL/SQL procedures and functions in
most places where built-in types can appear.
The parameters and variables of PL/SQL functions and procedures can be of object
types.
You can implement the methods associated with object types in PL/SQL. These
methods (functions and procedures) reside on the server as part of a user's schema.
The object cache is completely under the control and management of the application
programs using it. The Oracle server has no access to it. The application programs
using it must maintain data coherency with the server and protect the workspace
against simultaneous conflicting access.
OCI provides functions to
■ Access objects on the server using SQL.
■ Access, manipulate and manage objects in the object cache by traversing
pointers or REFs.
■ Convert Oracle dates, strings and numbers to C data types.
■ Manage the size of the object cache's memory.
OCI improves concurrency by allowing individual objects to be locked. It improves
performance by supporting complex object retrieval.
OCI developers can use the object type translator to generate the C datatypes
corresponding to a Oracle object types.
Object Cache
To support high-performance navigational access of objects, OCI runtime provides
an object cache for caching objects in memory. The object cache supports references
(REFs) to database objects in the object cache, the database objects can be identified
(that is, pinned) through their references. Applications do not need to allocate or
free memory when database objects are loaded into the cache, because the object
cache provides transparent and efficient memory management for database objects.
Also, when database objects are loaded into the cache, they are transparently
mapped into the host language representation. For example, in the C programming
language, the database object is mapped to its corresponding C structure. The object
cache maintains the association between the object copy in the cache and the
corresponding database object. Upon transaction commit, changes made to the
object copy in the cache are propagated automatically to the database.
The object cache maintains a fast look-up table for mapping REFs to objects. When
an application de-references a REF and the corresponding object is not yet cached in
the object cache, the object cache automatically sends a request to the server to fetch
the object from the database and load it into the object cache. Subsequent
de-references of the same REF are faster because they become local cache access and
do not incur network round-trips. To notify the object cache that an application is
accessing an object in the cache, the application pins the object; when it is finished
with the object, it unpins it. The object cache maintains a pin count for each object in
the cache. The count is incremented upon a pin call and decremented upon an
unpin call. When the pin count goes to zero, it means the object is no longer needed
by the application. The object cache uses a least-recently used (LRU) algorithm to
manage the size of the cache. When the cache reaches the maximum size, the LRU
algorithm frees candidate objects with a pin count of zero.
See Also: Oracle Call Interface Programmer's Guide for tips and
techniques for using OCI program effectively with objects
The SELF parameter is mapped like an IN parameter, so in the case of a NOT FINAL
type, it is mapped to (dvoid *), not (dvoid **).
The return value's TDO must match the TDO of SELF and is therefore implicit. The
return value can never be null, so the return indicator is implicit as well.
Pro*C/C++
The Oracle Pro*C/C++ precompiler allows programmers to use user-defined
datatypes in C and C++ programs.
Pro*C developers can use the Object Type Translator to map Oracle object types and
collections into C datatypes to be used in the Pro*C application.
Pro*C provides compile time type checking of object types and collections and
automatic type conversion from database types to C datatypes.
Pro*C includes an EXEC SQL syntax to create and destroy objects and offers two
ways to access objects in the server:
■ Support for flushing changes made in the object cache to the server with an
embedded SQL OBJECT FLUSH statement
See Also: For complete information about OTT, see Oracle Call
Interface Programmer's Guide and Pro*C/C++ Programmer's Guide.
The OCCI interface is modeled on the JDBC interface and, like the JDBC interface, is
easy to use. OCCI itself is built on top of OCI and provides the power and
performance of OCI using an object-oriented paradigm.
OCI is a C API to the Oracle database. It supports the entire Oracle feature set and
provides efficient access to both relational and object data, but it can be challenging
to use—particularly if you want to work with complex, object datatypes. Object
types are not natively supported in C, and simulating them in C is not easy. OCCI
addresses this by providing a simpler, object-oriented interface to the functionality
of OCI. It does this by defining a set of wrappers for OCI. By working with these
higher-level abstractions, developers can avail themselves of the underlying power
of OCI to manipulate objects in the server through an object-oriented interface that
is significantly easier to program.
The Oracle C++ Call Interface, OCCI, can be roughly divided into three sets of
functionalities, namely:
■ Associative relational access
■ Associative object access
■ Navigational access
With the OCCI navigational interface, you can retrieve an object and navigate
through references from that object to other objects. Server objects are materialized
as C++ class instances in the application cache.
An application can use OCCI object navigational calls to perform the following
functions on the server's objects:
■ Create, access, lock, delete, and flush objects
■ Get references to the objects and navigate through them
Figure 4–1 illustrates the containment hierarchy for value instances of all types in
OO4O.
OraObject OraAttribute
OraBLOB
OraCLOB
OraBFILE
Instances of these types can be fetched from the database or passed as input or
output variables to SQL statements and PL/SQL blocks, including stored
procedures and functions. All instances are mapped to COM Automation Interfaces
that provide methods for dynamic attribute access and manipulation. These
interfaces may be obtained from:
■ The value property of an OraField object in a Dynaset
■ The value property of an OraParameter object used as an input or an output
parameter in SQL Statements or PL/SQL blocks
■ An attribute of an object (REF)
■ An element in a collection (varray or a nested table)
See Also: Oracle Call Interface Programmer's Guide for tips and
techniques for using OCI program effectively with objects
JDBC and Oracle SQLJ. These interfaces enable you both to access SQL data from
Java and to provide persistent database storage for Java objects.
For an example of using Java APIs with Oracle objects, see the Oracle by Example
Series available on the Oracle Technology Network (OTN) Web site.
You can use the followings steps to navigate to the Oracle by Example Series.
■ Go to http://otn.oracle.com
■ Select Oracle Database under Products from the menu on the left side of the
page
■ Select Oracle9i Database Release 1 under Previous Releases on the right side
of the page
■ Under Technical Information, select Oracle9i by Example Series
■ Select Build Application Components from the menu on the left side of the
page
■ Select the Using Objects to Build an Online Product Catalog example
You can also search for Using Objects to Build an Online Product Catalog on the
OTN Web site.
■ Manually specify the mappings between Oracle objects and Java classes; that is,
customize your Java classes for object data. The driver then populates the
customized Java classes that you specify, which imposes a set of constraints on
the Java classes. To satisfy these constraints, you can choose to define your
classes according to either the SQLData interface or the ORAData interface.
See Also: For complete information about JDBC, see the Oracle
Database JDBC Developer's Guide and Reference.
See Also: For complete information about SQLJ, see the Oracle
Database Java Developer's Guide.
Using JPublisher to Create Java Classes for JDBC and SQLJ Programs
Oracle lets you map Oracle object types, reference types, and collection types to
Java classes and preserve all the benefits of strong typing. You can:
■ Use JPublisher to automatically generate custom Java classes and use those
classes without any change.
■ Subclass the classes produced by JPublisher to create your own specialized Java
classes.
■ Manually code custom Java classes without using JPublisher if the classes meet
the requirements stated in the Oracle Database JPublisher User's Guide.
We recommend that you use JPublisher and subclass when the generated classes do
not do everything you need.
See Also: The Oracle Database JPublisher User's Guide for more
information about using JPublisher.
SQLJ types use the corresponding Java class as the body of the type; you do not
specify a type body in SQL to contain implementations of the type's methods as you
do with ordinary object types.
Constraints
For SQLJ types having a SQL representation, the same constraints can be defined as
for ordinary object types.
Constraints are defined on tables, not on types, and are defined at the column level.
The following constraints are supported for SQLJ types having a SQL
representation:
■ Unique constraints
■ Primary Key
■ Check constraints
■ NOT NULL constraints on attributes
■ Referential constraints
The IS OF TYPE constraint on column substitutability is supported, too, for SQLJ
types having a SQL representation.
A column of a SQLJ type can be set to NULL or to another column using the same
syntax as for ordinary object types. For example, the following statement assigns
column d to column c:
UPDATE employee_reltab SET c=d ;
AS LANGUAGE JAVA
NAME 'pkg1.J_Person.J_Person(java.lang.String, int) return J_Person'
);
XML
XMLType views wrap existing relational and object-relational data in XML formats.
These views are similar to object views. Each row of an XMLType view corresponds
to an XMLType instance. The object identifier for uniquely identifying each row in
the view can be created using an expression such as extract() on the XMLType
value.
This chapter shows how to write object-oriented applications without changing the
underlying structure of your relational data.
The chapter contains these topics:
■ Why Use Object Views
■ Defining Object Views
■ Using Object Views in Applications
■ Nesting Objects in Object Views
■ Identifying Null Objects in Object Views
■ Using Nested Tables and Varrays in Object Views
■ Specifying Object Identifiers for Object Views
■ Creating References to View Objects
■ Modelling Inverse Relationships with Object Views
■ Updating Object Views
■ Applying the Object Model to Remote Tables
■ Defining Complex Relationships in Object Views
■ Object View Hierarchies
See Also:
■ Oracle Database SQL Reference for a complete description of SQL
syntax and usage.
■ PL/SQL User's Guide and Reference for a complete discussion of
PL/SQL capabilities
■ Oracle Database Java Developer's Guide for a complete discussion
of Java.
■ Oracle Call Interface Programmer's Guide for a complete
discussion of those facilities.
To access the data from the empnum column of the relational table, you would
access the empno attribute of the object type.
See Also: See Oracle Call Interface Programmer's Guide for more
information about OCI calls.
process of creating the object view. If column objects of the attribute type already
exist in a relational table, you can simply select them; otherwise, you must
synthesize the object instances from underlying relational data just as you
synthesize the principal object instances of the view. You synthesize, or create, these
objects by calling the respective object type's constructor method to create the object
instances, and you populate their attributes with data from relational columns that
you specify in the constructor.
For example, consider the department table dept:
CREATE TABLE dept (
deptno NUMBER PRIMARY KEY,
deptname VARCHAR2(20),
deptstreet VARCHAR2(20),
deptcity VARCHAR2(10),
deptstate CHAR(2),
deptzip VARCHAR2(10));
You might want to create an object view where the addresses are objects inside the
department objects. That would allow you to define reusable methods for address
objects, and use them for all kinds of addresses.
1. Create the type for the address object:
CREATE TYPE address_t AS OBJECT (
street VARCHAR2(20),
city VARCHAR2(10),
state CHAR(2),
zip VARCHAR2(10));
/
2. Create the type for the department object:
CREATE TYPE dept_t AS OBJECT (
deptno NUMBER,
deptname VARCHAR2(20),
address address_t );
/
3. Create the view containing the department number, name and address. The
address objects are constructed from columns of the relational table.
CREATE VIEW dept_view OF dept_t WITH OBJECT IDENTIFIER (deptno) AS
SELECT d.deptno, d.deptname,
address_t(d.deptstreet,d.deptcity,d.deptstate,d.deptzip) AS
deptaddr
FROM dept d;
Using this relational table, we can construct a dept_view with the department
number, name, address and a collection of employees belonging to the department.
1. Define a nested table type for the employee type employee_t:
The SELECT subquery inside the CAST-MULTISET block selects the list of
employees that belong to the current department. The MULTISET keyword
indicates that this is a list as opposed to a singleton value. The CAST operator casts
the result set into the appropriate type, in this case to the employee_list_t
nested table type.
A query on this view could give us the list of departments, with each department
row containing the department number, name, the address object and a collection of
employees belonging to the department.
respective table columns. In addition, the employee type has a nested table
(attribute) of projects, and the department type has a nested table (attribute) of
employees. The latter nested table is a multilevel collection. The CAST-MULTISET
operator is used in the CREATE VIEW statement to build the collections.
These are the underlying relational tables:
CREATE TABLE depts
( deptno NUMBER,
deptname VARCHAR2(20));
These are the object and collection types the view will use:
CREATE TYPE project_t AS OBJECT
( projname VARCHAR2(20),
mgr VARCHAR2(20));
/
CREATE TYPE nt_project_t AS TABLE OF project_t;
/
CREATE TYPE emp_t AS OBJECT
( ename VARCHAR2(20),
salary NUMBER,
deptname VARCHAR2(20),
projects nt_project_t );
/
CREATE TYPE nt_emp_t AS TABLE OF emp_t;
/
CREATE TYPE depts_t AS OBJECT
( deptno NUMBER,
deptname VARCHAR2(20),
emps nt_emp_t );
/
The following statement creates the object view:
CREATE VIEW v_depts OF depts_t WITH OBJECT IDENTIFIER (deptno) AS
SELECT d.deptno, d.deptname,
CAST(MULTISET(SELECT e.ename, e.salary, e.deptname,
The deptref column in the view holds the department reference. We write the
following simple query to determine all employees whose department is located in
the city of San Francisco:
SELECT e.eno, e.salary, e.deptref.deptno
FROM emp_view e
WHERE e.deptref.address.city = 'San Francisco';
Note that we could also have used the REF modifier to get the reference to the dept_
view objects:
CREATE OR REPLACE VIEW emp_view OF emp_t WITH OBJECT IDENTIFIER(empno)
AS SELECT e.empno, e.empname, e.salary, REF(d)
FROM emp e, dept_view d
WHERE e.deptno = d.deptno;
In this case we join the dept_view and the emp table on the deptno key. The
advantage of using MAKE_REF operator instead of the REF modifier is that in using
the former, we can create circular references. For example, we can create employee
view to have a reference to the department in which she works, and the department
view can have a list of references to the employees who work in that department.
Note that if the object view has a primary key based object identifier, the reference
to such a view is primary key based. On the other hand, a reference to a view with
system generated object identifier will be a system generated object reference. This
difference is only relevant when you create object instances in the OCI object cache
and need to get the reference to the newly created objects. This is explained in a
later section.
As with synthesized objects, we can also select persistently stored references as
view columns and use them seamlessly in queries. However, the object references to
view objects cannot be stored persistently.
One-to-One Relationships
One-to-one relationships can be modeled with inverse object references. For
example, let us say that each employee has a particular computer on her desk, and
that the computer belongs to that employee only. A relational model would capture
this using foreign keys either from the computer table to the employee table, or in
the reverse direction. Using views, we can model the objects so that we have an
object reference from the employee to the computer object and also have a reference
from the computer object to the employee.
relation (from employee to department) and the inverse relation (department to list
of employees). The department view can also have a collection of references to
employee objects instead of embedding the employee objects.
Something you want to be careful of: In an object view hierarchy, UPDATE and
DELETE statements operate polymorphically just as SELECT statements do: the set
of rows picked out by an UPDATE or DELETE statement on a view implicitly
includes qualifying rows in any subviews of the specified view as well. See "Object
View Hierarchies" on page 5-19 for a discussion of object view hierarchy and
examples defining Student_v and Employee_v.
For example, the following statement, which deletes all persons from Person_v,
also deletes all students from Student_v and all employees from the Employee_v
view.
DELETE FROM Person_v;
To exclude subviews and restrict the affected rows just to those in the view actually
specified, use the ONLY keyword. For example, the following statement updates
only persons and not employees or students.
UPDATE ONLY(Person_v) SET address = ...
This view has the list of all employees for each department. We use UNION ALL
because we cannot have two employees working in more than one department.
To create object views, we need object types that map to columns from the relational
tables:
Next, we create the department view, which includes references to the employee
objects.
CREATE VIEW dept_view OF dept_t WITH OBJECT IDENTIFIER(dno)
AS SELECT d.deptno, d.deptname,
address_t(d.deptstreet,d.deptcity,d.deptstate,d.deptzip),
CAST( MULTISET (
SELECT MAKE_REF(emp_view, e.empno)
FROM emp e
WHERE e.deptno = d.deptno)
AS employee_list_ref_t)
FROM dept d;
Next, we create a department view that includes references to the employee objects.
We do not have to use the FORCE keyword here, because emp_view already exists.
CREATE OR REPLACE VIEW dept_view OF dept_t WITH OBJECT IDENTIFIER(dno)
AS SELECT d.deptno, d.deptname,
address_t(d.deptstreet,d.deptcity,d.deptstate,d.deptzip),
CAST( MULTISET (
SELECT MAKE_REF(emp_view, e.empno)
FROM emp e
WHERE e.deptno = d.deptno)
AS employee_list_ref_t)
FROM dept d;
This allows us to query the department view, getting the employee object by
de-referencing the employee reference from the nested table empreflist:
SELECT DEREF(e.COLUMN_VALUE)
FROM TABLE( SELECT e.empreflist FROM dept_view e WHERE e.dno = 100) e;
COLUMN_VALUE is a special name that represents the scalar value in a scalar nested
table. In this case, COLUMN_VALUE denotes the reference to the employee objects in
the nested table empreflist.
We can also access only the employee number of all those employees whose name
begins with John.
SELECT e.COLUMN_VALUE.eno
FROM TABLE(SELECT e.empreflist FROM dept_view e WHERE e.dno = 100) e
WHERE e.COLUMN_VALUE.ename like 'John%';
To get a tabular output, unnest the list of references by joining the department table
with the items in its nested table:
SELECT d.dno, e.COLUMN_VALUE.eno, e.COLUMN_VALUE.ename
FROM dept_view d, TABLE(d.empreflist) e
WHERE e.COLUMN_VALUE.ename like 'John%'
AND d.dno = 100;
Finally, we can rewrite the preceding query to use the emp_view instead of the
dept_view to show how you can navigate from one view to the other:
SELECT e.deptref.dno, DEREF(f.COLUMN_VALUE)
FROM emp_view e, TABLE(e.deptref.empreflist) f
WHERE e.deptref.dno = 100
AND f.COLUMN_VALUE.ename like 'John%';
Person_typ
Student_typ Employee_typ
ParTimeStudent_typ
If you have created an object view hierarchy based on this type hierarchy, with an
object view built on each type, you can query the object view that corresponds to
the level of specialization you are interested in. For instance, you can query the
view of student_typ to get a result set that contains only students, including
part-time students.
You can base the root view of an object view hierarchy on any type in a type
hierarchy: you do not need to start the object view hierarchy at the root type. Nor
do you need to extend an object view hierarchy to every leaf of a type hierarchy or
cover every branch. However, you cannot skip intervening subtypes in the line of
descent. Any subview must be based on a direct subtype of the type of its direct
superview.
Just as a type can have multiple sibling subtypes, an object view can have multiple
sibling subviews. But a subview based on a given type can participate in only one
object view hierarchy: two different object view hierarchies cannot each have a
subview based on the same subtype.
A subview inherits the object identifier (OID) from its superview. An OID cannot be
explicitly specified in any subview.
A root view can explicitly specify an object identifier using the WITH OBJECT ID
clause. If the OID is system-generated or the clause is not specified in the root view,
then subviews can be created only if the root view is based on a table or view that
also uses a system generated OID.
The query underlying a view determines whether the view is updatable. For a view
to be updatable, its query must contain no joins, set operators, aggregate functions,
GROUP BY, DISTINCT, pseudocolumns, or expressions. The same applies to
subviews.
The same object view hierarchy can be based on different underlying storage
models. In other words, a variety of layouts or designs of underlying tables can
produce the same object view hierarchy. The design of the underlying storage
model has implications for the performance and updatability of the object view
hierarchy.
The following examples show three possible storage models. In the first, a flat
model, all views in the object view hierarchy are based on the same table. In the
second, a horizontal model, each view has a one-to-one correspondence with a
different table. And in the third, a vertical model, the views are constructed using
joins.
Table AllPersons
TYPEID Person attributes (columns) Student attributes Employee attributes
1, 2, or 3
View Person_v
Person attributes
View Student_v
View Employee_v
The typeid column identifies the type of each row. Possible values are:
1 = person_typ
2 = student_typ
3 = employee_typ
The following statements create the views that make up the object view hierarchy:
CREATE VIEW Person_v OF person_typ
WITH OBJECT OID(ssn) AS
SELECT ssn, name, address
FROM AllPersons
WHERE typeid = 1;
The flat model has the advantage of simplicity and poses no obstacles to supporting
indexes and constraints. Its drawbacks are:
■ A single table cannot contain more than 1000 columns, so the flat model
imposes a 1000-column limit on the total number of columns that the object
view hierarchy can contain.
■ Each row of the table will have NULLs for all the attributes not belonging to its
type. Such non-trailing NULLs can adversely affect performance.
Such queries need access only a single physical table to get all the objects of the
specific type. The drawbacks of this model are that queries of the sort SELECT *
FROM view require performing a UNION over all the underlying tables and
projecting the rows over just the columns in the specified view. (See "Querying a
View in a Hierarchy" on page 5-26.) Also, indexes on attributes (and unique
constraints) must span multiple tables, and support for this does not currently exist.
The vertical model can efficiently process queries of the kind SELECT * FROM
root_view, and it is possible to index individual attributes and impose unique
contraints on them. However, to re-create an instance of a type, a join over OIDs
must be performed for each level that the type is removed from the root in the
hierarchy.
So, for instance, in an object view hierarchy based on the person_typ type
hierarchy, you can query the view of person_typ to get a result set that contains
all persons, including students and employees; or you can query the view of
student_typ to get a result set that contains only students, including part-time
students.
In the SELECT list of a query, you can include either functions such as REF() and
VALUE() that return an object instance, or you can specify object attributes of the
view's declared type, such as the name and ssn attributes of person_typ.
If you specify functions, to return object instances, the query returns a polymorphic
result set: that is, it returns instances of both the view's declared type and any
subtypes of that type.
For example, the following query returns instances of persons, employees, and
students of all types, as well as REFs to those instances.
SELECT REF(p), VALUE(p) FROM Person_v p;
If you specify individual attributes of the view's declared type in the SELECT list or
do a SELECT *, again the query returns rows for the view's declared type and any
subtypes of that type, but these rows are projected over columns for the attributes
of the view's declared type, and only those columns are used. In other words, the
subtypes are represented only with respect to the attributes they inherit from and
share with the view's declared type.
So, for example, the following query returns rows for all persons and rows for
employees and students of all types, but the result uses only the columns for the
attributes of person_typ—namely, name, ssn, and address. It does not show
rows for attributes added in the subtypes, such as the deptid attribute of
student_typ.
SELECT * FROM Person_v;
To exclude subviews from the result, use the ONLY keyword. The ONLY keyword
confines the selection to the declared type of the view that you are querying:
SELECT VALUE(p) FROM ONLY(Person_v) p;
However, a query that selects for any attributes added in subtypes but not used by
the root type requires the SELECT privilege on all subviews as well. Such subtype
attributes may hold sensitive information that should reasonably require additional
privileges to access.
The following query, for example, requires SELECT privileges on Person_v and
also on Student_v, Employee_v (and on any other subview of Person_v)
because the query selects object instances and thus gets all the attributes of the
subtypes.
SELECT VALUE(p) FROM Person_v p;
A query that excludes rows belonging to subviews also requires SELECT privileges
on all subviews. The reason is that information about which rows belong
exclusively to the most specific type of an instance may be sensitive, so the system
requires SELECT privileges on subviews for queries (such as the following one) that
exclude all rows from subviews.
SELECT * FROM ONLY(Person_v);
This chapter explains how Oracle objects work in combination with the rest of the
database, and how to perform DML and DDL operations on them. It contains the
following major sections:
■ Privileges on Object Types and Their Methods
■ Dependencies and Incomplete Types
■ Synonyms for User-Defined Types
■ Performance Tuning
■ Tools Providing Support for Objects
■ Utilities Providing Support for Objects
The phrase WITH HIERARCHY OPTION grants a specified object privilege on all
subobjects of the object. This option is meaningful only with the SELECT object
privilege granted on an object view in an object view hierarchy. In this case, the
privilege applies to all subviews of the view on which the privilege is granted.
The following statements succeed because USER2 has EXECUTE on USER1's TYPE2
with the GRANT option:
However, the following grant fails because USER2 does not have EXECUTE on
USER1.TYPE1 with the GRANT option:
GRANT SELECT ON tab1 TO user3;
For either query, Oracle checks the user's SELECT privilege for the emp table. For
the first query, the user needs to obtain the emp_type type information to interpret
the data. When the query accesses the emp_type type, Oracle checks the user's
EXECUTE privilege.
Execution of the second query, however, does not involve named types, so Oracle
does not check type privileges.
Additionally, using the schema from the previous section, USER3 can perform the
following queries:
SELECT t.col1.attr2 from user2.tab2 t;
Note that in both selects by USER3, USER3 does not have explicit privileges on the
underlying types, but the statement succeeds because the type and table owners
have the necessary privileges with the GRANT option.
Oracle checks privileges on the following requests, and returns an error if the
requestor does not have the privilege for the action:
■ Pinning an object in the object cache using its REF value causes Oracle to check
SELECT privilege on the object table containing the object and EXECUTE
privilege on the object type.
See Also: Oracle Call Interface Programmer's Guide for tips and
techniques for using OCI program effectively with objects
■ Modifying an existing object or flushing an object from the object cache, causes
Oracle to check UPDATE privilege on the destination object table. Flushing a
new object causes Oracle to check INSERT privilege on the destination object
table.
■ Deleting an object causes Oracle to check DELETE privilege on the destination
table.
■ Invoking a method causes Oracle to check EXECUTE privilege on the
corresponding object type.
Oracle does not provide column level privileges for object tables.
attribute of employee is the department the employee belongs to and one attribute
of department is the employee who manages the department.
Types that depend on each other in this way, either directly or through intermediate
types, are called mutually dependent. In a diagram that uses arrows to show the
dependency relationships among a set of types, connections among mutually
dependent types form a loop.
To define such a circular dependency, you must use REFs for at least one segment of
the circle.
For example, you can define the following types:
CREATE TYPE department;
/
This is a legal set of mutually dependent types and a legal sequence of SQL DDL
statements. Oracle compiles it without errors.
Notice that the preceding code creates the type department twice. The first
statement:
CREATE TYPE department;
/
is an optional, incomplete declaration of department that serves as a placeholder
for the REF attribute of employee to point to. The declaration is incomplete in that
it omits the AS OBJECT phrase and lists no attributes or methods. These are
specified later in the full declaration that completes the type. In the meantime,
department is created as an incomplete object type. This enables the compilation
of employee to proceed without errors.
Synonyms can be created for collection types, too. The following example creates a
synonym for a nested table type:
CREATE TYPE typ2 AS TABLE OF NUMBER;
/
CREATE SYNONYM syn2 FOR typ2;
The REPLACE option enables you to have the synonym point to a different
underlying type. For example, the following statement causes syn1 to point to type
typ2 instead of the type it formerly pointed to:
CREATE OR REPLACE SYNONYM syn1 FOR typ2;
The next example shows a type synonym syn1 used to call the constructor of the
user-defined type typ1, for which syn1 is a synonym. The statement returns an
object instance of typ1:
SELECT syn1(0) FROM dual;
In the following example, syn2 is a synonym for a nested table type. The example
shows the synonym used in place of the actual type name in a CAST expression:
SELECT CAST(MULTISET(SELECT eno FROM USER3.EMP) AS syn2) FROM dual;
views, such as USER_TYPE_ATTRS, that show type names will show the associated
type synonym names in their place.
You can query the catalog view USER_SYNONYMS to find out the underlying type of
a type synonym.
Other kinds of schema objects that reference synonyms in their DDL statements also
become dependents of those synonyms. An object that depends on a type synonym
depends on both the synonym and on the synonym's underlying type.
A synonym's dependency relationships affect your ability to drop or rename the
synonym. Dependent schema objects are also affected by some operations on
synonyms. The following sections describe these various ramifications.
You cannot drop a type synonym if it has table or valid user-defined types as
dependents unless you use the FORCE option. The FORCE option causes any
columns that directly or indirectly depend on the synonym to be marked unused,
just as if the actual types of the columns were dropped. (A column indirectly
depends on a synonym if, for instance, the synonym is used to specify the type of
an attribute of the declared type of the column.)
Any dependent schema objects of a dropped synonym are invalidated. They can be
revalidated by creating a local object of the same name as the dropped synonym or
by creating a new public synonym with same name.
Dropping the underlying base type of a type synonym has the same effect on
dependent objects as dropping the synonym.
Performance Tuning
When tuning objects, the following items need to be addressed:
■ How objects and object views consume CPU and memory resources during
runtime
■ How to monitor memory and CPU resources during runtime
■ How to manage large numbers of objects
JDeveloper
JDeveloper is a full-featured, integrated development environment for creating
multitier Java applications. It enables you to develop, debug, and deploy Java client
applications, dynamic HTML applications, web and application server components
and database stored procedures based on industry-standard models.
JDeveloper provides powerful features in the following areas:
■ Oracle Business Components for Java
■ Web Application Development
■ Java Client Application Development
■ Java in the Database
■ Component-Based Development with JavaBeans
■ Simplified Database Access
■ Visual Integrated Development Environment
■ Java Language Support
JDeveloper runs on Windows platforms. It provides a standard GUI based Java
development environment that is well integrated with Oracle Application Server
and Database.
JPublisher
JPublisher is a utility, written entirely in Java, that generates Java classes to
represent the following user-defined database entities in your Java program:
■ Database object types
■ Database reference (REF) types
■ Database collection types (varrays or nested tables)
■ PL/SQL packages
JPublisher enables you to specify and customize the mapping of database object
types, reference types, and collection types (varrays or nested tables) to Java classes,
in a strongly typed paradigm.
Types The definition statements for derived types are exported. On an Import, a
subtype may be created before the supertype definition has been imported. In this
case, the subtype will be created with compilation errors, which may be ignored.
The type will be revalidated after its supertype is created.
Object View Hierarchies View definitions for all views belonging to a view
hierarchy are exported
SQL*Loader
The SQL*Loader utility moves data from external files into tables in an Oracle
database. The files may contain data consisting of basic scalar datatypes, such as
INTEGER, CHAR, or DATE, as well as complex user-defined datatypes such as row
and column objects (including objects that have object, collection, or REF attributes),
collections, and LOBs. Currently, SQL*Loader supports single-level collections only:
you cannot yet use SQL*Loader to load multilevel collections, that is, collections
whose elements are, or contain, other collections.
SQL*Loader uses control files, which contain SQL*Loader data definition language
(DDL) statements, to describe the format, content, and location of the datafiles.
SQL*Loader provides two approaches to loading data:
■ Conventional path loading, which uses the SQL INSERT statement and a bind
array buffer to load data into database tables
■ Direct path loading, which uses the Direct Path Load API to write data blocks
directly to the database on behalf of the SQL*Loader client.
Direct path loading does not use a SQL interface and thus avoids the overhead
of processing the associated SQL statements. Consequently, direct path loading
tends to provide much better performance than conventional path loading.
Either approach can be used to load data of supported object and collection
datatypes.
The other chapters in this book discuss the topics that you need to get started with
Oracle objects. The topics in this chapter are of interest once you start applying
object-relational techniques to large-scale applications or complex schemas.
The chapter contains these topics:
■ Storage of Objects
■ Creating Indexes on Typeids or Attributes
■ Type Evolution
■ Transient and Generic Types
■ User-Defined Aggregate Functions
■ Partitioning Tables That Contain Oracle Objects
Storage of Objects
Oracle automatically maps the complex structure of object types into the simple
rectangular structure of tables.
Leaf-Level Attributes
An object type is like a tree structure, where the branches represent the attributes.
Attributes that are objects sprout subbranches for their own attributes.
Ultimately, each branch ends at an attribute that is a built-in type; such as NUMBER,
VARCHAR2, or REF; or a collection type, such as VARRAY or nested table. Each of
these leaf-level attributes of the original object type is stored in a table column.
The leaf-level attributes that are not collection types are called the leaf-level scalar
attributes of the object type.
NAME TYPEID
------------------------------ --------------------------------
Bob Jones 01
Joe Lane 02
Kim Patel 03
column to get the type names corresponding to the typeids in a type discriminant
column.
REFs
When Oracle constructs a REF to a row object, the constructed REF is made up of
the object identifier (OID), some metadata of the object table, and, optionally, the
ROWID.
The size of a REF in a column of REF type depends on the storage properties
associated with the column. For example, if the column is declared as a REF WITH
ROWID, Oracle stores the ROWID in the REF column. The ROWID hint is ignored for
object references in constrained REF columns.
If column is declared as a REF with a SCOPE clause, the column is made smaller by
omitting the object table metadata and the ROWID. A scoped REF is 16 bytes long.
If the object identifier is primary-key based, Oracle may create one or more internal
columns to store the values of the primary key depending on how many columns
comprise the primary key.
■ If the elements are objects, the storage table is like an object table: the top-level
attributes of the object type become the columns of the storage table. But
because a nested table row has no object identifier column, you cannot
construct REFs to objects in a nested table.
■ If the elements are scalars, the storage table contains a single column called
COLUMN_VALUE that contains the scalar values.
For example, the following statement creates a bitmap index on the type
discriminant column underlying the substitutable contact column of table
contacts. Function SYS_TYPEID is used to reference the type discriminant
column:
CREATE BITMAP INDEX typeid_idx ON contacts (SYS_TYPEID(contact));
student_typ is the type that first defined the major attribute: the person_typ
supertype does not have it. Consequently, all the values in the hidden column for
the major attribute are values for student_typ or parttimestudent_typ
authors (a student_typ subtype). This means that the hidden column's values are
identical to the values returned by the TREAT expression, which returns major
values for all students, including student subtypes: both the hidden column and the
TREAT expression list majors for students and nulls for authors of other types. The
system exploits this fact and creates index major1_idx as an ordinary B-tree index
on the hidden column.
Values in a hidden column are identical to the values returned by a TREAT
expression like the preceding one only if the type named as the target of the TREAT
function (student_typ) is the type that first defined the attribute. If the target of
the TREAT function is a subtype that merely inherited the attribute, as in the
following example, the TREAT expression will return non-null major values for the
subtype (part-time students) but not for its supertype (other students).
CREATE INDEX major2_idx ON contacts
(TREAT(contact AS part_time_student_typ).major);
Here the values stored in the hidden column for major may be different from the
results of the TREAT expression. Consequently, an ordinary B-tree index cannot be
created on the underlying column. In a case like this, Oracle treats the TREAT
expression like any other function-based expression and tries to create the index as
a function-based index on the result.
The following example, like the previous one, creates a function-based index on the
major attribute of part-time students, but in this case the hidden column for major
is associated with a substitutable object table person_obj_table:
Type Evolution
Changing a user-defined type is called type evolution. You can make the following
changes to a user-defined type:
■ Add and drop attributes
■ Add and drop methods
■ Modify a numeric attribute to increase its length, precision, or scale
■ Modify a varying length character attribute to increase its length
■ Change a type's FINAL and INSTANTIABLE properties
■ Modify limit and size of VARRAYs
■ Modify length, precision, and scale of collection elements
Changes to a type affect things that reference the type. For example, if you add a
new attribute to a type, data in a column of that type must be presented so as to
include the new attribute.
Schema objects that directly or indirectly reference a type and are affected by a
change to it are called dependents of the type. A type can have these kinds of
dependents:
■ Table
■ Type or subtype
■ Program unit (PL/SQL block): procedure, function, package, trigger
■ Indextype
■ View (including object view)
■ Function-based index
■ Operator
How a dependent schema object is affected by a change to a type depends on the
dependent object and on the nature of the change to the type.
All dependent program units, views, operators and indextypes are marked invalid
when a type is modified. The next time one of these invalid schema objects is
referenced, it is revalidated using the new type definition. If the object recompiles
successfully, it becomes valid and can be used again. Depending on the change to
the type, function-based indexes may be dropped or disabled and need to be
rebuilt.
If a type has dependent tables, then, for each attribute added to a type, one or more
internal columns are added to the table depending on the new attribute's type. New
attributes are added with NULL values. For each dropped attribute, the columns
associated with that attribute are dropped. For each modified attribute, the length,
precision, or scale of its associated column is changed accordingly.
These changes mainly involve updating the tables' metadata (information about a
table's structure, describing its columns and their types) and can be done quickly.
However, the data in those tables must be updated to the format of the new type
version as well. Updating this data can be time-consuming if there is a lot of it, so
the ALTER TYPE command has options to let you choose whether to convert all
dependent table data immediately or to leave it in the old format to be converted
piecemeal as it is updated in the course of business.
The CASCADE option for ALTER TYPE propagates a type change to dependent
types and tables. See "ALTER TYPE Statement for Type Evolution" on page 7-15.
CASCADE itself has options that let you choose whether to convert table data to the
new type format as part of the propagation: the option INCLUDING TABLE DATA
converts the data; the option NOT INCLUDING TABLE DATA does not convert it.
By default, the CASCADE option converts the data. In any case, table data is always
returned in the format of the latest type version. If the table data is stored in the
format of an earlier type version, Oracle converts the data to the format of the latest
version before returning it, even though the format in which the data is actually
stored is not changed until the data is rewritten.
You can retrieve the definition of the latest type from the system view USER_
SOURCE. You can view definitions of all versions of a type in the USER_TYPE_
VERSIONS view.
The following example changes person_typ by adding one attribute and
dropping another. The CASCADE keyword propagates the type change to dependent
types and tables, but the phrase NOT INCLUDING TABLE DATA prevents
conversion of the related data.
CREATE TABLE person_obj_table OF person_typ;
-- The data of table person_obj_table has not been converted yet, but
-- when the data is retrieved, Oracle returns the data based on
-- the latest type version. The new attribute is initialized to NULL.
SELECT value(p) FROM person_obj_table p;
During SELECT statements, even though column data may be converted to the
latest type version, the converted data is not written back to the column. If a certain
user-defined type column in a table is retrieved often, you should consider
converting that data to the latest type version to eliminate redundant data
conversions. Converting is especially beneficial if the column contains a VARRAY
attribute because a VARRAY typically takes more time to convert than an object or
nested table column.
You can convert a column of data by issuing an UPDATE statement to set the column
to itself. For example:
UPDATE dept_tab SET emp_array_col = emp_array_col;
You can convert all columns in a table by using ALTER TABLE UPGRADE DATA.
For example:
ALTER TYPE person_typ ADD ATTRIBUTE (photo BLOB)
CASCADE NOT INCLUDING TABLE DATA;
ALTER TABLE dept_tab UPGRADE INCLUDING DATA;
In the following code, conversion of table data is deferred by adding the phrase
NOT INCLUDING TABLE DATA.
-- Add new attributes to person_typ and propagate the change
-- to employee_store_nt and department_typ
ALTER TYPE person_typ ADD ATTRIBUTE (photo BLOB, email VARCHAR2(80))
CASCADE NOT INCLUDING TABLE DATA;
Validating a Type
When the system executes an ALTER TYPE statement, it first validates the
requested type change syntactically and semantically to make sure it is legal. The
system performs the same validations as for a CREATE TYPE statement plus some
additional ones. For example, it checks to be sure an attribute being dropped is not
used as a partitioning key. If the new spec of the target type or any of its dependent
types fails the type validations, the ALTER TYPE statement aborts. No new type
version is created, and all dependent objects remain unchanged.
If dependent tables exist, further checking is done to ensure that restrictions relating
to the tables and any indexes are observed. Again, if the ALTER TYPE statement
fails the check of table-related restrictions, then the type change is aborted, and no
new version of the type is created.
When multiple attributes are added in a single ALTER TYPE statement, they are
added in the order specified. Multiple type changes can be specified in the same
ALTER TYPE statement, but no attribute name or method signature can be specified
more than once in the statement. For example, adding and modifying the same
attribute in a single statement is not allowed.
For example:
CREATE TYPE mytype AS OBJECT (attr1 NUMBER, attr2 NUMBER);
/
ALTER TYPE mytype ADD ATTRIBUTE (attr3 NUMBER),
DROP ATTRIBUTE attr2,
ADD ATTRIBUTE attr4 NUMBER CASCADE;
The following ALTER TYPE statement, which attempts to make multiple changes to
the same attribute (attr5), is invalid:
-- invalid ALTER TYPE statement
ALTER TYPE mytype ADD ATTRIBUTE (attr5 NUMBER, attr6 CHAR(10)),
DROP ATTRIBUTE attr5;
The following are other notes on validation constraints, table restrictions, and
assorted information about the various kinds of changes that can be made to a type.
Dropping an Attribute
■ Dropping all attributes from a root type is not allowed. You must instead drop
the type. Because a subtype inherits all the attributes from its supertype,
dropping all the attributes from a subtype does not reduce its attribute count to
zero; thus, dropping all attributes declared locally in a subtype is allowed.
■ Only an attribute declared locally in the target type can be dropped. You cannot
drop an inherited attribute from a subtype. Instead, drop the attribute from the
type where it is locally declared.
■ Dropping an attribute which is part of a table partitioning or sub-partitioning
key in a table is not allowed.
Dropping a Method
■ You can drop a method only from the type in which the method is defined (or
redefined): You cannot drop an inherited method from a subtype, and you
cannot drop an redefined method from a supertype.
■ If a method is not redefined, dropping it using the CASCADE option removes the
method from the target type and all subtypes. However, if a method is
redefined in a subtype, the CASCADE will fail and roll back. For the CASCADE to
succeed, you must first drop each redefined method from the subtype that
defines it and only then drop the method from the supertype.
You can consult the USER_DEPENDENCIES table to find all the schema objects,
including types, that depend on a given type. You can also run the DBMS_
UTILITY.GET_DEPENDENCY utility to find the dependencies of a type.
■ You can use the INVALIDATE option to drop a method that has been redefined,
but the redefined versions in the subtypes must still be dropped manually. The
subtypes will remain in an invalid state until they are explicitly altered to drop
the redefined versions. Until then, an attempt to recompile the subtypes for
revalidation will produce the error Method does not override.
Unlike CASCADE, INVALIDATE bypasses all the type and table checks and
simply invalidates all schema objects dependent on the type. The objects are
revalidated the next time they are accessed. This option is faster than using
CASCADE, but you must be certain that no problems will be encountered
revalidating dependent types and tables. Table data cannot be accessed while a
table is invalid; if a table cannot be validated, its data remains inaccessible.
instances stored in the column. The column can then store subtype instances of
the altered type.
Figure 7–1 graphically summarizes the options for ALTER TYPE INVALIDATE and
their effects. In the figure, T1 is a type and T2 is a dependent type. See the notes
following the figure.
Target type T1
T2
Dependent types
Metadata Metadata
2
TB2 TB1
Cascade Including
Table Data
Dependent tables
D2 D1
Other dependent objects
supply a value for every attribute declared in the type. Otherwise the constructor
call will fail to compile.
This requirement of an attribute-value constructor can create a problem if you
evolve the type later on—by adding an attribute, for example. When you change the
attributes of a type, the type's attribute-value constructor changes, too. If you add
an attribute, the updated attribute-value constructor expects a value for the new
attribute as well as the old ones. As a result, all the attribute-value constructor calls
in your existing code, where values for only the old number of attributes are
supplied, will fail to compile.
these are the same. If the argument names are different, no such qualification is
necessary. For example:
SELF.name := name;
or:
name := p1;
The function body must include an explicit return; as shown. The return
keyword must not be followed by a return expression. The system automatically
returns the newly constructed SELF instance.
A user-defined constructor may be implemented in PL/SQL, C, or Java.
VALUE(S)(NAME, AREA)
---------------------------------------------
SHAPE('shape1', 20)
RECTANGLE('rectangle', 10, 2, 5)
RECTANGLE('Quad', 36, 12, 3)
Each of these three types can be used with any built-in type native to the database
as well as with object types and collection types, both named and unnamed. The
types provide a generic way to work dynamically with type descriptions, lone
instances, and sets of instances of other types. Using the APIs, you can create a
transient ANYTYPE description of any kind of type. Similarly, you can create or
convert (cast) a data value of any SQL type to an ANYDATA and can convert an
ANYDATA (back) to a SQL type. And similarly again with sets of values and
ANYDATASET.
The generic types simplify working with stored procedures. You can use the generic
types to encapsulate descriptions and data of standard types and pass the
encapsulated information into parameters of the generic types. In the body of the
procedure, you can detail how to handle the encapsulated data and type
descriptions of whatever type.
You can also store encapsulated data of a variety of underlying types in one table
column of type ANYDATA or ANYDATASET. For example, you can use ANYDATA with
Advanced Queuing to model queues of heterogeneous types of data. You can query
the data of the underlying datatypes like any other data.
Example 7–4 defines and executes a PL/SQL procedure that uses methods built into
SYS.ANYDATA to access information about data stored in a SYS.ANYDATA table
column.
v_id mytab.id%TYPE;
v_data mytab.data%TYPE;
v_type SYS.ANYTYPE;
v_typecode PLS_INTEGER;
v_typename VARCHAR2(60);
v_dummy PLS_INTEGER;
v_n NUMBER;
v_dogowner dogowner;
non_null_anytype_for_NUMBER exception;
unknown_typename exception;
BEGIN
OPEN cur;
LOOP
FETCH cur INTO v_id, v_data;
EXIT WHEN cur%NOTFOUND;
v_typecode := v_data.GetType ( v_type /* OUT */ );
CASE v_typecode
WHEN Dbms_Types.Typecode_NUMBER THEN
IF v_type IS NOT NULL
THEN RAISE non_null_anytype_for_NUMBER; END IF;
v_dummy := v_data.GetNUMBER ( v_n /* OUT */ );
Dbms_Output.Put_Line (
To_Char(v_id) || ': NUMBER = ' || To_Char(v_n) );
WHEN Dbms_Types.Typecode_Object THEN
v_typename := v_data.GetTypeName();
IF v_typename NOT IN ( 'OBJTEST1.DOGOWNER' )
THEN RAISE unknown_typename; END IF;
v_dummy := v_data.GetObject ( v_dogowner /* OUT */ );
Dbms_Output.Put_Line (
To_Char(v_id) || ': user-defined type = ' || v_typename ||
'(' || v_dogowner.ownerno || ', ' || v_dogowner.ownername || ' )' );
END CASE;
END LOOP;
CLOSE cur;
EXCEPTION
WHEN non_null_anytype_for_NUMBER THEN
RAISE_Application_Error ( -20000,
'Paradox: the return AnyType instance FROM GetType ' ||
'should be NULL for all but user-defined types' );
WHEN unknown_typename THEN
RAISE_Application_Error ( -20000,
'Unknown user-defined type ' || v_typename ||
' - program written to handle only OBJTEST1.DOGOWNER' );
END;
/
The query and the procedure P in the preceding code sample produce output like
the following:
T.DATA.GETTYPENAME()
--------------------------------------------------------------------------------
SYS.NUMBER
OBJTEST1.DOGOWNER
1: NUMBER = 5
2: user-defined type = OBJTEST1.DOGOWNER(5555, John )
Corresponding to the three generic SQL types are three OCI types that model them.
Each has a set of functions for creating and accessing the respective type:
■ OCIType, corresponding to SYS.ANYTYPE
■ OCIAnyData, corresponding to SYS.ANYDATA
■ OCIAnyDataSet, corresponding to SYS.ANYDATASET
See Also:
■ Oracle Call Interface Programmer's Guide for the OCIType,
OCIAnyData, and OCIAnyDataSet APIs and details on how
to use them.
■ PL/SQL Packages and Types Reference for information about the
interfaces to the ANYTYPE, ANYDATA, and ANYDATASET types
and about the DBMS_TYPES package, which defines constants
for built-in and user-defined types, for use with ANYTYPE,
ANYDATA, and ANYDATASET.
Once all of these object types are in place, you can create a table to hold the
information about the people in the organization with the following SQL statement:
CREATE TABLE people_reltab (
id NUMBER(4) CONSTRAINT pk_people_reltab PRIMARY KEY,
name_obj name_objtyp,
address_obj address_objtyp,
phones_ntab phone_ntabtyp)
NESTED TABLE phones_ntab STORE AS phone_store_ntab;
Table PEOPLE_RELTAB
ID NAME_OBJ ADDRESS_OBJ PHONES_NTAB
PK
Text Number
VARCHAR(15) VARCHAR(14)
The storage for each object stored in the people_reltab table is the same as that
of the attributes of the object. For example, the storage required for a name_obj
object is the same as the storage for the first, middle, and last attributes
combined, except for the null indicator overhead.
If the COMPATIBLE parameter is set to 8.1.0 or higher, the null indicators for an
object and its embedded object attributes occupy one bit each. Thus, an object with
n embedded object attributes (including objects at all levels of nesting) has a storage
overhead of CEIL(n/8) bytes. In the people_reltab table, for example, the
overhead of the null information for each row is one byte because it translates to
CEIL(3/8) or CEIL(.37), which rounds up to one byte. In this case, there are
three objects in each row: name_obj, address_obj, and phones_ntab.
If, however, the COMPATIBLE parameter is set to a value lower than 8.1.0, such as
8.0.0, the storage is determined by the following calculation:
CEIL(n/8) + 6
Here, n is the total number of all attributes (scalar and object) within the object.
Therefore, in the people_reltab table, for example, the overhead of the null
information for each row is seven bytes because it translates to the following
calculation:
CEIL(4/8) + 6 = 7
CEIL(4/8) is CEIL(.5), which rounds up to one byte. In this case, there are three
objects in each row and one scalar.
Therefore, the storage overhead and performance of manipulating a column object
is similar to that of the equivalent set of scalar columns. The storage for collection
attributes are described in the "Viewing Object Data in Relational Form with
Unnesting Queries" section on page 8-11.
object table is logically and physically similar to a relational table whose column
types correspond to the top level attributes of the object type stored in the object
table. The key difference is that an object table can optionally contain an additional
object identifier (OID) column and index.
integrity on columns that store references to these row objects in a way similar to
foreign keys in relational tables.
Primary-key based identifiers also make it faster and easier to load data into an
object table. By contrast, system-generated object identifiers need to be remapped
using some user-specified keys, especially when references to them are also stored.
However, if each primary key value requires more than 16 bytes of storage and you
have a large number of REFs, using the primary key might require more space than
system-generated OIDs because each REF is the size of the primary key. In addition,
each primary-key based OID is locally (but not necessarily globally) unique. If you
require a globally unique identifier, you must ensure that the primary key is
globally unique or use system-generated OIDs.
If an object type does not have either a map or order method, only equality
comparisons are allowed on objects of that type. In this case, Oracle performs the
comparison by doing a field-by-field comparison of the corresponding object
attributes, in the order they are defined. If the comparison fails at any point, a
FALSE value is returned. If the comparison matches at every point, a TRUE value is
returned. However, if an object has a collection of LOB attributes, then Oracle does
not compare the object on a field-by-field basis. Such objects must have a map or
order method to perform comparisons.
Unscoped REFs are useful if the application design requires that the objects
referenced be scattered in multiple tables. Because rowid hints are ignored for
scoped REFs, you should use unscoped REFs if the performance gain of the rowid
hint, as explained in the "Speeding up Object Access Using the WITH ROWID
Option" on page 8-10, outweighs the benefits of the storage saving and query
optimization of using scoped REFs.
queries, Oracle can use an index on the scoped REF column to evaluate the join
efficiently.
For example, suppose the object type address_objtyp is used to create an object
table named address_objtab:
CREATE TABLE address_objtab OF address_objtyp ;
Then, a people_reltab2 table can be created that has the same definition as the
people_reltab table discussed in "Column Object Storage" on page 8-2, except
that a REF is used for the address:
CREATE TABLE people_reltab2 (
id NUMBER(4) CONSTRAINT pk_people_reltab2 PRIMARY KEY,
name_obj name_objtyp,
address_ref REF address_objtyp SCOPE IS address_objtab,
phones_ntab phone_ntabtyp)
NESTED TABLE phones_ntab STORE AS phone_store_ntab2 ;
The Oracle query optimizer might create a plan to perform a nested-loops join with
address_objtab as the outer table and look up matching addresses using the
index on the address_ref scoped REF column.
hint. Maintaining the rowid requires more storage space because the rowid adds 10
bytes to the storage requirements of the REF.
Bypassing the OID index search improves the performance of REF traversal
(navigational access) in applications. The actual performance gain may vary from
application to application depending on the following factors:
■ How large the OID indexes are.
■ Whether the OID indexes are cached in the buffer cache.
■ How many REF traversals an application does.
The WITH ROWID option is only a hint because, when you use this option, Oracle
checks the OID of the row object with the OID in the REF. If the two OIDs do not
match, Oracle uses the OID index instead. The rowid hint is not supported for
scoped REFs, for REFs with referential integrity constraints, or for primary
key-based REFs.
If the SELECT list of a query does not refer to any columns from the parent table
other than the nested table column, the query is optimized to execute only against
the nested table's storage table.
The unnesting query syntax is the same for varrays as for nested tables. For
instance, suppose the phones_ntab nested table is instead a varray named
phones_var. The following example shows how to use the TABLE syntax to query
the varray:
SELECT p.name_obj, v.num
FROM people_reltab p, TABLE(p.phones_var) v ;
RETURN homephones;
END;
/
Now, to query for a list of people and their home phone numbers, enter the
following:
SELECT p.name_obj, n.num
FROM people_reltab p, TABLE(
CAST(home_phones(p.phones_ntab) AS phone_ntabtyp)) n ;
To query for a list of people and their home phone numbers, including those people
who do not have a home phone number listed, enter the following:
SELECT p.name_obj, n.num
FROM people_reltab p,
TABLE(home_phones(p.phones_ntab) AS phone_ntabtyp)(+) n ;
The CASCADE option in the ALTER TYPE statement propagates the VARRAY size
change to its dependent types and tables. A new version is generated for each valid
dependent type and dependent tables metadata are updated accordingly based on
the different case scenarios described previously. If the VARRAY column is in a
cluster table, an ALTER TYPE statement with the CASCADE option fails because a
cluster table does not support a LOB.
The CASCADE option in the ALTER TYPE statement also provides the [NOT]
INCLUDING TABLE DATA option. The NOT INCLUDING TABLE DATA option only
updates the metadata of the table, but does not convert the data image. In order to
convert the VARRAY image to the latest version format, you can either specify
INCLUDING TABLE DATA explicitly in ALTER TYPE CASCADE statement or issue
ALTER TABLE UPGRADE statement.
Varray Querying
The unnesting syntax can be used to access varray columns similar to the way it is
used to access nested tables.
Varray Updates
Piece-wise updates of a varray value are not supported. Thus, when a varray is
updated, the entire old collection is replaced by the new collection.
Figure 8–2 shows how the storage table works. The storage table contains each
value for each nested table in a nested table column. Each value occupies one row in
the storage table. The storage table uses the NESTED_TABLE_ID to track the nested
table for each value. So, in Figure 8–2, all of the values that belong to nested table A
are identified, all of the values that belong to nested table B are identified, and so
on.
Storage Table
NESTED_TABLE_ID Values
B B21
B B22
C C33
A A11
E E51
B B25
E E52
A A12
E E54
B B23
C C32
A A13
D D41
B B24
E E53
Figure 8–3 shows how the storage table works when the nested table is in an IOT.
The storage table groups by NESTED_TABLE_ID the values for each nested table in
a nested table column. In Figure 8–3, for each nested table in the NT_DATA column
of the parent table, the data is grouped in the storage table: all of the values in
nested table A are grouped together, all of the values in nested table B are grouped
together, and so on.
Storage Table
NESTED_TABLE_ID Values
Storage for A A11
nested A A12
table A A A13
B B21
Storage for B B22
nested B B23
table B B B24
B B25
Storage for
nested C C31
Storage for table C C C32
nested D D41
table D E E51
Storage for E E52
nested
table E E E53
E E54
In addition, the COMPRESS clause enables prefix compression on the IOT rows. It
factors out the key of the parent in every child row. That is, the parent key is not
repeated in every child row, thus providing significant storage savings.
In other words, if you specify nested table compression using the COMPRESS clause,
the amount of space required for the storage table is reduced because the NESTED_
TABLE_ID is not repeated for each value in a group. Instead, the NESTED_TABLE_
ID is stored only once for each group, as illustrated in Figure 8–4.
Storage Table
NESTED_TABLE_ID Values
Storage for A11
nested A A12
table A A13
B21
Storage for B22
nested B B23
table B B24
B25
Storage for
nested C31
C
Storage for table C C32
nested D D41
table D E51
Storage for E52
nested E
table E E53
E54
In general, Oracle recommends that nested tables be stored in an IOT with the
NESTED_TABLE_ID column as a prefix of the primary key. Further, prefix
compression should be enabled on the IOT. However, if you usually do not retrieve
the nested table as a unit and you do not want to cluster the child rows, do not store
the nested table in an IOT and do not specify compression.
Unlike with the RETURN AS LOCATOR clause, however, you cannot specify a
particular inner collection to return as a locator when using the hint.
Oracle can execute a query that tests the membership in a child-set more efficiently
by transforming it internally into a semijoin. However, this optimization only
happens if the ALWAYS_SEMI_JOIN initialization parameter is set. If you want to
perform semijoins, the valid values for this parameter are MERGE and HASH; these
parameter values indicate which join method to use.
of a multilevel collection, then nesting a collection with REFs may provide better
performance because only the REFs need to be loaded, not the elements themselves.
True multilevel collections (specifically multilevel nested tables) perform better for
queries that access individual elements of the collection. Using nested table locators
can improve the performance of programmatic access if you do not need to access
all elements.
For an example of a collection that uses REFs to nest another collection, suppose
you want to create a new object type called person_objtyp using the object types
described in "Column Object Storage" on page 8-2, which are name_objtyp,
address_objtyp, and phone_ntabtyp. Remember that the phone_ntabtyp
object type is a nested table because each person may have more than one phone
number.
To create the person_objtyp object type, issue the following SQL statement:
CREATE TYPE person_objtyp AS OBJECT (
id NUMBER(4),
name_obj name_objtyp,
address_obj address_objtyp,
phones_ntab phone_ntabtyp);
The people_objtab table has the same attributes as the people_reltab table
discussed in "Column Object Storage" on page 8-2. The difference is that the
people_objtab is an object table with row objects, while the people_reltab
table is a relational table with three column objects.
PK
Text Number
VARCHAR(15) VARCHAR(14)
Now you can reference the row objects in the people_objtab object table from
other tables. For example, suppose you want to create a projects_objtab table
that contains:
■ A project identification number for each project.
PK
PK
Once the people_objtab object table and the projects_objtab object table are
in place, you indirectly have a nested collection. That is, the projects_objtab
table contains a nested table collection of REFs that point to the people in the
people_objtab table, and the people in the people_objtab table have a nested
table collection of phone numbers.
You can insert values into the people_objtab table in the following way:
INSERT INTO people_objtab VALUES (
0001,
name_objtyp('JOHN', 'JACOB', 'SCHMIDT'),
address_objtyp('1252 Maple Road', 'Fairfax', 'VA', '22033'),
phone_ntabtyp(
phone_objtyp('home', '650.339.9922'),
phone_objtyp('work', '510.563.8792'))) ;
phone_ntabtyp(
phone_objtyp('home', '415.642.6722'),
phone_objtyp('work', '650.891.7766'))) ;
Then, you can insert into the projects_objtab relational table by selecting from
the people_objtab object table using a REF operator, as in the following
examples:
INSERT INTO projects_objtab VALUES (
1101,
'Demo Product',
(SELECT REF(p) FROM people_objtab p WHERE id = 0001),
'Demo the product, show all the great features.',
personref_ntabtyp(
(SELECT REF(p) FROM people_objtab p WHERE id = 0001),
(SELECT REF(p) FROM people_objtab p WHERE id = 0002),
(SELECT REF(p) FROM people_objtab p WHERE id = 0003))) ;
Note: This example uses nested tables to store REFs, but you also
can store REFs in varrays. That is, you can have a varray of REFs.
END;
/
See Also:
■ Oracle Database Java Developer's Guide for more information
■ Chapter 4, "Object Support in Oracle Programming
Environments" for more information about choosing a
language
Static Methods
Static methods differ from member methods in that the SELF value is not passed in
as the first parameter. Methods in which the value of SELF is not relevant should be
implemented as static methods. Static methods can be used for user-defined
constructors.
The following example is a constructor-like method that constructs an instance of
the type based on the explicit input parameters and inserts the instance into the
specified table:
CREATE TYPE atype AS OBJECT(
a1 NUMBER,
STATIC PROCEDURE newa (
p1 NUMBER,
tabname VARCHAR2,
schname VARCHAR2));
/
CREATE TYPE BODY atype AS
STATIC PROCEDURE newa (p1 NUMBER, tabname VARCHAR2, schname VARCHAR2)
IS
sqlstmt VARCHAR2(100);
BEGIN
sqlstmt := 'INSERT INTO '||schname||'.'||tabname|| ' VALUES (atype(:1))';
EXECUTE IMMEDIATE sqlstmt USING p1;
END;
END;
/
BEGIN
atype.newa(1, 'atab', 'OBJTEST1');
END;
/
See Also:
■ PL/SQL User's Guide and Reference for information on
performance issues and restrictions on the use of NOCOPY
■ Oracle Database SQL Reference for information about using
NOCOPY in the CREATE PROCEDURE statement
■ "Member Methods" on page 2-9
SELECT e.name
FROM emps e
WHERE e.bonus() > 2000;
To evaluate this query, Oracle must evaluate bonus() for each row object in the
table. If there is a function-based index on the return values of bonus(), then this
work has already been done, and Oracle can simply look up the results in the index.
This enables Oracle to return a result from the query more quickly.
Return values of a function can be usefully indexed only if those values are
constant, that is, only if the function always returns the same value for each object
instance. For this reason, to use a user-written function in a function-based index,
the function must have been declared with the DETERMINISTIC keyword, as in the
preceding example. This keyword promises that the function always returns the
same value for each object instance's set of input argument values.
The following example creates a function-based index on the method bonus() in
the table emps:
CREATE INDEX emps_bonus_idx ON emps x (x.bonus()) ;
Now, suppose user OBJTEST2 tries to use atype in the following statement:
BEGIN
OBJTEST1.atype.newa(1, 'atab', 'OBJTEST2'); -- raises an error
END;
/
This statement raises an error because the definer of the type (OBJTEST1) does not
have the privileges required to perform the insert in the newa procedure. You can
avoid this error by defining atype using invoker rights. Here, you first drop the
atab table in both schemas and re-create atype using invoker rights:
DROP TABLE atab;
CONNECT OBJTEST1/OBJTEST1;
DROP TABLE atab; DROP TYPE atype; commit;
Now, if user OBJTEST2 tries to use atype again, the statement executes
successfully:
GRANT EXECUTE ON atype TO OBJTEST2;
CONNECT OBJTEST2/OBJTEST2;
CREATE TABLE atab OF OBJTEST1.atype;
BEGIN
OBJTEST1.atype.newa(1, 'atab', 'OBJTEST2');
END;
The statement is successful this time because the procedure is executed under the
privileges of the invoker (OBJTEST2), not the definer (OBJTEST1).
In a type hierarchy, a subtype has the same rights model as its immediate
supertype. That is, it implicitly inherits the rights model of the supertype and
cannot explicitly specify one. Furthermore, if the supertype was declared with
definer rights, the subtype must reside in the same schema as the supertype. These
rules allow invoker-rights type hierarchies to span schemas. However, type
hierarchies that use a definer-rights model must reside within a single schema. For
example:
CREATE TYPE deftype1 AS OBJECT (...); --Definer-rights type
CREATE TYPE subtype1 UNDER deftype1 (...); --subtype in same schema as supertype
CREATE TYPE schema2.subtype2 UNDER deftype1 (...); --ERROR
CREATE TYPE invtype1 AUTHID CURRENT_USER AS OBJECT (...); --Invoker-rights type
CREATE TYPE schema2.subtype2 UNDER invtype1 (...); --LEGAL
For both object-relational and object materialized views that are based on an object
table, if the type of the master object table is not FINAL, the FROM clause in the
materialized view definition query must include the ONLY keyword. For example:
CREATE MATERIALIZED VIEW customer OF cust_objtyp
AS SELECT CustNo FROM ONLY Scott.Customer_objtab@dbs1;
Constraints on Objects
Oracle does not support constraints and defaults in type specifications. However,
you can specify the constraints and defaults when creating the tables:
CREATE TYPE customer_type AS OBJECT(
cust_id INTEGER);
/
CREATE TYPE department_type AS OBJECT(
deptno INTEGER);
/
CREATE TABLE customer_tab OF customer_type (
cust_id default 1 NOT NULL);
where:
■ rel is a release string that is chosen by the product, such as, 'Release 10.1'
■ errmsg is any error message that may need to be returned
■ The function returns 0 on success and a nonzero value on error
■ To make queries involving joins and sorts parallel (using the ORDER BY, GROUP
BY, and SET operations), a MAP function is required. In the absence of a MAP
function, the query automatically becomes serial.
■ Parallel queries on nested tables are not supported. Even if there are parallel
hints or parallel attributes for the table, the query is serial.
■ Parallel DML and parallel DDL are not supported with objects. DML and DDL
are always performed in serial.
■ Parallel DML is not supported on views with INSTEAD-OF trigger. However,
the individual statements within the trigger may be parallelized.
Adding Specialization
Suppose that an existing type hierarchy of Graphic types (for example, curve, circle,
square, text) needs to accommodate an additional variation, namely, Bezier curve.
To support a new specialization of this sort that does not reflect a shortcoming of
the base type, we should use inheritance and create a new subtype BezierCurve
under the Curve type.
To sum up, the semantics of the required change dictates whether we should use
type evolution or inheritance. For a change that is more general and affects the base
type, use type evolution. For a more specialized change, implement the change
using inheritance.
queries on a view within the hierarchy to see a polymorphic set of objects contained
by the queried view or its subviews.
As an alternative way to support such polymorphic queries, you can define an
object view based on a query that returns a polymorphic set of objects. This
approach is especially useful when you want to define a view over a set of tables or
views that already exists.
For example, an object view of Person_t can be defined over a query that returns
Person_t instances, including Employee_t instances. The following statement
creates a view based on queries that select persons from a persons table and
employees from an employees table.
CREATE VIEW Persons_view OF Person_t AS
SELECT Person_t(...) FROM persons
UNION ALL
SELECT TREAT(Employee_t(...) AS Person_t) FROM employees;
An INSTEAD OF trigger defined for this view can use the VALUE function to access
the current object and to take appropriate action based on the object's most specific
type.
Polymorphic views and object view hierarchies have these important differences:
■ Addressability: In a view hierarchy, each subview can be referenced
independently in queries and DML statements. Thus, every set of objects of a
particular type has a logical name. However, a polymorphic view is a single
view, so you must use predicates to obtain the set of objects of a particular type.
■ Evolution: If a new subtype is added, a subview can be added to a view
hierarchy without changing existing view definitions. With a polymorphic view,
the single view definition must be modified by adding another UNION branch.
■ DML Statements: In a view hierarchy, each subview can be either inherently
updatable or can have its own INSTEAD OF trigger. With a polymorphic view,
only one INSTEAD OF trigger can be defined for a given operation on the view.
maps to a Java class. Once the mapping is registered through the extended SQL
CREATE TYPE command (a DDL statement), the Java application can insert or
select the Java objects directly into or from the database through an Oracle JDBC
driver. This enables the user to deploy the same class in the client, through JDBC,
and in the server, through SQL method dispatch.
In order for the client to access these objects, JPub can be used to generate the
corresponding Java class. Furthermore, the user has to augment the generated
classes with the code of the corresponding methods. Alternatively, the user can
create the class corresponding to the SQL object type.
At runtime, the JDBC user has to register the correspondence between a SQL Type
name and its corresponding Java class in a map.
Miscellaneous Tips
This section discusses miscellaneous tips.
See Also:
■ Oracle Database SQL Reference for a complete description of SQL
syntax and usage for user-defined types
■ PL/SQL User's Guide and Reference for a complete discussion of
PL/SQL capabilities
■ Oracle Database Java Developer's Guide for a complete discussion
of Java
■ Oracle Call Interface Programmer's Guide
■ Pro*C/C++ Programmer's Guide
Index-1
indexes on column objects, 2-5 D
qualifying in queries, 2-6
qualifying names in queries, 2-7 dangling REFs, 1-11
comparisons database administrators (DBAs)
collections, 3-17 DBA role, 6-2
methods, 2-10 database links, 2-8
compilation of object types, 6-6 datatypes
COMPRESS clause array types, 3-3
nested tables, 8-16 nested tables, 3-4
CONNECT role See also object types, user-defined types
user-defined types, 6-2, 6-3 transient and generic, 7-25
constraints DBA role
object tables, 2-4 user-defined types, 6-2
on Oracle objects, 8-33 default values
REFs, 8-8 collections, 3-3
constructor methods, 1-7, 2-14, 7-2 user-defined types, 3-3
literal invocation of, 2-14 DELETE privilege for object tables, 6-4, 6-5
constructors DEREF function, 2-36
methods, 2-14 dereferencing, 1-11
user-defined, 7-20 implicit, 1-11
CREATE ANY TYPE privilege, 6-2 dot notation, 2-10
See also privileges DROP ANY TYPE privilege, 6-2
CREATE INDEX statement See also privileges
object types, 2-5 DROP TYPE statement, 6-9
CREATE TABLE statement dump files
examples Export and Import, 6-14
column objects, 1-6
object tables, 1-8, 2-4 E
CREATE TRIGGER statement
equal and not equal conditions
examples
nested tables, 3-17
object tables, 2-5
Excel, 4-10
CREATE TYPE privilege, 6-2
EXECUTE ANY TYPE privilege, 6-2, 6-3
See also privileges
See also privileges
CREATE TYPE statement, 8-39
EXECUTE privilege
collection types, 1-12
user-defined types, 6-3
example, 3-5
See also privileges
incomplete types, 6-6
Export utility
nested tables, 2-14, 3-5
user-defined types, 6-14
object types, 1-4, 1-6, 2-2, 2-14
EXTERNAL NAME phrase, 4-16
varrays, 3-4
creating VARRAYs
containing references to LOBs, 3-8 F
CURSOR expression, 2-36 files
Export and Import dump file, 6-14
FINAL keyword, 2-17
Index-2
modifying finality, 7-14, 8-34 with Oracle objects, 4-12
FORCE keyword, 5-18 JDBC
FORCE option, 6-9 See Oracle JDBC
function-based indexes JPublisher, 4-15
on type methods, 8-28
L
G leaf-level attributes, 7-2
GRANT option for EXECUTE privilege, 6-3 scalar, 7-2
granting literal invocation
execute user-defined type, 6-3 constructor methods, 2-14
locators
returning nested tables as, 7-30, 8-18
I using a hint, 8-19
implicit dereferencing, 1-11 locks
Import utility object level locking, 4-3
user-defined types, 6-14
IN condition, 3-18
incomplete object types, 6-6 M
indexes managing
on REFs, 2-5 object types, 6-1
type-discriminant column, 7-5 map methods, 2-10, 8-7
user-defined types, 2-5 comparing collections, 3-17
index-organized tables for comparing objects, 2-10
storing nested tables as, 3-11, 8-15 materialized views, 8-32
inheritance, 1-7 MEMBER condition, 3-18
See type inheritance methods, 1-6, 2-8
inner capture, 2-7 choosing a language for, 8-25
INSERT privilege for object tables, 6-4, 6-5 comparison methods, 2-10
INSTANTIABLE keyword, 2-19 in a type hierarchy, 2-13
modifying instantiability, 7-14 constructor methods, 2-14, 7-2
INSTEAD OF triggers literal invocation, 2-14
nested tables, 5-13 dropping, 7-13
invoker-rights dynamic method dispatch, 2-23
object types, 8-29 execution privilege for, 6-2
IS A SET condition, 3-19 final, 2-17
IS EMPTY condition, 3-19 function-based indexes, 8-28
IS OF type predicate, 2-36 inheriting, 2-20
instantiability, 2-19
invoking, 2-10
J map, 2-10, 8-7
Java map for comparing objects, 2-10
object storage, 4-16 map required for collections, 3-17
Oracle JDBC and Oracle objects, 4-13 member, 2-9
Oracle SQLJ and Oracle objects, 4-14 of object types, 1-5
Index-3
order, 2-12, 8-7 O
overloading, 2-20
overriding, 2-18, 2-20, 2-21 object cache
PL/SQL, 4-2 object views, 5-4
SELF parameter, 2-9 OCI, 4-2
static, 2-13, 8-27 privileges, 6-5
multilevel collections Pro*C, 4-7
See collections, multilevel object identifiers, 1-8, 8-6
MULTISET EXCEPT operator, 3-20 column and index, 8-6
MULTISET INTERSECT operator, 3-20 for object types, 7-2
multiset operations primary-key based, 8-6
with nested tables, 3-19 REFs, 8-6
MULTISET UNION operator, 3-21 storage, 8-6
object instances, 1-4, 1-5
comparing, 2-34
N object tables, 1-8, 8-5
narrowing, 2-33, 2-40 constraints, 2-4
nested tables, 3-4, 8-14 indexes, 2-5
COMPRESS clause, 8-16 replicating, 8-31
creating, 3-2 row objects, 1-9
creating indexes on, 8-17 triggers, 2-5
equal and not equal conditions, 3-17 virtual object tables, 5-2
in an index-organized table, 3-11, 8-15 object types, 1-2
indexes, 2-5 assignments across, 2-32
INSTEAD OF triggers, 5-13 attributes of, 1-5
multiset operations, 3-19 column objects, 1-9
querying, 3-12 column objects versus row objects, 8-2
unnesting results, 3-13 comparison methods for, 2-10
returning as locators, 8-18 constructor methods for, 2-14, 7-2
specifying storage in a tablespace, 3-6 creating, 1-6
storage, 3-9, 8-14 creating subtypes of, 2-19
updating in views, 5-13 dependents, 6-6, 7-7
NESTED_TABLE_GET_REFS hint, 8-19 evolving, 7-7, 8-35
NESTED_TABLE_ID keyword, 3-11, 8-17 design considerations, 8-33
NLS_LENGTH_SEMANTICS initialization SQLJ types, 4-19
parameter, 2-3 FINAL or NOT FINAL, 2-17
NOCOPY compiler hint, 2-10 final/not final, 8-34
performance issues, 8-28 incomplete, 6-6, 6-7
NOT MEMBER condition, 3-18 indexes on column objects, 2-5
nulls indexing, 7-5
atomic, 2-2 instantiable/not instantiable, 2-19
object types, 2-2 invoker-rights, 8-29
locking in cache, 4-3
managing, 6-1
methods of, 1-5
Index-4
PL/SQL, 4-2 for Oracle objects
mutually dependent, 6-6 building a program, 4-5
Oracle type translator, 4-8 navigational access, 4-4
remote access to, 2-8, 5-14 object cache, 4-4
row objects, 1-9 OCIObjectFlush, 5-4
See also type inheritance OCIObjectPin, 5-4
specializing, 1-7 OIDs, 1-8
SQLJ types, 4-16 Oracle JDBC
substituting, 2-24 accessing Oracle object data, 4-13
use of table aliases, 2-7 Oracle objects
object views, 5-1 to 5-19 See object-relational model
advantages of, 5-2 Oracle Objects for OLE
circular references, 5-16 OraCollection interface, 4-12
defining, 5-3 OraObject interface, 4-11
hierarchies, 5-19, 8-36 OraRef interface, 4-12
privileges, 5-27 support of object-relational features, 4-10
querying in, 5-26 Oracle SQLJ
modeling relationships, 5-11, 5-15 creating custom Java classes, 4-14
multilevel collections in, 5-7 JPublisher, 4-14
nested tables, 5-13 support for Oracle objects, 4-14
null objects in, 5-6 Oracle type translator (OTT), 4-8
OIDs with, 5-9 OraCollection interface, 4-12
REFs to, 5-10 ORAData interface, 4-17
replicating, 8-31 OraObject interface, 4-11
updating through INSTEAD OF triggers, 5-12 OraRef interface, 4-12
OBJECT_ID pseudocolumn, 2-26 order methods, 2-12, 8-7
OBJECT_VALUE pseudocolumn, 2-26 OTT, 4-8
object-relational model, 9-1
comparing objects, 8-7
constraints, 8-33
P
design considerations, 8-1 parallel query
limitations of relational model, 1-2 objects, 8-34
methods, 1-6, 2-8 restrictions for Oracle objects, 8-34
partitioning, 7-29 view objects, 8-34
programmatic environments for, 4-1, 4-12 partitioning
replication, 8-31 tables containing Oracle objects, 7-29
objects pkREFs, 7-4
collection objects, 5-6 PL/SQL
comparing, 2-34 bind variables
in columns, 5-4 user-defined types, 4-2
object references, 5-10 object views, 5-4
row objects and object identifiers, 5-6 polymorphism, 2-15, 8-36
OCCI, 4-9 See also substitutability
OCI POWERMULTISET function, 3-22
associative access, 4-3 POWERMULTISET_BY_CARDINALITY
Index-5
function, 3-22 constraints on, 2-6, 8-8
primary-key-based REFs, 7-4 constructing from object identifiers, 7-2
privileges dangling, 1-11, 2-6
system dereferencing of, 1-11
user-defined types, 6-2 for rows of object views, 5-3
user-defined types implicit dereferencing of, 1-11
acquired by role, 6-2 indexes on, 2-5
ALTER ANY TYPE, 6-2 indexing, 8-9
checked when pinning, 6-5 obtaining, 1-11
column level for object tables, 6-5 pinning, 5-4, 6-5
CREATE ANY TYPE, 6-2 scoped, 1-10, 2-6, 7-4, 8-9
CREATE TYPE, 6-2 size of, 7-4
DELETE, 6-4, 6-5 storage, 8-8
DROP ANY TYPE, 6-2 substitutability and, 2-24, 2-28
EXECUTE, 6-3 use of table aliases, 2-8
EXECUTE ANY TYPE, 6-2, 6-3 WITH ROWID option, 8-10
EXECUTE ANY TYPE with ADMIN RESOURCE role
OPTION, 6-3 user-defined types, 6-2, 6-3
EXECUTE with GRANT option, 6-3 roles
INSERT, 6-4, 6-5 CONNECT role, 6-2, 6-3
SELECT, 6-4, 6-5 DBA role, 6-2
system privileges, 6-2 RESOURCE role, 6-2, 6-3
UPDATE, 6-4, 6-5 row objects, 1-9
using, 6-3 storage, 8-5
Pro*C/C++
associative access, 4-7
converting between Oracle and C types, 4-8
S
navigational access, 4-7 schemas
user-defined datatypes, 4-2 qualifying column names, 2-7
programmatic environments user-defined datatypes, 4-2
for Oracle objects, 4-1, 4-12 user-defined types, 1-5
scoped REFs, 1-10, 7-4
SELECT privilege for object tables, 6-4, 6-5
Q SELF parameter, 2-9
queries SET function, 3-22
set membership, 8-19 SQL
unnesting, 8-11 user-defined datatypes, 4-2
varrays, 8-14 embedded SQL, 4-7
OCI, 4-3
SQLData interface, 4-17
R SQLJ
REF function, 2-38 See Oracle SQL
references See REFs SQLJ object types, 4-12, 8-37
REFs, 1-9 creating, 4-17
comparing, 2-35 mapping Java classes, 4-18
Index-6
See also object types, Oracle SQLJ indexes, 2-5
storage triggers, 2-5
column objects, 8-2 virtual, 5-2
nested tables, 7-4 qualifying column names, 2-6, 2-7
object tables, 7-2 TREAT function, 2-26, 2-33, 2-37, 2-39, 7-6
REFs, 7-4 triggers
SUBMULTISET condition, 3-18 INSTEAD OF triggers
substitutability, 2-24 object views and, 5-12
attribute, 2-24 user-defined types, 2-5
collections and, 2-24 type dependencies, 6-8
column and row, 2-25, 7-5 type evolution
constraining, 2-30 See object types
dependencies, 6-8 type hierarchies, 1-7, 2-15
narrowing, 2-33 methods in, 2-13
OBJECT_ID, 2-26 type inheritance, 2-15
OBJECT_VALUE, 2-26 finality, 2-17
turning off, 2-29 instantiability, 2-19
views and, 2-25, 8-36 See inheritance
widening, 2-32 specializing subtypes, 2-16
subtypes, 2-15, 2-27 typeids, 2-38, 7-5
creating, 2-18 types
indexing attributes of, 7-6 See datatypes, object types
specializing, 8-35
supertypes, 2-15, 2-27
SYS_TYPEID function, 2-38, 7-5
U
SYS.ANYDATA, 7-25 UNDER keyword, 2-18
SYS.ANYDATASET, 7-25 unnesting queries, 8-11
SYS.ANYTYPE, 7-25 UPDATE privilege for object tables, 6-4, 6-5
system privileges updates
ADMIN OPTION, 6-3 object views, 5-12
user-defined types, 6-2 user-defined aggregate functions, 7-28
See also privileges user-defined constructors, 7-20
user-defined datatypes
See also user-defined types
T user-defined types, 1-2
TABLE and remote databases, 2-8
function, 2-39 collections
TABLE expressions, 3-13, 8-11 nested tables, 3-4
tables variable arrays (VARRAYs), 3-3
aliases, 2-7 example of privileges, 6-3
functions, 2-39 Export and Import, 6-14
nested tables, 3-4 incomplete types, 6-5
indexes, 2-5 managing, 6-1
object tables, 1-8 object types
constraints, 2-4 use of table aliases, 2-7
Index-7
performance tuning, 6-12
privileges, 6-2
See also object types
See also object-relational model
storage, 7-2
synonyms, 6-9
tools, 6-13
utilities, 6-14
USING clause, 4-16
V
validation
failure, 7-15
object types, 7-11
VALUE function, 2-41
variables
bind variables
user-defined types, 4-2
object variables, 5-4
varrays, 3-3
accessing, 8-14
creating, 3-2
creating VARRAYs, 3-8
increasing the number of elements, 3-8
querying, 8-14
storage, 3-6, 8-13
updating, 8-14
views
See also object views
substitutability, 2-25
updatability, 5-12
Visual Basic, 4-10
W
widening
and substitutability, 2-32
Index-8