Thông tin tài liệu
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.
Ngày đăng: 22/01/2014, 00:20
Xem thêm: Tài liệu ORACLE8i- P10 pptx, Tài liệu ORACLE8i- P10 pptx, Migrating an Existing 7.1+ Database to Oracle8i