Tải bản đầy đủ (.pdf) (40 trang)

Tài liệu ORACLE8i- P10 pptx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (408.33 KB, 40 trang )

CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES
352
Another option for an object table is to define the primary key of the table to be
the OID, using the OID clause of the CREATE TABLE statement. If you use the pri-
mary key as the OID for the table, it will only be unique to the table itself. This is an
alternative to using the default system-generated OID (a 128 byte, base 64 number),
which is globally unique throughout the database. If you specify that the table should
use the system-generated OID, then you will want to specify the STORAGE clauses for
the related OID index that will be created. Thus, using the system-generated OID will
require more storage space than using the primary key.
Listing 8.9 provides an example of the creation of both the child and the parent
object tables, using a few of the options just described.
Listing 8.9: Creating Object Tables
Drop all types and tables to make this easier.
DROP TABLE child;
DROP TABLE parent;
DROP TYPE parent_type FORCE;
DROP TYPE child_type FORCE;
CREATE OR REPLACE TYPE name_type AS OBJECT(
First_name VARCHAR2(30),
Last_name VARCHAR2(30),
Middle_init CHAR(1) )
/
Create our forward type declaration for the child_type type so we
can create the parent_type type.
CREATE OR REPLACE TYPE child_type
/
Create the parent_type type.
Note the two REFs to the child_type.
CREATE OR REPLACE TYPE parent_type AS OBJECT (
Parent_id NUMBER,


Parent_name name_type,
Parent_address address_type,
Child_name REF child_type,
Exch_student REF child_type)
/
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
353
Now, create the child_type. Again, note the REFs to the
parent_type type.
CREATE OR REPLACE TYPE child_type AS OBJECT (
Parent_id REF parent_type,
Child_id NUMBER,
Child_name name_type,
Child_address address_type,
Teacher REF parent_type)
/
Now, create the parent table. We will use an OID index for this
table. This is generally required for the main table in a
parent/child relationship. The OIDINDEX clause will help speed up
REF lookups between this and the child table.
CREATE TABLE parent
OF parent_type
OIDINDEX idx_parent (TABLESPACE indexes)
TABLESPACE users
PCTFREE 10
PCTUSED 70
STORAGE (INITIAL 100k NEXT 100k PCTINCREASE 0);

Now, we are going to add a primary key constraint to the parent
table.
ALTER TABLE parent ADD
CONSTRAINT pk_parent
PRIMARY KEY (parent_id)
USING INDEX
PCTFREE 10
TABLESPACE indexes
STORAGE (INITIAL 10k NEXT 10k);
CREATE TABLE child
OF child_type
(parent_id WITH ROWID SCOPE IS parent,
teacher WITH ROWID SCOPE IS parent)
OIDINDEX oid_child (TABLESPACE indexes)
TABLESPACE users
STORAGE (INITIAL 100k NEXT 100k PCTINCREASE 0);
USING OBJECT TABLES
Oracle Database
Administration
PART
II
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES
354
There is a lot going on in Listing 8.9, but much of it is building on what you have
already learned (and we will build even more on this example shortly). Let’s dissect
what this code is doing.

First, we drop the types and tables that we will be creating. This just makes the
overall re-creation process much easier. Next, we create a forward type declaration for
the CHILD_TYPE type, since we will need it to create the PARENT_TYPE type. Next,
we create the parent type and then the child type. As before, each type has REFs (ref-
erences) to each other (yes, we know, true evil nastiness).
Then we begin to create the object tables. The first thing you may be wondering
about is the OIDINDEX clause that you see in both CREATE TABLE statements. The
OIDINDEX clause will create an index on the OID of the tables. This is not unlike a
regular index on a primary key. The OID index can significantly speed up REF queries
between object tables. Since both tables will be referencing each other, both indexes
will be helpful. If you had only one table with REFs, then you definitely would want
an OID index on the table being referenced. In this case, an OID index on the other
table—the one that has no references to it—would not be needed.
The parent table creation is a fairly straightforward operation that you have
already seen in earlier examples. The child table creation is a bit different. Here, you
see some new syntax in the form of:
(parent_id WITH ROWID SCOPE IS parent,
teacher WITH ROWID SCOPE IS parent)
What we are doing here is completing what we started. When we defined the
PARENT_ID and TEACHER_ID attributes of the PARENT_TYPE type (in the CREATE
TYPE statement), we used the REF clause to indicate that the PARENT_ID and
TEACHER_ID attributes would reference row objects in some other object table. I’m
sure that you were wondering just what that REF was going to be used for. Well, here is
your answer. When we first created the REF, we didn’t have an actual object to refer-
ence it to. Remember that types are just templates, and beyond that, they do not store
anything. Thus, when you create a type, you don’t need anything to reference an
attribute to. Now that we have created the object tables (and thus allocated some stor-
age to an instance of the PARENT_TYPE), we can define what object these REFs are
referring to. In Listing 8.9, we have two different operations going on. This is known
as scoping the REF.

