9.7 Extending the Relational Model

The relational model was designed to represent data that consists of single-valued attributes of a small collection of data types, related in relatively simple ways and typically used in traditional data processing. As discussed in Section 9.1, the original relational model lacks features needed to represent the more complex types and relationships necessary for advanced applications. The industry responded to this challenge by proposing the object data model as a new data model. Vendors of relational DBMSs, including Oracle, IBM, Sybase, Informix, PostgreSQL, and Microsoft, met this competition by extending their relational products to incorporate features of the object data model. The SQL:1999 standard also extended the SQL language to use these new features, which were further extended in 2003, 2006, 2008, 2011, 2016, and 2019. The OR model can be viewed as a compromise between the strictly relational model and the OO model described earlier.

Some of the additional features are as follows:

  • Richer fundamental data types, including support for large objects such as text, image, video or audio data, as well as types for Boolean, national characters sets, XML, JSON, and geographical data

  • Structured types that can hold multiple attributes, including row, array, and multiset

  • UDTs that correspond to classes in OO systems, including built-in constructor, observer, and mutator methods, and user-written methods

  • Reference types

  • Representation of class hierarchies, with inheritance of both data structures and methods

  • Multidimensional arrays

  • Support for analytical processing, with additional statistical functions and new operations

9.7.1 Large Object Data Types

SQL:1999 added the LOB(Large Object) type to standard SQL. The LOB type can be used to store semistructured data such as XML or text files, and unstructured data such as images, audio, video, and other multimedia objects. The LOB type has variants BLOB (Binary Large Object), CLOB (Character Large Object), and NCLOB (National Character Large Object). LOB types have very restricted functions, such as substring operations. They allow comparisons only for equality or inequality, and they cannot be used for ordering or in GROUP BY or ORDER BY clauses. Because they are large files, LOBs are normally stored and rarely retrieved again. They can be stored in the database itself if they are not too large, or in a file outside the table, by using an LOB locator, a system-generated binary surrogate for the actual address. For example, if we wish to add a student’s picture to a student record, we would add the picture attribute in the CREATE TABLE command for the Student table, using the attribute declaration

picture C L O B REF IS pic I d SYSTEM GENERATED.

The picId is a reference pointer to the file containing an image of the picture. We will discuss the use of reference types in Section 9.7.4.

Oracle does not support all the features of the SQL standard for LOBs, although it includes BLOB, CLOB, and NCLOB types, as well as Bfile, which is used for extremely large objects that are stored outside the database space.

9.7.2 Structured Types

The SQL standard includes structured collection types, including array and row, as well as set (an unordered collection of distinct elements) and multiset (an unordered collection that allows repetition of elements, also called a bag). Oracle has two collection types—varray and nested table—that perform many of the same functions as the SQL standard collection types. A third collection type, an associative array, consists of key-value pairs.

To create an Oracle varray, we must provide a name for the varray type, specify the base type for the values to be stored in the cells of the varray, and specify the size of the varray, using the form

CREATE TYPE array type hyphen name AS V ARRAY open parentheses size close parentheses OF base hyphen type semicolon.

For example, if students can have double majors, we can create a user-defined type for an array with two cells to hold major values, and then use that type as the data type of the majors attribute in a new Stu table. FIGURE 9.9(A) shows the Oracle commands for the MajorsType varray type and the table declaration where the attribute majors is of that type.

Note that Oracle does not support the SQL standard Boolean data type, so the attribute matriculated is given the datatype VARCHAR2(5) here. It uses string values of 'true' or 'false', not Boolean values.

To insert a record into a table with a varray type, we use the type constructor, listing the values to be inserted into the varray, as shown for the three rows of the Stu table inserted in FIGURE 9.9(B) where the constructor MajorsType appears.

Students with only one major are assigned a null value for the second major, as shown in the second row inserted. Queries can be written as usual, or we can use dot notation, as we did when we employed aliases in previous SQL queries, to get the entire majors array as shown in FIGURE 9.9(C). However, Oracle does not allow us to access cells of the array individually in queries by using an index directly. Instead we must use PL/SQL, as shown in the printarray procedure in FIGURE 9.9(D). Recall that Oracle is not case-sensitive, so we have used both uppercase and lowercase in these examples.

Line 1. CREATE TYPE Majors Type AS V ARRAY open parentheses 2 close parentheses OF VAR CHAR 2 open parentheses 20 close parentheses.
Line 2. Forward slash.
Line 3. CREATE TABLE S t u open parentheses.
Line 4. S t u I d VAR CHAR 2 open parentheses 6 close parentheses comma.
Line 5. Last Name VAR CHAR 2 open parentheses 20 close parentheses NOT NULL comma.
Line 6. First Name VAR CHAR 2 open parentheses 20 close parentheses NOT NULL comma.
Line 7. Matriculated VAR CHAR 2 open parentheses 5 close parentheses DEFAULT single quote false comma.
Line 8. Majors Majors Type comma.
Line 9. Credits NUMBER open parentheses 3 close parentheses DEFAULT 0 comma.
Line 10. CONSTRAINT S t u underscore s t u I d underscore p k PRIMARY KEY open parentheses s t u I d close parentheses comma.
Line 11. CONSTRAINT S t u underscore credits underscore c c CHECK open parentheses open parentheses credits greater than or equal to 0 close parentheses AND open parentheses credits less than 150 close parentheses close parentheses semicolon.
 Line 1. INSERT INTO S t u VALUES open parentheses single quote S 555 single quote comma single quote Quirk single quote comma single quote Sean single quote comma single quote true single quote comma.
