Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
29
Добавлен:
16.04.2013
Размер:
5.97 Mб
Скачать

Manipulating Objects through SQL

You must use the function DEREF or make calls to the package UTL_REF to access the object. For some examples, see "Using Function DEREF" on page 12-20.

Forward Type Definitions

You can refer only to schema objects that already exist. In the following example, the first CREATE TYPE statement is not allowed because it refers to object type Department, which does not yet exist:

CREATE TYPE Employee AS OBJECT ( name VARCHAR2(20),

dept REF Department, -- not allowed

...

);

CREATE TYPE Department AS OBJECT ( number INTEGER,

manager Employee,

...

);

Switching the CREATE TYPE statements does not help because the object types are mutually dependent. Object type Employee has an attribute that refers to object type Department, and object type Department has an attribute of type Employee. To solve this problem, you use a special CREATE TYPE statement called a forward type definition, which lets you define mutually dependent object types.

To debug the last example, simply precede it with the following statement:

CREATE TYPE Department; -- forward type definition

-- at this point, Department is an incomplete object type

The object type created by a forward type definition is called an incomplete object type because (until it is defined fully) it has no attributes or methods.

An impure incomplete object type has attributes but causes compilation errors because it refers to an undefined type. For example, the following CREATE TYPE statement causes an error because object type Address is undefined:

CREATE TYPE Customer AS OBJECT ( id NUMBER,

name VARCHAR2(20),

addr Address, -- not yet defined phone VARCHAR2(15)

);

This lets you defer the definition of object type Address. The incomplete type Customer can be made available to other application developers for use in refs.

Manipulating Objects through SQL

You can use an object type in the CREATE TABLE statement to specify the datatype of a column. Once the table is created, you can use SQL statements to insert an object, select its attributes, call its methods, and update its state.

Note: Access to remote or distributed objects is not allowed.

In the SQL*Plus script below, the INSERT statement calls the constructor for object type Rational, then inserts the resulting object. The SELECT statement retrieves the value of attribute num. The UPDATE statement calls member method reciprocal(),

Using PL/SQL Object Types 12-17

Manipulating Objects through SQL

which returns a Rational value after swapping attributes num and den. Notice that a table alias is required when you reference an attribute or method. (For an explanation, see Appendix D.)

CREATE TABLE numbers (rn Rational, ...)

/

INSERT INTO numbers (rn) VALUES (Rational(3, 62)) -- inserts 3/62

/

SELECT n.rn.num INTO my_num FROM numbers n ... -- returns 3

/

UPDATE numbers n SET n.rn = n.rn.reciprocal() ... -- yields 62/3

When you instantiate an object this way, it has no identity outside the database table. However, the object type exists independently of any table, and can be used to create objects in other ways.

In the next example, you create a table that stores objects of type Rational in its rows. Such tables, having rows of objects, are called object tables. Each column in a row corresponds to an attribute of the object type. Rows can have different column values.

CREATE TABLE rational_nums OF Rational;

Each row in an object table has an object identifier, which uniquely identifies the object stored in that row and serves as a reference to the object.

Selecting Objects

Assume that you have run the following SQL*Plus script, which creates object type Person and object table persons, and that you have populated the table:

CREATE TYPE Person AS OBJECT ( first_name VARCHAR2(15), last_name VARCHAR2(15), birthday DATE, home_address Address, phone_number VARCHAR2(15))

/

CREATE TABLE persons OF Person

/

The following subquery produces a result set of rows containing only the attributes of Person objects:

BEGIN

INSERT INTO employees -- another object table of type Person

SELECT * FROM persons p WHERE p.last_name LIKE '%Smith';

To return a result set of objects, you must use the function VALUE, which is discussed in the next section.

Using Function VALUE

As you might expect, the function VALUE returns the value of an object. VALUE takes as its argument a correlation variable. (In this context, a correlation variable is a row variable or table alias associated with a row in an object table.) For example, to return a result set of Person objects, use VALUE as follows:

BEGIN

INSERT INTO employees