Also notice in Listing 8.9 that we are storing the ROWID pseudocolumn with the
OID of each row. Like scoping the REF to a specific table, this can speed up certain
query activities. Neither of these actions is required, but taking them will reduce space
requirements and can speed up access to the table being referenced.
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
355
Have you noticed that something is still missing? Think about it for a moment and
see if you can figure out what it is. There is something we still have not done yet, and
that leads us to the topic of altering object tables.
Altering Object Tables
After you create an object table, you may need to later alter the nature of that table.
As you might guess, the ALTER TABLE statement is what you are looking for.
So, going back to the previous section, did you figure out what it was we still
needed to do? What we have not done yet is to scope out the REFs for the parent
table. This is because when we created the parent object table, we had not yet created
the child table. After creating the child table, we can scope the circular references that
are in the parent table, as well as set up the ROWID storage. We execute these opera-
tions in the last two ALTER TABLE statements, shown in Listing 8.10.
Listing 8.10: Altering Object Tables
This enables our circular reference from parent to child for
the parent table. This is the same as the “parent_id WITH
ROWID SCOPE IS parent” line in the CREATE TABLE statement
for the child table. Since the child table was not present
when we created the parent table, we could not do this yet.
Now that the child table has been created, we can create the
scoped REF.
ALTER TABLE parent ADD

(REF(child_name) WITH ROWID, REF(exch_student) WITH ROWID)
/
ALTER TABLE parent ADD
(SCOPE FOR (child_name) IS CHILD,
SCOPE FOR (exch_student) IS CHILD)
/
As you would expect, you can also use the ALTER TABLE statement to change a
number of characteristics of an object table, just as you would a relational table. This
includes STORAGE clauses, partitioning, and so on.
NOTE One big difference between object tables and relational tables is that it is not
possible to add a column to an object table. This is because an object table is wholly
defined by a user-defined type.
USING OBJECT TABLES
Oracle Database
Administration
PART
II
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES
356
Dropping Object Tables
Well, it doesn’t get much simpler than this. You use the DROP TABLE clause to drop
an object table:
DROP TABLE parent;
As you might expect, there are a couple of nasty potential results from dropping an
object table. If you drop a parent table and leave a child table (or even vice-versa, as in
our example), you can end up with dangling REFs—the orphaned table will have ref-

erences to rows in a table that no longer exists. This can also occur if you drop parent
rows but do not clean up the child records. This is bad news, but Oracle has provided
a way to deal with this problem through the use of the ANALYZE command, using the
VALIDATE REF UPDATE SET DANGLING TO NULL option. As explained in the “Intro-
ducing Row and Column Objects, OIDs, and REFs” section earlier in this chapter, this
option will update all ROWIDs for REFs, and set dangling REFs to NULL.
Getting Information about Object Tables
There are a couple of data dictionary views that are useful for managing object tables.
These include the DBA_OBJECT_TABLES view and the DBA_REFS data dictionary views.
The DBA_OBJECT_TABLES View
Do you want to see a listing of object tables? You won’t find them in the DBA_TABLES
view. You’ll need to use the DBA_OBJECT_TABLES view, which provides information
about the object table, such as the owner name, object table name, the tablespace
name that the object table is assigned to, as well as the results of the ANALYZE process
executed against that object table. Here is an example of a query against the
DBA_OBJECT_TABLES view and its results:
SELECT owner, table_name, tablespace_name, initial_extent,
next_extent
FROM dba_object_tables
WHERE owner=’SCOTT’;
OWNER TABLE_NAME TABLESPACE_NAME INITIAL_EXTENT NEXT_EXTENT

SCOTT CHILD USERS 102400 102400
SCOTT PARENT USERS 102400 102400
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
357
NOTE Even though you won’t find object tables in the DBA_TABLES view, you will find

the columns of an object table in the DBA_TAB_COLUMNS view.
The DBA_REFS View
The DBA_REFS data dictionary view describes the REFs present in an attribute of an
object type. This view describes the owner and object that contains the REF, as well as
other information about the REF. Here is an example of a query against this data dic-
tionary view and its results:
SELECT owner, table_name, column_name,is_scoped, scope_table_owner,
scope_table_name
FROM dba_refs
WHERE owner NOT LIKE ‘%SYS%’;
OWNER TABLE_NAME COLUMN_NAME IS_ SCOPE_TABL SCOPE_TABLE_NA

SCOTT CHILD PARENT_ID YES SCOTT PARENT
SCOTT CHILD TEACHER YES SCOTT PARENT
SCOTT PARENT CHILD_NAME NO
SCOTT PARENT EXCH_STUDENT NO
Using Collection Types
If you have had any programming experience, you know what an array is. A collec-
tion is not unlike an array. A collection allows you to store one or more object types in
a given row. In other words, with a collection type, you can denormalize a table, stor-
ing multiple related objects of information in a given row that is related to that infor-
mation. The two collection types in Oracle are VARRAYs and nested tables. Each has
its own distinguishing characteristics, but they are similar in nature.
Working with VARRAYs
A VARRAY (or varying array) is much like an array in a programming language such as
C or BASIC. A VARRAY column allows you to store multiple values in the same allo-
cated datatype. You can define a VARRAY as an attribute of a table or as a volatile ele-
ment in a PL/SQL routine.
USING COLLECTION TYPES
Oracle Database