Line 2. Majors Type open parentheses single quote French single quote comma single quote Psychology single quote close parentheses comma 30 close parentheses semicolon.
Line 3. INSERT INTO S t u VALUES open parentheses single quote S 511 single quote comma single quote Marks single quote comma single quote Daniel single quote comma single quote true single quote comma.
Line 4. Majors Type open parentheses single quote History single quote comma null close parentheses comma 15 close parentheses semicolon.
Line 5. INSERT INTO S t u VALUES open parentheses single quote S 599 single quote comma single quote White single quote comma single quote Kimberly single quote comma single quote true single quote comma.
Line 6. Majors Type open parentheses single quote C S C single quote comma single quote Math single quote close parentheses comma 60 close parentheses semicolon.
 Line 1. SELECT s dot s t u I d comma s dot majors.
Line 2. FROM S t u s semicolon.

The following returns an error comma showing we cannot use subscripts to access an array.
Line 1. SELECT s dot s t u I d comma s dot majors open square bracket 1 close square bracket FROM S t u s semicolon
We must use P L forward slash S Q L instead comma with a loop for the subscript.
Line 1. set server output on semicolon
Line 2. create or replace procedure print array as
Line 3. i d VAR CHAR 2 open parentheses 6 close parentheses semicolon
Line 4. f name VAR CHAR 2 open parentheses 20 close parentheses semicolon
Line 5. l name VARCHAR2 open parentheses 20 close parentheses semicolon
Line 6. my majors Majors Type semicolon
Line 7. cursor maj cursor is
Line 8. SELECT s dot s t u I d comma s dot first Name comma s dot last Name comma s dot majors
Line 9. FROM S t u s semicolon
Line 10. begin
Line 11. open maj cursor semicolon
Line 12. d b m s underscore output dot put underscore line open parentheses single quote Id single quote vertical bar vertical bar single quote First Name single quote vertical bar
Line 13. vertical bar single quote Last Name single quote vertical bar vertical bar single quote Majoring in single quote close parentheses semicolon
Line 14. d b m s underscore output dot put underscore line open parentheses single quote hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen
Line 15. hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen hyphen single quote close parentheses semicolon
Line 16. loop
Line 17. fetch m a j cursor into i d comma f name comma l name comma my majors semicolon
Line 18. exit when m a j cursor percentage not found semicolon
Line 19. d b m s underscore output dot put open parentheses id vertical bar vertical bar single quote single quote vertical bar vertical bar f name vertical bar vertical bar single quote single quote vertical bar vertical bar l name close parentheses semicolon
Line 20. for i in 1 dot dot 2 loop
Line 21. if open parentheses my majors open parentheses i close parentheses is not null close parentheses
Line 22. then d b m s underscore output dot put open parentheses single quote single quote vertical bar vertical bar my majors open parentheses i close parentheses close parentheses semicolon
Line 23. end if semicolon
Line 24. end loop semicolon hyphen hyphen FOR MAJORS
Line 25. d b m s underscore output dot put underscore line open parentheses single quote single quote close parentheses semicolon
Line 26. end loop semicolon hyphen hyphen FOR STUDENTS
Line 27. close m a j cursor semicolon
Line 28. end semicolon

FIGURE 9.9 Varrays in Oracle

9.7.3 User-Defined Data Types (UDTs)

Both standard SQL and Oracle allow users to create user-defined object types. Object types are like classes in the OO model. The attributes can be any SQL type, including other previously defined object types, allowing nesting of object types. An object type can be either the type used for an attribute or the only type used for a table. For example, we can create an AddressType as follows

Line 1. CREATE OR REPLACE TYPE Address Type AS OBJECT open parentheses.
Line 2. Street VAR CHAR 2 open parentheses 50 close parentheses comma.
Line 3. City VAR CHAR 2 open parentheses 15 close parentheses comma.
Line 4. State CHAR open parentheses 2 close parentheses comma.
Line 5. Zip VAR CHAR 2 open parentheses 10 close parentheses close parentheses semicolon.

For each such type, SQL provides a default constructor to allow new instances of the type to be created. This constructor always has the same name and data type as the UDT, and we can invoke it by simply using the name of the type. Users can also create their own constructors when they define the new type.

Column Objects

We can use a user-defined type as the data type for a column of any table, as in

Line 1. CREATE TABLE Customer open parentheses.
Line 2. c u s t I D NUMBER open parentheses 5 close parentheses PRIMARY KEY comma.
Line 3. c u s t Name VAR CHAR 2 open parentheses 40 close parentheses comma.
Line 4. c u s t Add Address Type close parentheses semicolon.

When an object type is used in this way, it is called a column object. Data is inserted using the default type constructor, as in

Line 1. INSERT INTO Customer VALUES open parentheses 1001 comma single quote Susan Miller single quote comma Address Type
Line 2. Open parentheses single quote 1 2 3 Main street single quote comma single quote Anytown single quote comma single quote M N single quote comma single quote 55144 single quote close parentheses single parentheses semicolon.

Data can be retrieved using the SQL SELECT command, but dot notation is used to refer to the individual attributes of the column object, and an iterator variable, much like an alias, must be used, as in

Line 1. SELECT c dot c u s t I d comma c dot c u s t add dot street comma c dot c u s t add dot zip.
Line 2. FROM customer c.
Line 3. WHERE c dot c u s t I d equals 1001 semicolon.

A table may contain more than one column object.

Object Tables

An object table is one where each row represents an object. Each row, called a row object, has a unique OID as described in Section 9.2.4. In both standard SQL and Oracle, the system generates an OID by default when we insert a row object. Oracle creates an index on the OID of object tables. Note that the value is an internal one that does not appear as part of the row object it refers to and cannot be accessed directly by the user. To create an object table in Oracle, we first define the object type. For example, FIGURE 9.10(A) shows how to create a new StudentType1 as an object type (a class).