SELECT VALUE(p) FROM persons p

12-18 PL/SQL User's Guide and Reference

Manipulating Objects through SQL

WHERE p.last_name LIKE '%Smith';

In the next example, you use VALUE to return a specific Person object:

DECLARE

p1 Person;

p2 Person;

...

BEGIN

SELECT VALUE(p) INTO p1 FROM persons p WHERE p.last_name = 'Kroll';

p2 := p1;

...

END;

At this point, p1 holds a local Person object, which is a copy of the stored object whose last name is 'Kroll', and p2 holds another local Person object, which is a copy of p1. As the following example shows, you can use these variables to access and update the objects they hold:

BEGIN

p1.last_name := p1.last_name || ' Jr';

Now, the local Person object held by p1 has the last name 'Kroll Jr'.

Using Function REF

You can retrieve refs using the function REF, which, like VALUE, takes as its argument a correlation variable. In the following example, you retrieve one or more refs to Person objects, then insert the refs into table person_refs:

BEGIN

INSERT INTO person_refs

SELECT REF(p) FROM persons p

WHERE p.last_name LIKE '%Smith';

The next example retrieves a ref and attribute at the same time:

DECLARE

 

p_ref

REF Person;

taxpayer_id VARCHAR2(9); BEGIN

SELECT REF(p), p.ss_number INTO p_ref, taxpayer_id FROM persons p

WHERE p.last_name = 'Parker'; -- must return one row

END;

This example, updates the attributes of a Person object:

DECLARE

 

p_ref

REF Person;

my_last_name VARCHAR2(15); BEGIN

SELECT REF(p) INTO p_ref FROM persons p WHERE p.last_name = my_last_name;

UPDATE persons p

SET p = Person('Jill', 'Anders', '11-NOV-67', ...) WHERE REF(p) = p_ref;

END;

Using PL/SQL Object Types 12-19

Manipulating Objects through SQL

Testing for Dangling Refs

If the object to which a ref points is deleted, the ref is left dangling, pointing to a nonexistent object. To test for this condition, you can use the SQL predicate IS DANGLING. For example, suppose column manager in relational table department holds refs to Employee objects stored in an object table. You can use the following UPDATE statement to convert any dangling refs into nulls:

UPDATE department SET manager = NULL WHERE manager IS DANGLING;

Using Function DEREF

You cannot navigate through refs within PL/SQL procedural statements. Instead, you must use the function DEREF in a SQL statement to dereference a pointer, and get the value to which it points. DEREF takes a reference to an object, and returns the value of that object. If the ref is dangling, DEREF returns a null object.

The following example dereferences a ref to a Person object. You can select from the dummy table DUAL because each object stored in an object table has a unique object identifier, which is part of every ref to that object.

DECLARE

p1 Person; p_ref REF Person; name VARCHAR2(15);

BEGIN

/* Assume that p_ref holds a valid reference to an object stored in an object table. */

SELECT DEREF(p_ref) INTO p1 FROM dual; name := p1.last_name;

You can use DEREF in successive SQL statements to dereference refs:

CREATE TYPE PersonRef AS OBJECT (p_ref REF Person)

/

DECLARE

 

name

VARCHAR2(15);

pr_ref

REF PersonRef;

pr

PersonRef;

p

Person;

BEGIN

 

/* Assume pr_ref holds a valid reference. */ SELECT DEREF(pr_ref) INTO pr FROM dual; SELECT DEREF(pr.p_ref) INTO p FROM dual; name := p.last_name;

END

/

The next example shows that you cannot use function DEREF within procedural statements:

BEGIN

p1 := DEREF(p_ref); -- not allowed

Within SQL statements, you can use dot notation to navigate through object columns to ref attributes and through one ref attribute to another. You can also navigate through ref columns to attributes by using a table alias. For example, the following syntax is valid:

table_alias.object_column.ref_attribute table_alias.object_column.ref_attribute.attribute table_alias.ref_column.attribute

12-20 PL/SQL User's Guide and Reference

Соседние файлы в папке Oracle 10g