Administration
PART
II
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES
358
A VARRAY is an ordered set of data elements of the same type. Each element of a
VARRAY contains an index. An index is a number that points to the order of the data
element in the array. Because you need to define the boundaries of the array (or how
many records it can store), the VARRAY is somewhat more limiting than its cousin,
the nested table. Once created, the boundaries of the array cannot be redefined with-
out dropping and re-creating the VARRAY object. A VARRAY cannot contain another
collection type in its definition. Also, VARRAY types cannot store LOBs, while nested
tables can. Finally, a VARRAY has a storage limit of 2GB. These restrictions obviously
limit the effectiveness of the VARRAY collection type.
Just as you can store LOBs out of line in a given object to improve performance,
you can also store VARRAYs out of line with the rest of the data in the object table.
The associated LOB storage segment must be contained in the same tablespace as the
object table. When you define the object that contains the VARRAY, you can force
Oracle to store the data out of line with the DISABLE STORAGE IN ROW clause of the
CREATE TABLE command.
The elements of a VARRAY must be packed, meaning that you need to start with
index 0 for the first record, store the second in index 1, and so on. You cannot store
record one in position two and record three in position four. This also implies that
you cannot remove records from a VARRAY except from the uppermost used index.
Creating VARRAYs
To create a VARRAY, use the CREATE TYPE command, just as you would to create a

user type. When creating a VARRAY, you must provide a type name for that array. The
type name can be a built-in datatype (such as NUMBER or VARCHAR2), a REF, or an
object type (such as ADDRESS_TYPE). Listing 8.11 provides an example of creating a
VARRAY.
Listing 8.11: Creating a VARRAY
DROP TABLE parent;
DROP TYPE address_type FORCE;
DROP TYPE name_type FORCE;
DROP TYPE parent_type FORCE;
First, create the address_type type.
CREATE OR REPLACE TYPE address_type AS OBJECT (
Address_number NUMBER,
Street_address_one VARCHAR2(50),
Street_address_two VARCHAR2(50),
City VARCHAR2(30),
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
359
State VARCHAR2(2),
Zip_code VARCHAR2(10) )
/
CREATE OR REPLACE TYPE address_varray AS VARRAY(5) OF address_type
/
Create the name_type type.
CREATE TYPE name_type AS OBJECT(
First_name VARCHAR2(30),
Last_name VARCHAR2(30),
Middle_init CHAR(1) )

/
Create the parent_type type.
CREATE TYPE parent_type AS OBJECT (
Parent_id NUMBER,
Parent_name name_type,
Parent_address address_varray
)
/
Create the object table with the VARRAY.
CREATE TABLE parent OF parent_type (
PRIMARY KEY (parent_id)
USING INDEX TABLESPACE indexes
STORAGE (INITIAL 10k NEXT 10k PCTINCREASE 0) )
OBJECT ID PRIMARY KEY
VARRAY parent_address STORE AS LOB parent_address_varray
(DISABLE STORAGE IN ROW )
PCTFREE 10
PCTUSED 70
STORAGE (INITIAL 100k NEXT 100k PCTINCREASE 0);
In this example, we begin by dropping the table and types that we will be creating.
This is so we get a fresh start with each creation. Next, we create the ADDRESS_TYPE
type. Following that is the creation of the VARRAY type. Notice that when we create
the VARRAY type, we are, again, just creating a type. There is still no storage associ-
ated with this type; it is just another type defined in the data dictionary. We proceed
to create the other types (NAME_TYPE and PARENT_TYPE) that we will need in the
object table to be created in this example.
USING COLLECTION TYPES
Oracle Database
Administration
PART

II
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES
360
Now comes the fun part—the actual creation of the object table that we call PAR-
ENT. The creation syntax is straightforward. First, we indicate that the parent object
table will be of the type PARENT_TYPE. Next, we define the primary key for the object
table to be the PARENT_ID column, and we use the USING INDEX clause to define
the tablespace and storage characteristics of the primary key index, just as we would
with a normal relational table. Next, we define the OID to be the primary key of the
table. (Recall that the OID is a unique identifier for each row in the table.)
Following the definition of the primary key as the OID, we define the VARRAY that
will be contained in this table, starting with this command:
VARRAY parent_address STORE AS LOB parent_address_varray;
The VARRAY is the attribute PARENT_ADDRESS in the type PARENT_TYPE. We are
storing the VARRAY data as a LOB datatype, and the LOB segment that will be created
is PARENT_ADDRESS_VARRAY. Note the use of the DISABLE STORAGE IN ROW
clause, which is optional. This forces Oracle to store all of the data associated with the
VARRAY out of line, in the LOB segment. If the DISABLE STORAGE IN ROW clause is
not used, or the default ENABLE STORAGE IN ROW clause is used, then the first 4000
bytes of the data (more or less, depending on how finicky Oracle is feeling on a given
day) will be stored in line. The remaining data will be stored out of line in the LOB
segment.
Note that you can also create a VARRAY as a PL/SQL variable, as shown in this
example:
CREATE OR REPLACE TYPE number_varray AS VARRAY(10) OF NUMBER;
Altering and Dropping VARRAYs