As this example illustrates, an object type definition contains the name of the type, a list of attributes with their data types, and member functions and procedures within parentheses, as well as optional specifications [NOT] INSTANTIABLE and [NOT] FINAL. The specification NOT FINAL means that we can create subtypes for the type. The specification NOT INSTANTIABLE means that no instances of that type can be created, so such types have no constructors. However, they can be used as supertypes from which subtypes can inherit, and those subtypes can be instantiable. Types that have been created as NOT INSTANTIABLE can be changed later by the statement

ALTER TYPE type hyphen name INSTANTIABLE semicolon.

However, altering a type from INSTANTIABLE to NOT INSTANTIABLE is possible only if the type has not previously been used to create columns, tables, or any other items that reference it.

Note that we do not indicate a primary key constraint or other constraints for the type because we are defining a type, not a table. The attributes can themselves be previously defined UDTs, as we see in the student attribute address, which uses AddressType. We can also write declarations of methods as functions or procedures for the type, indicating the parameters and return types. In Oracle, the code body for the methods is written in PL/SQL, but all the member methods must be coded together, as illustrated in FIGURE 9.10(B) for StudentType1. No code is needed for the built-in methods. Within the code for a member method, the implicit parameter, the calling object, is referred to as self. When invoked, a member method takes an instance of the type as an implicit parameter. Member methods are invoked using dot notation because, like attributes, they are members of the type. For example, if firstStudent is an instance of the StudentType1, we can write in an application program

first Student dot add Credits open parentheses 3 close parentheses semicolon.

Row 1. CREATE OR REPLACE TYPE Student Type 1 AS OBJECT open parentheses.
Row 2. s t u I d VAR CHAR 2 open parentheses 6 close parentheses comma.
Row 3. last Name VAR CHAR 2 open parentheses 20 close parentheses comma.
Row 4. first Name VAR CHAR 2 open parentheses 20 close parentheses comma.
Row 5. address Address Type comma.
Row 6. advisor F a c i d VAR CHAR 2 open parentheses 6 close parentheses comma.
Row 7. credits NUMBER open parentheses 3 close parentheses comma.
Row 8. date Of Birth DATE comma.
Row 9. MEMBER FUNCTION find Age RETURN NUMBER comma.
Row 10. MEMBER PROCEDURE add Credits open parentheses num Credits IN NUMBER close parentheses.
Row 11. Close parentheses.
Row 12. INSTANTIABLE.
Row 13. NOT FINAL semicolon.
 Line 1. CREATE OR REPLACE TYPE BODY Student Type 1 IS
Line 2. MEMBER FUNCTION find Age RETURN NUMBER IS
Line 3. age NUMBER semicolon.
Line 4. BEGIN.
Line 5. age colon equals TRUNC open parentheses open parentheses SYSDATE minus date Of Birth close parentheses forward slash 365.25 close parentheses semicolon.
Line 6. RETURN open parentheses age close parentheses semicolon.
Line 7. END semicolon. hyphen hyphen of find Age.
Line 8. MEMBER PROCEDURE add Credits open parentheses num Credits in NUMBER close parentheses IS
Line 9. BEGIN.
Line 10. Self dot credits colon equals self dot credits plus num Credits semicolon.
Line 11. END semicolon hyphen hyphen of add Credits.
Line 12. END semicolon.
Line 13. Forward slash.

FIGURE 9.10 Object Type Definitions

Using the new StudentType1, we can create a new table, called NewStudent1, which differs slightly from the Student table used in previous chapters, for purposes of illustration. The table definition does not provide a list of attributes, but it states that the table is of the StudentType1 object type as specified in the type definition. This is an example of an object table, where each row is an instance of StudentType1. This object table also contains the embedded column object, address

Line 1. CREATE TABLE New Students 1 OF Student Type 1.
Line 2. Open parentheses CONSTRAINT New Students 1 underscore s t u I d underscore p k PRIMARY KEY open parentheses s t u I d close parentheses comma.
Line 3. CONSTRAINT New Students underscore advisor I d underscore f k FOREIGN KEY open parentheses advisor F a c I d close parentheses.
Line 4. REFERENCES Faculty open parentheses f a c I d close parentheses close parentheses semicolon.

Any constraints, including primary and foreign keys, are specified when the table is created because constraints apply to the table, not to the type. For the present, we are using the facId of the advisor in the existing Faculty table as a foreign key. We can create as many tables as we wish using the same UDT. Each row of an object table is called a row object.

Although we can insert values in the usual way, it is preferable to use the StudentType1 type constructor to create the row objects, as in

Line 1. INSERT INTO New Students 1.
Line 2. VALUES open parentheses Student Type 1 open parentheses single quote S 999 single quote comma single quote Fernandes single quote comma single quote Luis single quote comma Address Type.
Line 3. Open parentheses single quote 101 Pine Lane single quote comma single quote Madison single quote comma single quote W I single quote comma single quote 53726 single quote close parentheses comma single quote F 101 single quote comma 0 comma single quote 25 hyphen Jan hyphen 2005 single quote close parentheses close parentheses semicolon.
Line 4. INSERT INTO New students 1.
Line 5. VALUES open parentheses Student Type 1 open parentheses single quote S 888 single quote comma single quote Bates single quote comma single quote Lucy single quote comma Address Type.
Line 6. Open parentheses single quote 102 Pine Lane single quote comma single quote Milwaukee single quote comma single quote W I single quote comma single quote 53201 single quote close parentheses comma null comma 30 comma single quote 15 hyphen Jun hyphen 2004 single quote close parentheses close parentheses semicolon.

Besides the constructor StudentType1, used here, the new type has the addCredits() and FindAge() methods that we wrote in Figure 9.10(B), as well as the built-in observer and mutator methods for each of its attributes.