There isn’t really anything to alter with regard to a VARRAY. If you need to make
changes to the definition of a VARRAY, you will need to drop the type and re-create it.
This implies that you will need to preserve your data before you make the change. If
you created a VARRAY and then decide that it just isn’t working out, you can drop the
thing (in Nevada, there is no waiting period required). To drop a VARRAY, simply use
the DROP TYPE command.
You can use the ALTER TABLE statement to modify some of the attributes of the
actual VARRAY assigned to the table. This would include the LOB STORAGE clause
(you can change the PCTVERSION and CHUNK parameters, for example). Here is an
example of changing the PCTVERSION:
ALTER TABLE parent
MODIFY VARRAY parent_address
(PCTVERSION 20);
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
361
Note that once you have created or added a VARRAY, you cannot change the set-
ting for storing rows in line.
Working with Nested Tables
The second cousin (once removed) to the VARRAY is the nested table. The nested
table type has the same job as the VARRAY, which is to store repeating data for a sin-
gle row. The primary differences between a nested table and a VARRAY are that a
nested table is not bounded and that the elements of a nested table can be sparsely
populated. If you have a nested table with three elements, you can remove the middle
element without affecting the other elements.
The data in a nested table is stored out of line in an object that you define when
you create the table with the nested table. The table created to store the nested table
data is stored in the same tablespace as the table that the data is associated with, and

this default cannot be changed.
Creating Nested Tables
When you create a nested table, you define a primary key index for the nested object,
just as you would for any other table. You can also define the storage of the nested
table as a hash table, which is the default, or as an index-organized table. As with
VARRAYs, nested tables cannot contain other collection types; thus, a nested table
type cannot contain a reference to another nested table.
Listing 8.12 shows an example of creating a nested table. This example makes the
ADDRESS_TYPE type a nested table in the PARENT table (assume our parents have
multiple homes).
Listing 8.12: Creating a Nested Table
DROP TYPE address_type FORCE;
DROP TYPE address_type_nt FORCE;
DROP TYPE name_type FORCE;
DROP TYPE parent_type FORCE;
DROP TABLE parent;
First, create the address_type type.
CREATE OR REPLACE TYPE address_type AS OBJECT (
Address_number NUMBER,
Street_address_one VARCHAR2(50),
Street_address_two VARCHAR2(50),
City VARCHAR2(30),
USING COLLECTION TYPES
Oracle Database
Administration
PART
II
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com

Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES
362
State VARCHAR2(2),
Zip_code VARCHAR2(10) )
/
Now, create a nested table type.
CREATE TYPE address_type_nt AS TABLE OF address_type
/
Create the name_type type.
CREATE TYPE name_type AS OBJECT(
First_name VARCHAR2(30),
Last_name VARCHAR2(30),
Middle_init CHAR(1) )
/
Create the parent_type type.
CREATE TYPE parent_type AS OBJECT (
Parent_id NUMBER,
Parent_name name_type,
Parent_address address_type_nt
)
/
Create the object table with the nested table.
CREATE TABLE parent OF parent_type (
PRIMARY KEY (parent_id)
USING INDEX TABLESPACE indexes
STORAGE (INITIAL 10k NEXT 10k PCTINCREASE 0) )
OBJECT ID PRIMARY KEY
NESTED TABLE parent_address STORE AS parent_address_nestab (
(PRIMARY KEY ( nested_table_id, address_number ) ) )

TABLESPACE users
PCTFREE 10
PCTUSED 70
STORAGE (INITIAL 100k NEXT 100k PCTINCREASE 0);
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
363
Altering and Dropping Nested Tables
Like VARRAYs, nested tables don’t really have anything to alter, but you might con-
sider using some ALTER TABLE options for active tables containing nested tables. You
can use the ALTER TABLE statement to add a nested table to an existing table. You can
also change the nested table so that it returns the locator value of the data in the
nested table rather than the data contained in it. This is handy for situations where
you might get a great deal of information from a query that includes a nested table.
Since, by default, you would get all of the data in the nested table that met the criteria
of the query, this could end up being a significant amount of data. By using the
RETURN AS LOCATOR clause (and you can create the nested table to do this as well),
Oracle will simply return a locator value that is a pointer to the rows that match the
criteria of the query. You can use the Oracle Call Interface (OCI) interfaces or the
package UTL_COLL_IS_LOCATOR to return the row detail using this value.
Listing 8.13 provides an example of an ALTER TABLE command that you might
run against a relational table with a nested table in it. In this case, the example adds a
nested table of type CHILD_TYPE to the parent table. This particular nested table will
return a locator to any rows that are retrieved by a query, rather than the data itself.
Listing 8.13: Altering a Relational Table That Contains a Nested Table
Drop the type first.
DROP TYPE name_type FORCE;
DROP TYPE name_type_nt FORCE;

DROP TYPE child_type_nt FORCE;
DROP TYPE child_type FORCE;
DROP TABLE parent;
Create the name_type type.
CREATE TYPE name_type AS OBJECT(
First_name VARCHAR2(30),
Last_name VARCHAR2(30),
Middle_init CHAR(1) )
/
Make this a nested table.
CREATE TYPE name_type_nt AS TABLE OF name_type
/
Now, create the child_type.
CREATE OR REPLACE TYPE child_type AS OBJECT (
USING COLLECTION TYPES
Oracle Database
Administration
PART
II
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES
364
Child_id NUMBER,
Child_name name_type
)
/
Now, create a nested table type.

CREATE TYPE child_type_nt AS TABLE OF child_type
/
CREATE TABLE parent (
Parent_id NUMBER PRIMARY KEY,
Parent_name name_type_nt
)
NESTED TABLE parent_name STORE AS parent_name_nestab (
(PRIMARY KEY ( nested_table_id ) ) )
TABLESPACE users
PCTFREE 10
PCTUSED 70
STORAGE (INITIAL 100k NEXT 100k PCTINCREASE 0);
ALTER TABLE parent ADD (child_name child_type_nt)
NESTED TABLE child_name STORE AS parent_child_name_nestab
RETURN AS LOCATOR;
As noted earlier, this example only works on a relational table. Unfortunately, you
cannot add columns to an object table.
Getting Information about Collection Types
If you want to know something about the collection types present in your database,
the DBA_COLL_TYPES view is the place to go. This view will show you the name and
owner of the collection type, what type of collection it is, and other useful informa-
tion. The following is an example of a query against this DBA view and its results.
SELECT owner, type_name, coll_type,
elem_type_owner “EOwner”,
elem_type_name “Ename”
FROM dba_coll_types
WHERE owner NOT LIKE ‘%SYS%’;
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com

Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
365
OWNER TYPE_NAME COLL_TYP EOwner Ename

SCOTT ADDRESS_TYPE_NT TABLE SCOTT ADDRESS_TYPE
SCOTT CHILD_TYPE_NT TABLE SCOTT CHILD_TYPE
SCOTT ADDRESS_VARRAY VARYING SCOTT ADDRESS_TYPE_2
ARRAY
Notice that it indicates the type of collection (nested tables are identified by the
word TABLE and VARRAYs by the words VARYING ARRAY).
To generate a report on all the nested tables defined in your database, use the
DBA_NESTED_TABLES view. Here is an example of a query against this view and its
results:
SELECT owner, table_name, table_type_name, parent_table_column
FROM dba_nested_tables;
OWNER TABLE_NAME TABLE_TYPE_NAME PARENT_TABLE_COLUMN

SCOTT PARENT_NAME_NESTAB NAME_TYPE_NT PARENT_NAME
SCOTT PARENT_CHILD_NAME_NESTAB CHILD_TYPE_NT CHILD_NAME
Notice that the name and owner of the nested table appear in the OWNER and
TABLE_NAME columns (this is the name of the actual segment that is storing the
table data). You also see the type name of the nested table, as shown in the CREATE
TYPE OF TABLE statement, in the TABLE_TYPE_NAME column. In the PARENT_
TABLE_COLUMN column, you find the name of the column that the nested table is
assigned to.
Using Methods
Methods are PL/SQL or Java programs that are associated with user-defined types. In
this chapter, we will stick to PL/SQL methods.
NOTE This chapter includes some examples of using PL/SQL. For more information
about PL/SQL, such as overloading PL/SQL methods, using the AUTHID clause to indicate

if the user or creator’s privileges should be used when executing a method, and other
PL/SQL details, see Appendix F on the CD.
USING METHODS
Oracle Database
Administration
PART
II
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES
366
There are four types of methods that you can associate with any type that you create:
• Constructor methods
• Member methods (including static member methods)
• Map methods
• Order methods
To call a method, you use named decimal notation. In some cases, you can send
parameters to a method; in other cases, you may create methods without any parame-
ters. Constructor methods are created automatically. If you want to use the other
types, you will need to create them.
Using Constructor Methods
A constructor is a PL/SQL function that is created automatically with the creation of
any type or collection object. Constructors are used to insert data into user-defined
datatypes and collection objects, as you will learn in the “Querying Object Types” sec-
tion later in the chapter.
A constructor is named the same as the type that it is based on. Therefore, if a
VARRAY or nested table is based on a type called ADDRESS_TYPE, the constructor is
also called ADDRESS_TYPE. The constructor contains several parameters, one for each

of the attributes of the type it is associated with, in the order that they were created.
Thus, if the type the collection type was based on has three attributes, then the con-
structor will have three parameters.
Working with Member Methods
When creating a member method, you define the method when you issue the CRE-
ATE TYPE statement to create the user-defined type. Just as with other PL/SQL pro-
gram units, you can define a member method to run with the rights of either the
invoker or the creator. Use the AUTHID clause to indicate if the user or creator’s privi-
leges should be used when executing a method. As with a package, you define the
method in the initial definition of the type. You then proceed to create the actual
code for the method by using the CREATE TYPE BODY statement.
When you call an instance of a member method, the first parameter of that method
is always called SELF. This parameter identifies the instance of the object within that
object. SELF is bound automatically when you refer to an object in a method that was
created (instantiated) in that method. If you want to pass the instance of an object to
another method, or reference it in an argument to a function or procedure, you need
to preface the instance of that object with the SELF keyword.
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
367
When using the CREATE TYPE statement to create a method, you can define two
types of member methods: functions or procedures. The methods created can be
defined as either static or member methods. A member method can have any number
of parameters associated with it, and it can also be overloaded.
Static member methods were introduced in Oracle81. This type of method is a deriva-
tive of the member method. It is associated and invoked with the object type, rather
than an instance of that object. A static method, since it is associated with the type
rather than any instance of that type, cannot refer to the attributes of the current object.