Although the user can override observer and mutator methods by redefining them, they cannot be overloaded, unlike the corresponding methods in some OO languages. The observer methods (usually called GET in OO terminology) are called using standard SQL DML commands, with path expressions using dot notation and iterator variables that look like aliases, as illustrated in the following example, which retrieves the ID, street, and age of a student in the NewStudents1 table

Line 1. SELECT s dot s t u I d comma s dot address dot street comma s dot find Age open parentheses close parentheses.
Line 2. FROM New Students 1 s.
Line 3. WHERE s dot s t u I d equals single quote S 999 single quote semicolon.

The SELECT statement can be used to retrieve entire row objects using the VALUE function, as in

Line 1. SELECT VALUE open parentheses s close parentheses.
Line 2. FROM New Students 1 s semicolon.

The mutator methods (usually called SET in OO terminology) are invoked by using the SQL INSERT command already illustrated, or using the UPDATE command, again using path expressions and iterator variables, as in

Line 1. UPDATE New Students 1 n.
Line 2. SET n dot date Of Birth equals single quote 20 hyphen Jun hyphen 1999 single quote comma n dot address dot zip equals single quote 53727 single quote.
Line 3. WHERE n dot s t u I d equals single quote S 999 single quote semicolon.

When users define their own data types, the only built-in operations are testing for equality of objects of that type or membership (IN). Most operations that are built in for standard data types are not defined for UDTs. Therefore, users must define operations on the new types they create, building on the basic operations defined for the source types. The definition of a new type includes a list of its attributes and its methods, but the methods are defined only for a single user-defined type and do not apply to other types the user creates. Methods for a type can be classified as member methods or static methods. Member methods have the implicit self parameter, as described earlier, and can be either functions, which have a single return type, or procedures, which have no return but may have input and/or output parameters. We can also create nonmember or static methods, which are defined for the type and which do not have an implicit self parameter.

Attributes of objects can be compared or ordered by using comparison operators as usual or by comparisons of returns of their methods, as in

Line 1. SELECT s dot asterisk.
Line 2. FROM New Students 1 s.
Line 3. ORDER BY s dot find Age open parentheses close parentheses semicolon.

However, entire row objects cannot be compared, so the following query will cause an error

Line 1. SELECT s dot s t u I d comma s dot last Name comma s dot first Name.
Line 2. FROM New Students 1 s.
Line 3. ORDER BY VALUE open parentheses s close parentheses semicolon

To provide comparison of objects of the same user-defined type, the user can define an order for the type as a method. In Oracle, users can impose an order by identifying either a map method or an order method for the type. A map method directs Oracle to apply the comparison method it normally uses for one of its built-in types (normally, one of the attributes) as the comparison method for the entire type. For example, if we had defined a member function

MAP MEMBER FUNCTION get s t u I d RETURN VAR CHAR 2.

in the definition of the type, and then coded this function in the type body to return the value of stuId, as follows

Line 1. CREATE OR REPLACE TYPE BODY Student Type 1 IS.
Line 2. MAP MEMBER FUNCTION get s t u I d RETURN VARCHAR 2 IS.
Line 3. BEGIN.
Line 4. RETURN s t u I d semicolon.
Line 5. END semicolon.
Line 6. Open angled bracket code for other member functions close angled bracket.
Line 7. END semicolon.

Then Oracle would use its built-in method of comparing VARCHAR2 values applied to the stuId values whenever we compared StudentType objects, because we listed this method as MAP. For example, for the query

Line 1. SELECT s dot s t u I d comma s dot last Name comma s dot first Name.
Line 2. FROM New Students 1 s.
Line 3. ORDER BY VALUE open parentheses s close parentheses semicolon.

the ordering will be by the value of stuId.

Users can instead write their own comparison method, called an order method, to tell Oracle how to compare two objects of a UDT. If we had chosen to write a compareAge() function in the type definition and make it an order method by declaring

ORDER MEMBER FUNCTION compare Age open parentheses s Student Type 1 close parentheses RETURN NUMBER semicolon.

we could write code for the function in the type body as follows

Line 1. CREATE OR REPLACE TYPE BODY Student Type 1 AS.
Line 2. ORDER MEMBER FUNCTION compare Age open parentheses s Student Type close parentheses RETURN NUMBER IS.
Line 3. BEGIN.
Line 4. IF open parentheses self dot date Of Birth less than s dot date Of Birth close parentheses THEN RETURN 1 semicolon.
Line 5. ELSE IF open parentheses self dot date Of Birth greater than s dot date Of Birth close parentheses THEN RETURN negative 1 semicolon.
Line 6. ELSE RETURN 0 semicolon.
Line 7. END IF semicolon.
Line 8. END IF semicolon.
Line 9. END semicolon.

Then Oracle would always compare two StudentType1 objects based on age, not stuId. The previous query would return the rows in order by age. A UDT can have at most one map method or order method for the entire type. A subtype can create its own map method if its root supertype has one, but not its own order method.

9.7.4 Reference Types

In strictly relational databases, foreign keys are used to establish relationships between tables. For example, in the relational model, if we assume each student has an advisor who is a faculty member, the corresponding facId is identified as a foreign key when we create the Student table. Object-relational systems use a similar mechanism, allowing attributes of a type that are references or pointers to another type. By default, the value for a reference is the OID of the referenced object, not the value of the primary key. For example, if we define FacultyType2 as an object, we can create a new StudentType2 with a reference, advisor, to FacultyType2 as shown in FIGURE 9.11(A), using Oracle syntax

Line 1. CREATE OR REPLACE TYPE Student Type 2 AS OBJECT open parentheses.
Line 2. Dot, dot, dot.
Line 3. advisor R E F Faculty Type 2 comma.
Line 4. Dot, dot, dot.