If you create a static method, the PL/SQL procedures will not have a SELF parameter.
Creating Member Methods
To create a member method, use the CREATE OR REPLACE TYPE BODY command. In
this command, you define the type and name of the member. If it is a function, you
declare the value type to be returned. Following this is the body of a PL/SQL block of
code. Listing 8.14 provides an example of the creation of a type that contains one
method—a function that returns the name and phone number of the record
selected—followed by the command to create the associated PL/SQL block.
Listing 8.14: Creating a Member Method
First, create the type.
CREATE OR REPLACE TYPE parent_type AS OBJECT
(
first_name VARCHAR2(30),
last_name VARCHAR2(30),
middle_initial CHAR(1),
phone_number VARCHAR2(20),
last_contact DATE,
MEMBER FUNCTION name_and_phone RETURN VARCHAR2
)
/
Now, create the members.
CREATE OR REPLACE TYPE BODY parent_type AS
MEMBER FUNCTION name_and_phone RETURN VARCHAR2 IS
BEGIN
RETURN(SELF.first_name||’ ‘||SELF.last_name||’ Phone:
‘||SELF.phone_number);
END name_and_phone;
END;
/
USING METHODS

Oracle Database
Administration
PART
II
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES
368
Listing 8.14 just creates a template of the user-defined object. What you need to do
next is create an instance of it. Here is an example of creating the table and then
inserting some records into it:
CREATE TABLE parent OF parent_type;
Insert a couple of records.
INSERT INTO parent VALUES
(‘Robert’,’Freeman’,’G’,’904.200.2020’,to_date(‘01-JAN-01’));
INSERT INTO parent VALUES
(‘Deborah’,’Freeman’,’L’,’014.200.2020’,to_date(‘01-MAY-01’));
Now you can use the NAME_AND_PHONE function, like this:
SELECT p.name_and_phone() FROM parent p;
P.NAME_AND_PHONE()

Robert Freeman Phone: 904.200.2020
Deborah Freeman Phone: 904.200.2020
Notice that the method is called using the name of the object (or its alias, as in the
case of the listing above) and then the name of the method.
You can also create and use a member method in PL/SQL, as demonstrated in the
example in Listing 8.15.
Listing 8.15: Creating and Using a Method Instance in PL/SQL

DECLARE
V_output VARCHAR2(60);
V_parent parent_type := parent_type
(‘Robert’,’Freeman’,’G’,’904.200.2020’,to_date(‘01-JAN-01’));
BEGIN
V_output=v_parent.name_and_phone();
END;
/
Creating Static Member Methods
To define a static member method, use the keyword STATIC in both the header and
the body of the code you are using to create the method. The method can refer to an
object passed to it and to the attributes of a new object.
A static method can be used as an alternative to the default constructor method for
a given type. Using a static method, you can create the constructor with a name other
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
369
than the name of the object. Listing 8.16 provides an example of using a static
method associated with an object type.
Listing 8.16: Creating a Static Member Method
DROP TYPE parent_type FORCE;
First, create the type.
CREATE OR REPLACE TYPE parent_type AS OBJECT
(
first_name VARCHAR2(30),
last_name VARCHAR2(30),
middle_initial CHAR(1),
phone_number VARCHAR2(20),

last_contact DATE,
STATIC PROCEDURE my_static_procedure (p_var1 IN VARCHAR2)
)
/
Now, create the members.
CREATE OR REPLACE TYPE BODY parent_type AS
STATIC PROCEDURE my_static_procedure
(p_var1 IN VARCHAR2)
IS
BEGIN
Dbms_output.enable(1000);
Dbms_output.put_line(p_var1||’ Passed into the static Procedure’);
END my_static_procedure;
END;
/
Here is an example of using the static procedure:
SQL> SET SERVEROUTPUT ON
SQL> EXEC parent_type.my_static_procedure(’This is a test of the
procedure!’);
This is a test of the procedure! Passed into the static Procedure!
USING METHODS
Oracle Database
Administration
PART
II
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES

370
Creating Map and Order Methods
Map and order methods are used to facilitate ordering and grouping of attributes in
an object. By default, Oracle supports comparisons of values within an instance of an
object (not the comparison within an instance of an object) only if those compar-
isons are equality or inequality based. A type can have only one order or map
method, so they are mutually exclusive.
Both map and order methods use the SELF parameter. A map method returns a
VARCHAR2 value and requires no other parameters. An order method takes one other
parameter, which represents the value being compared to the current record. The
order method will then return one of three values:
• –1 when the value of SELF is less than the input parameter
• 0 when the value of SELF is equal to that of the input parameter
• 1 when the value of SELF is more than that of the input parameter
Listing 8.17 provides examples of creating map and order methods for a type.
NOTE In Oracle8i, you will find that ordering within an instance of a type works just
fine, without a map or order method.
Listing 8.17: Creating a Map and Order Method
First, create the type.
CREATE OR REPLACE TYPE parent_type AS OBJECT
(
first_name VARCHAR2(30),
last_name VARCHAR2(30),
middle_initial CHAR(1),
phone_number VARCHAR2(20),
last_contact DATE,
MAP MEMBER FUNCTION parent_map RETURN VARCHAR2
)
/
Now, create the map method.