After we create the Faculty2 table, we can create a new Students2 table. We can specify the scope for the reference attribute, limiting the reference values to the new Faculty2 table instead of permitting them to refer to any FacultyType2 row, regardless of what table it belongs to. The reference attribute, advisor, which is a reference to a FacultyType2, refers to rows in an existing table, Faculty2, as indicated by the scope specification for it. Note that the reference itself specifies the type of object referred to, while the scope specifies the table containing row objects of that type. This limits the allowable values of advisor to OIDs of rows in the Faculty2 table. However, we should also ensure that if one of those rows is deleted, then the advisor value in any Student2 row that points to it is modified, or else we are left with dangling pointers that lead nowhere. This can be done by adding a referential integrity constraint with an ON DELETE option, as shown in Figure 9.11(A).

When we wish to insert a Students2 object, we must use a REF() operator to find the value of the OID of the advisor using a query. If we have already inserted the faculty record for the advisor, as shown in FIGURE 9.11(B), we can then insert a Students2 row with a query to obtain the correct reference for the advisor, as shown in the same figure.

Using REF(f), the value placed in the advisor attribute is the OID of the Faculty2 record. Besides REF(), which returns the REF to a row object, the DEREF() function can be used with references. The DEREF() function takes a REF to an object (normally found in another object table) and returns the row object for that REF. If we write a query on the Students2 table, we can follow the reference from the advisor and get the Faculty2 row for the advisor, as shown in Figure 9.11(B). The query will return the values in the Faculty2 object for F101. In Oracle, we can use dot notation to create a path expression that allows us to follow the reference. For example, the last query shown in Figure 9.11(B) finds a student’s first and last name and the name and department of his or her advisor. Notice that this query returns values from both tables, even though only the Students2 table is named in the FROM clause. This is not a join operation. The result is found by following the REF from Students2 row to the corresponding Faculty2 row.

Line 1. CREATE OR REPLACE TYPE Faculty Type 2 AS OBJECT open parentheses
Line 2. fac I d VARCHAR2 open parentheses 6 close parentheses comma
Line 3. CREATE TABLE Faculty 2 OF FacultyType 2 open parentheses
Line 4. CONSTRAINT Fac 2 underscore fac I d underscore p k PRIMARY KEY open parentheses fac I d close parentheses comma
Line 5. CONSTRAINT Fac 2 underscore rank underscore c c CHECK open parentheses rank IN open parentheses single quote Instructor single quote comma single quote Assistant single quote comma single quote Associate single quote comma single quote Professor single quote close parentheses close parentheses close parentheses semicolon
Line 6. CREATE OR REPLACE TYPE Student Type 2 AS OBJECT open parentheses
Line 7. s t u I d VAR CHAR 2 open parentheses 6 close parentheses comma
Line 8. last Name VAR CHAR 2 open parentheses 20 close parentheses comma
Line 9. first Name VAR CHAR 2 open parentheses 20 close parentheses comma
Line 10. address Address Type comma
Line 11. advisor R E F FacultyType2 comma
Line 12. credits NUMBER open parentheses 3 close parentheses comma
Line 13. date Of Birth DATE close parentheses
Line 14. INSTANTIABLE
Line 15. NOT FINAL
Line 16. forward slash
Line 17. CREATE TABLE Students 2 OF StudentType 2 open parentheses
Line 18. CONSTRAINT S t u 2 underscore s t u I d underscore p k PRIMARY KEY open parentheses s t u I d close parentheses close parentheses semicolon
Line 19. ALTER TABLE Students 2 ADD open parentheses SCOPE FOR open parentheses advisor close parentheses IS Faculty 2 close parentheses semicolon
Line 20. ALTER TABLE Students 2 ADD CONSTRAINT S t u 2 underscore a d v i s underscore f k FOREIGN KEY open parentheses advisor close parentheses REFERENCES Faculty 2
Line 21. ON DELETE SET NULL semicolon
Line 22. name VAR CHAR 2 open parentheses 20 close parentheses comma
Line 23. dept VAR CHAR 2 open parentheses 20 close parentheses comma
Line 24. rank VAR CHAR 2 open parentheses 15 close parentheses close parentheses
Line 25. forward slash

FIGURE 9.11(A) StudentType2 with a Ref Attribute

Line 1. INSERT INTO Faculty 2
Line 2. VALUES open parentheses Faculty Type 2 open parentheses single quote F 101 single quote comma single quote Smith single quote comma single quote History single quote comma single quote Associate single quote close parentheses close parentheses semicolon
Line 3. INSERT INTO Students 2 VALUES open parentheses Student Type 2 open parentheses single quote S 555 single quote comma single quote Hughes single quote comma single quote John single quote comma Address Type open parentheses single quote 101 Oak
Lane single quote comma single quote Austin single quote comma single quote T X single quote comma single quote 73301 single quote close parentheses comma open parentheses SELECT REF open parentheses f close parentheses FROM faculty 2 f WHERE f a c i d equals single quote F101 single quote close parentheses comma 0 comma
 single quote 01 hyphen Jan hyphen 2005 single quote close parentheses close parentheses semicolon
Line 4. SELECT DEREF open parentheses s dot advisor close parentheses FROM Students 2 s WHERE s t u i d equals single quote S 555 single quote semicolon
Line 5. SELECT s t u i d comma last name comma first name comma s dot advisor dot name comma s dot advisor dot dept FROM Students 2 S WHERE
s t u i d equals single quote S 555 single quote semicolon

FIGURE 9.11(B) Adding Ref Values and Querying Using Ref Attributes

In a nondistributed, nonreplicated environment, the user can choose the primary key as the OID. The selection is specified in the CREATE TABLE command, as in

Line 1. CREATE TABLE My Faculty OF Faculty Type 2 open parentheses
Line 2. CONSTRAINT My Faculty underscore f a c I d underscore p k PRIMARY KEY close parentheses
Line 3. OBJECT IDENTIFIER PRIMARY KEY semicolon

For references to objects where the object identifier is the primary key, the scope clause is required.

9.7.5 Type Hierarchies in Standard SQL

Object types can participate in type hierarchies, in which subtypes inherit all attributes and operations of their supertypes, but they may have additional attributes and operations of their own. As discussed in Section 9.7.3, when defining a new type, the user can declare it as FINAL, which means that no subtypes can be defined for it, or NOT FINAL, which allows subtypes to be created if a class is defined as NOT INSTANTIABLE, we cannot create instances of that type, but if it has subtypes, instances of the subtypes can be created, provided the subtypes themselves are instantiable. Using our previously defined type, StudentType2 from Figure 9.11, which was NOT FINAL, we can define the subtype UndergraduateType by writing

Line 1. CREATE TYPE Undergraduate Type UNDER Student Type 2 AS open parentheses
Line 2. major VAR CHAR 2 open parentheses 15 close parentheses close parentheses
Line 3. INSTANTIABLE
Line 4. NOT FINAL semicolon

UndergraduateType objects inherit all the attributes of StudentType2 objects and have an additional attribute, major. They also inherit any methods defined for StudentType2 but have their own constructor, observer, and mutator methods for major, and they can have their own user-defined methods.

We could continue in this fashion, creating a type called FreshmanType under UndergraduateType.

Line 1. CREATE TYPE Freshman Type UNDER Undergraduate Type AS open parentheses
peer Mentor VAR CHAR open parentheses 25 close parentheses close parentheses
Line 2. INSTANTIABLE
Line 3. FINAL semicolon

We could continue to create types for sophomores, juniors, and seniors under UndergraduateType.

For graduate students, we could write a definition for GraduateStudentType under StudentType2, similar to the one for UndergraduateType, this time specifying the graduate program that the student is enrolled in as an attribute. We could also create the subtype TeachingAssistantType under GraduateStudentType. In Figure 9.4 we also had TeachingAssistant as a subtype of Faculty. However, multiple inheritance is not allowed in the SQL standard or Oracle, so we would not be able to make TeachingAssistant a subtype of FacultyType as well. Standard SQL allows tables and subtables to be created for supertypes and subtypes, with the condition that no object can be inserted into both a supertable and its subtable.

9.7.6 Type Hierarchies in Oracle

Oracle supports the creation of types and subtypes exactly as in the SQL standard, but it does not allow subtables to be created under existing tables. Therefore, although we can create subtypes under StudentType2 as we did in the previous section, as shown in FIGURE 9.12(A) and FIGURE 9.12(B), we cannot create subtables for the subtypes under the Students2 table. Instead, all the subtypes can be placed in the Students2 table shown in Figure 9.11(A).

In Oracle, subtypes can be substituted for supertypes as object columns or rows, in object tables or views. This property is known as substitutability. We can therefore insert undergraduate records and freshman records in the Students2 table, which is called a substitutable table, by using the appropriate constructor for the subtype, as shown in FIGURE 9.12(C).

Line 1. CREATE OR REPLACE TYPE Undergraduate Type UNDER Student Type 2 open parentheses
major VAR CHAR 2 open parentheses 15 close parentheses close parentheses
Line 2. INSTANTIABLE
Line 3. NOT FINAL semicolon
 Line 1. CREATE OR REPLACE TYPE Freshman Type UNDER Undergraduate Type open parentheses
peer Mentor VAR CHAR 2 open parentheses 25 close parentheses close parentheses
Line 2. INSTANTIABLE
Line 3. FINAL semicolon
Line 1. INSERT INTO Students 2 VALUES
Line 2. open parentheses Student Type 2 open parentheses single quote S 444 single quote comma single quote Klein single quote comma single quote Susan single quote comma Address Type open parentheses single quote 123 Hudson Street single quote comma
 single quote New York single quote comma single quote N Y single quote comma single quote 10001 single quote close parentheses comma open parentheses SELECT REF open parentheses f close parentheses FROM Faculty 2 f WHERE f a c I d equals single quote F 101 single quote close parentheses comma 36 comma
 single quote 14 hyphen Mar hyphen 2004 single quote close parentheses close parentheses semicolon
Line 3. INSERT INTO Students 2 VALUES
Line 4. open parentheses Undergraduate Type open parentheses single quote S 666 single quote comma single quote Logan single quote comma single quote Randolph single quote comma null comma null comma 12 comma single quote 23 hyphen May hyphen 2001 single quote comma single quote Spanish single quote close parentheses close parentheses semicolon
Line 5. INSERT INTO Students 2 VALUES
Line 6. open parentheses Freshman Type open parentheses single quote S 777 single quote comma single quote Miller single quote comma single quote Terrence single quote comma Address Type
Line 7. open parentheses single quote 999 Salmon Street single quote comma single quote Sitka single quote comma single quote AK single quote comma single quote 99835 single quote close parentheses comma open parentheses SELECT REF open parentheses f close parentheses FROM Faculty 2 f WHERE
Line 8. f a c I d equals single quote F 101 single quote close parentheses comma 30 comma single quote 30 hyphen Jun hyphen 2005 single quote comma single quote Math single quote comma single quote Tom Smith single quote close parentheses close parentheses semicolon

FIGURE 9.12 Hierarchies in Oracle

Every row in the substitutable table is, of course, a Students2 tuple, but some belong to other subtypes as well. Every tuple in a substitutable table has a most specific type, which is the closest subtype it belongs to—the subtype whose constructor was used when it was created.

To retrieve data from a substitutable table, we can use the VALUE function, which ordinarily returns the attribute values of tuples, including all subtypes in the result, as shown in FIGURE 9.13(A).