CREATE OR REPLACE TYPE BODY parent_type AS
MAP MEMBER FUNCTION parent_map RETURN VARCHAR2 IS
BEGIN
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
371
Return(SELF.first_name||’ ‘||SELF.last_name);
END;
END;
/
DROP TYPE parent_type FORCE;
First, re-create the type for the order method.
CREATE OR REPLACE TYPE parent_type AS OBJECT
(
first_name VARCHAR2(30),
last_name VARCHAR2(30),
middle_initial CHAR(1),
phone_number VARCHAR2(20),
last_contact DATE,
ORDER MEMBER FUNCTION parent_order (OTHER parent_type)
RETURN NUMBER
)
/
Now, create the order method.
CREATE OR REPLACE TYPE BODY parent_type AS
ORDER MEMBER FUNCTION parent_order (other parent_type)
RETURN NUMBER IS
My_name VARCHAR2(2000):=

self.last_name||self.first_name||self.middle_initial;
compare_name VARCHAR2(2000):=
other.last_name||other.first_name||other.middle_initial;
BEGIN
IF my_name < compare_name
THEN
RETURN -1;
ELSIF my_name < compare_name
THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
USING METHODS
Oracle Database
Administration
PART
II
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES
372
END;
/
Getting Information about Methods
There are a few data dictionary tables that you can use to gather information about
methods (each of these views has a related ALL_ and USER_ version):

• The DBA_METHOD_PARAMS view provides the parameters required for all
methods in the database.
• The DBA_METHOD_RESULTS view describes the method results from all meth-
ods in the database.
• The DBA_TYPE_METHODS view describes all methods associated with all types
in the database.
Querying Object Types
Now that you have created all sorts of objects with types, collections, methods, and so
on, you will want to know how to use DML to add data to these structures. This sec-
tion is all about how to do that.
Using INSERT Statements
The INSERT SQL required for dealing with types and collection objects is somewhat
different than that for dealing with tables that just contain columns. To insert values
into a collection type, you need to use the constructor of the type on which the col-
lection type is based. (Constructors were described earlier in the chapter, in the
“Using Constructor Methods” section.)
For example, here is the code to create a row in a table that contains a collection
type, using the VARRAY in the object table created in Listing 8.11.
INSERT INTO parent (parent_id, parent_name, parent_address) VALUES
(1,
name_type(‘Robert’,’Freeman’,’G’),
(address_varray(
address_type(1,’550 Water St.’,NULL,’Jax’,’Fl’,’32202’),
address_type(2,’500 Water St.’,NULL,’Jax’,’Fl’,’32202’) ) ) );
The INSERT statement starts like any other INSERT statement. It lists the table that
you are inserting into, and then uses the VALUES clause. (You can list each column in
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.

373
parentheses, if you prefer that style.) Next, start listing the values to insert, all
enclosed in parentheses, just as with a normal INSERT statement. First, insert the
value for the PARENT_ID table, which is a NUMBER type. That value is 1.
Next comes the INSERT INTO statement for the PARENT_NAME attribute, which is
of type NAME_TYPE. The NAME_TYPE type consists of three attributes. When you
created the NAME_TYPE type, a constructor was automatically created, just as when
you created ADDRESS_VARRAY. Use the constructor NAME_TYPE() to insert the new
values into the instance of that type, contained in the PARENT table. The instance of
NAME_TYPE in the PARENT table is PARENT_NAME. Since the type NAME_TYPE has
three attributes, the constructor takes three parameters, one for each attribute. For
quick reference, here is the definition of NAME_TYPE:
First_name VARCHAR2(30)
Last_name VARCHAR2(30)
Middle_init CHAR(1)
And here is the part of the INSERT statement that is using the constructor to insert
values into the PARENT_NAME attribute, which is of type NAME_TYPE:
name_type(‘Robert’,’Freeman’,’G’),
Can you see how it works then? The ‘Robert’ will be stored in the FIRST_NAME
attribute, the ‘Freeman’ will be stored in the LAST_NAME attribute, and the middle
initial ‘G’ will be stored in the MIDDLE_INIT attribute.
Adding the multidimensional VARRAY or the nested table to the mix makes this
slightly more complicated, because you now need to provide for multiple rows of data
for one column in one INSERT operation. If you have ever tried to insert more data
than columns, no doubt you have noticed that Oracle traditionally frowns on such an
action. This is not the case with collection types such as VARRAYs. Here are the lines
that create the rows in the VARRAY (recall that the attribute that is the VARRAY is
called PARENT_ADDRESS on the object table):
address_varray(
address_type(1,’550 Water St.’,NULL,’Jax’,’Fl’,’32202’),

address_type(2,’500 Water St.’,NULL,’Jax’,’Fl’,’32202’) ) )
Notice that there are references to two collection types here. First, the ADDRESS_
VARRAY constructor is what allows you to do multiple inserts into the VARRAY using
one INSERT statement. When the VARRAY type is created, this constructor is created
for just that purpose. Next, the ADDRESS_TYPE constructor, which was created when
you created the ADDRESS_TYPE type, is referenced twice. This constructor allows you
to insert actual values into the instance of the type that you created when you created
the PARENT table.
QUERYING OBJECT TYPES
Oracle Database
Administration
PART
II
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES
374
The INSERT INTO statement for the nested table is just like the INSERT INTO state-
ment for the VARRAY, except that the type names change (this next INSERT is based
on the objects created in Listing 8.12):
INSERT INTO parent (parent_id, parent_name, parent_address) VALUES
(2,
name_type(‘Debbie’,’Freeman’,’L’),
(address_type_nt(
address_type(1,’0293 Gonzo Way’,NULL,’Jax’,’Fl’,’32202’),
address_type(2,’500 Water St.’,NULL,’Jax’,’Fl’,’32202’) ) ) );
These examples illustrate that there is a hierarchy of sorts when you are inserting
into objects that contain types. Consider this when you are constructing DML state-