This query will show all the data for all the rows, including the reference values. We can improve the format of the results by specifying the attributes to be displayed.

We can limit the query to the supertype and exclude the subtypes by writing the keyword ONLY, as in FIGURE 9.13(B). This query will find only those students who are not undergraduate or freshmen subtypes—or any other subtype of Students2, if we had created others. It selects only those whose most specific subtype is StudentType2.

To limit the query to undergraduate students, we can specify that the row object instances must be of type UndergraduateType, using IS OF (type) as shown in FIGURE 9.13(C).

The results include all UndergraduateType rows that satisfy the condition, including FreshmanType objects. To eliminate the FreshmanType objects, we could write IS OF (ONLY UndergraduateType). The ONLY clause limits the return to tuples whose most specific type is UndergraduateType.

If we wish to retrieve specific columns, we can list them in the SELECT line, as usual. However, for columns that appear only in a subtype, we cannot simply list the column names in the SELECT line, because the column does not appear in the declaration of the type of the table listed in the FROM line. For example, peerMentor does not appear as a column in the Students2 table, so we cannot write SELECT s.peerMentor FROM Students2 s.... The TREAT() function allows us to treat a Students2 tuple as a FreshmanType tuple in order to examine the peerMentor attribute as shown in FIGURE 9.13(D).

If an Oracle type or subtype has a REF attribute, the DEREF operator can be used as described earlier.

Line 1. SELECT VALUE open parentheses s close parentheses.
Line 2. FROM Students 2 s semicolon
Line 1. SELECT s dot s t u I d comma s dot last Name comma s dot first Name comma s dot credits.
Line 2. FROM Students 2 s.
Line 3. WHERE VALUE open parentheses s close parentheses IS OF open parentheses ONLY Student Type 2 close parentheses semicolon.
Line 1. SELECT s dot s t u I d comma s dot last Name comma s dot first Name comma s dot credits.
Line 2. FROM Students 2 s.
Line 3. WHERE VALUE open parentheses s close parentheses IS OF open parentheses Undergraduate Type close parentheses semicolon.
Line 1. SELECT last Name comma first Name comma TREAT open parentheses VALUE open parentheses s close parentheses AS.
Line 2. Freshman Type close parentheses dot peer Mentor.
Line 3. FROM Students 2 s.
Line 4. WHERE VALUE open parentheses s close parentheses IS OF open parentheses Freshman Type close parentheses semicolon.

FIGURE 9.13 Retrieving Hierarchical Data from an Oracle Substitutable Table

9.7.7 Nested Tables in Oracle

A nested table is created using a single built-in type or object type table, which is then placed in another table. FIGURE 9.14 shows a ContactList table nested inside the Students3 table. For this example, we create ContactType and then create ContactListType that is an object table of ContactType to hold names and telephone numbers of a student’s parents, spouse, guardian, or other contacts, as shown in FIGURE 9.15(A).

A table titled Students 3. The table has 7 columns labeled s t u I d, last Name, first Name, address, Advisor, credits, and contact List. The contact List column consists of 4 columns labeled last Name first Name, relationship, and phone number. The row entry of the first 6 columns is as follows.
s t u I d: S 999. Last name: Smith. fist Name: John. Address: null. Advisor: Null. Credits: 0.
The row entries of the contact list column are as follows.
Row 1. last Name: Smith. first Name: Marjorie. Relationship: mother. Phone Number: 2017771234.
Row 2. last Name: Smith. first Name: Frank. Relationship: father. Phone Number: 9177778888.

FIGURE 9.14 A Nested Table

We nest the table in a new Students3 table. We define StudentType3 by adding as an attribute contactList of contactListType, as shown in FIGURE 9.15(B). When we create the Students3 table, we specify that it has a nested table, as shown in FIGURE 9.15(C).

Note that we must identify a name for a storage table for the nested table, which we called contactListStorageTable in our example. This is a separate table from Students3. We specify the primary key of the nested table to include nested_table_id, which is a hidden column created by Oracle that associates the rows of this contact table with the corresponding Students3 row. All the rows for contacts of a particular student have the same nested_table_id, so we added lastName and firstName to the primary key to guarantee uniqueness. These are the last and first names of the student’s contacts.

To insert data in the subtable, we first create a row for the owner table, Students3, including a parameterless call to the constructor for the subtable, as shown in FIGURE 9.15(D). The constructor creates an empty instance in the subtable, into which we can then insert data using an INSERT INTO TABLE statement, as shown in FIGURE 9.15(E). We can continue to insert as many contacts as we wish for this student or go on to create other Students3 rows and their contact lists.

Nested tables can be unnested using the TABLE keyword to flatten the table, as shown in FIGURE 9.15(F). The result will be a multiset with a flattened list where student names will be repeated for each of their contacts (one contact per line). If a type or subtype has a nested table, the TABLE keyword can also be used to unnest the table. ORDER BY and GROUP BY clauses can be used for queries on subtypes just as they were for other types.