ments to interact with objects that contain various types. The hierarchy starts from
the base type on which the attribute that you want to modify depends. You then
move up through the hierarchical stages using each collector of that type, until you
reach the attribute into which you want to insert.
Using UPDATE Statements
Now that you know how to insert into collection types, you’ll want to know how to
update these same structures. In this section, we will look at updating type columns
in object tables, which will include a review of the PL/SQL built-in functions to access
VARRAYs (which cannot be accessed from SQL directly) and nested tables.
Updating Types
Updating types in object tables is fairly easy. Again, just use named decimal notation,
and you have it. Here is an example of updating a type in an object table:
UPDATE parent p SET p.parent_name.last_name=’Freeman’
WHERE p.parent_name.last_name=’FREEMAN’;
Updating VARRAYs
One of the disadvantages of using VARRAYs is that SQL does not allow piece updates
for them. You can UPDATE an entire table row, however, as in this example:
UPDATE parent
SET parent_address=
Address_varray(
address_type(1,’550 Water St.’,NULL,’Jax’,’Fl’,’32202’)
)
WHERE parent_id=2;
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
375
Note some odd behavior here though. If PARENT_ID is not truly unique when you
execute this statement, and you had two rows with PARENT_ID=2 before you exe-

cuted the statement, you will end up with only one row after the UPDATE. Thus,
when you are updating a VARRAY type, you are really replacing the entire row rather
than updating the VARRAY.
If you want to update individual elements of a VARRAY, you will need to use
PL/SQL to do this. In PL/SQL, Oracle provides several methods (known as static meth-
ods) that allow you to traverse each index element of the VARRAY. Table 8.1 provides
a list of the methods supported for VARRAYs in Oracle8i.
TABLE 8.1: VARRAY ACCESS METHODS SUPPORTED IN PL/SQL
Method Description
COUNT Returns the number of elements in the collection
DELETE Causes the removal of one, all, or a given range of elements in a VARRAY
EXISTS Returns TRUE if the element exists
EXTEND Adds a given number of elements to the VARRAY
FIRST Returns the first index in the VARRAY
LAST Returns the last index in the VARRAY
LIMIT Returns the maximum number of elements in the VARRAY
NEXT Returns the next index number in the VARRAY
PRIOR Returns the previous index number
TRIM Removes one or more elements from a collection
Listing 8.18 provides a sample piece of PL/SQL that adds an element to a VARRAY
and updates an existing record.
Listing 8.18: Maintaining a VARRAY with PL/SQL
DECLARE
V_address_varray address_varray;
BEGIN
SELECT parent_address
INTO v_address_varray
FROM parent
WHERE parent_id=1;
Add to the VARRAY.

v_address_varray.EXTEND;
QUERYING OBJECT TYPES
Oracle Database
Administration
PART
II
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ORACLE OBJECT-ORIENTED FEATURES
376
v_address_varray(v_address_varray.LAST):=
address_type(2,
‘2145 W. Oak’, NULL,
‘Seattle’,’Wa’,’98042’);
Now, we are going to update the first element.
v_address_varray(1).street_address_one:=’Somewhere’;
v_address_varray(1).zip_code:=’00000’;
Now, update the object itself
UPDATE parent SET parent_address=v_address_varray
WHERE parent_id=1;
END;
/
COMMIT;
Notice that the code in Listing 8.18 reads the VARRAY into a PL/SQL variable. You
can then manipulate the VARRAY element in memory with the various access meth-
ods supplied by Oracle. Finally, once you have made the necessary changes, you can
update the entire VARRAY, since this is the only way that SQL supports changing VAR-
RAYs in Oracle.

Updating Nested Tables
Updating nested tables is much easier than updating VARRAYs. This is because Oracle
supports direct updates of each element of a nested table. By using the TABLE expres-
sion to locate the specific record (or records) in the object table you want to manipu-
late, you can change individual columns in the nested table, as in this example:
UPDATE table
(SELECT parent_address FROM parent WHERE parent_id=2)
SET street_address_one=’500 Water St.’
WHERE address_number=1;
Using SELECT Statements
Selecting objects and collections from SQL is, as you might expect, a bit different.
This section describes these differences and how to properly issue SELECT statements
against these different object types.
Selecting from Types
As with updating a type, selecting a type is fairly straightforward. You simply use
named decimal notation to indicate the attribute to update, as in this example:
SELECT parent_id, s.parent_name.last_name,
C
opyright ©2002 SYBEX, Inc., Alameda, CA
www.sybex.com
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×