Line 1. CREATE OR REPLACE TYPE Contact Type AS OBJECT open parentheses
Line 2. CREATE OR REPLACE TYPE Contact List Type AS TABLE OF Contact Type semicolon
Line 3. forward slash
Line 4. last Name VAR CHAR 2 open parentheses 15 close parentheses comma
Line 5. first Name VAR CHAR 2 open parentheses 12 close parentheses comma
Line 6. relationship VAR CHAR 2 open parentheses 15 close parentheses comma
Line 7. phone Number VAR CHAR 2 open parentheses 10 close parentheses close parentheses semicolon
Line 8. forward slash
Line 1. CREATE OR REPLACE TYPE student Type 3 AS OBJECT open parentheses
contact List contact List Type close parentheses
Line 2. INSTANTIABLE
Line 3. NOT FINAL semicolon
Line 4. forward slash
Line 5. s t u I d VAR CHAR 2 open parentheses 6 close parentheses comma
Line 6. last Name VAR CHAR 2 open parentheses 20 close parentheses comma
Line 7. first Name VAR CHAR 2 open parentheses 20 close parentheses comma
Line 8. address Address Type comma
Line 9. advisor R E F Faculty Type 2 comma
Line 10. credits NUMBER open parentheses 3 close parentheses comma
Line 11. date Of Birth DATE comma
Line 1. CREATE TABLE Students 3 OF Student Type 3 open parentheses
Line 2. CONSTRAINT S t u 3 underscore s t u I d underscore p k PRIMARY KEY open parentheses s t u I d close parentheses close parentheses
Line 3. OBJECT I D PRIMARY KEY
Line 4. NESTED TABLE contact List
Line 5. STORE AS contact List Storage Table open parentheses
Line 6. open parentheses PRIMARY KEY open parentheses nested underscore table underscore id comma last Name comma first Name close parentheses close parentheses close parentheses semicolon
Line 1. INSERT INTO Students 3 open parentheses s t u I d comma last name comma first name comma credits comma contact List close parentheses
Line 2. VALUES open parentheses single quote S 999 single quote comma single quote Smith single quote comma single quote John single quote comma 0 comma contact List Type open parentheses close parentheses close parentheses semicolon
Line 1. INSERT INTO TABLE open parentheses SELECT s dot contact List
Line 2. FROM Students 3 s
Line 3. WHERE s dot s t u I d equals single quote S 999 single quote close parentheses
Line 4. VALUES open parentheses single quote Smith single quote comma single quote Marjorie single quote comma single quote mother single quote comma single quote 2017771234 single quote close parentheses semicolon
Line 5. INSERT INTO TABLE open parentheses SELECT s dot contact List
Line 6. FROM Students 3 s
Line 7. WHERE s dot s t u I d equals single quote S 999 single quote close parentheses
Line 8. VALUES open parentheses single quote Smith single quote comma single quote Frank single quote comma single quote father single quote comma single quote 9177778888 single quote close parentheses semicolon
Line 1. SELECT s dot last Name comma s dot first Name comma c dot asterisk.
Line 2. FROM Students 3 s comma TABLE open parentheses s dot contact List close parentheses c.
Line 3. WHERE s dot credits less than or equal to 60 semicolon.

FIGURE 9.15 Nested Tables in Oracle

9.7.8 Oracle Object Views

Oracle allows users of strictly relational Oracle databases to view them as OR ones using a mechanism called an object view. An object view is constructed by defining an object type in which each attribute corresponds to a column of an existing relational table. The object view is created using a SELECT statement, in the same manner that we would create a relational view, except that we must specify an OID, saying which attribute(s) will be used to identify each row of the view. This identifier, which is usually the primary key, can be used to create reference attributes if desired. To guarantee safety of updates in the object view, users can write INSTEAD OF triggers. The object view can then be treated as if it were an object table. If we had a purely relational Faculty3 table, defined as shown in FIGURE 9.16(A), we could define a type, FacultyType, as shown in FIGURE 9.16(B).

Note that we include the keywords AS object as we normally do when we create an object type in Oracle. We could create an object view, Faculty3View, specifying the OID, facId, as shown in FIGURE 9.16(C).

Users can then refer to the attributes of the object view using object notation, write methods for the type, and use other OR features as if it were a user-defined structured type. Application programmers can treat the relational database as if its structure corresponded directly to the objects they create in their OO programs. FIGURE 9.16(D) shows a query on the object view.

Line 1. CREATE TABLE Faculty 3 open parentheses
Line 2. INSERT INTO Faculty 3 VALUES open parentheses 9999 comma single quote Lopez single quote comma single quote Janet single quote comma single quote History single quote comma single quote Professor single quote comma 75000 close parentheses semicolon
Line 3. fac I d NUMBER open parentheses 4 close parentheses PRIMARY KEY comma
Line 4. last Name VAR CHAR 2 open parentheses 15 close parentheses comma
Line 5. first Name VAR CHAR 2 open parentheses 10 close parentheses comma
Line 6. dept VAR CHAR 2 open parentheses 10 close parentheses comma
Line 7. rank VAR CHAR 2 open parentheses 10 close parentheses comma
Line 8. salary NUMBER open parentheses 8 comma 2 close parentheses close parentheses semicolon
Line 1. CREATE OR REPLACE TYPE Faculty 3 Type AS OBJECT open parentheses
Line 2. f I d NUMBER open parentheses 4 close parentheses comma
Line 3. l Name VAR CHAR 2 open parentheses 15 close parentheses comma
Line 4. f Name VAR CHAR 2 open parentheses 10 close parentheses comma
Line 5. department VAR CHAR 2 open parentheses 10 close parentheses comma
Line 6. r n k VAR CHAR 2 open parentheses 10 close parentheses close parentheses semicolon
Line 7. forward slash
Line 1. CREATE VIEW Faculty 3 View OF Faculty 3 Type WITH OBJECT
Line 2. IDENTIFIER open parentheses f I d close parentheses AS
Line 3. SELECT f dot f a c I d comma f dot last Name comma f dot first Name comma f dot dept comma f dot rank
Line 4. FROM Faculty 3 f semicolon

Line 1. SELECT v dot l Name comma v dot department comma v dot r n k comma R E F open parentheses v close parentheses comma VALUE open parentheses v close parentheses
Line 2. FROM Faculty 3 View v
Line 3. WHERE v dot f name equals single quote Janet single quote semicolon

FIGURE 9.16 Using Oracle’s Object View to Simulate Object Tables

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.109.234