Loading the “row object” TableHow do we load the Address_table with row objects?One way is to use the existing ADDRESS_OBJ values in some other table e.g., Emp like this: INSERT INTO Add
Trang 1Which gives:
EMPNO NAME - - ADDRESS(STREET, CITY, STATE, ZIP) -
101 Adam ADDRESS_OBJ('1 A St.', 'Mobile', 'AL', '36608')
102 Baker ADDRESS_OBJ('2 B St.', 'Pensacola', 'FL', '32504')
103 Charles ADDRESS_OBJ('3 C St.', 'Bradenton', 'FL', '34209')
Addressing specific columns works as well Specific umns including the composite are addressed by theirname in the result set:
col-SELECT empno, name, address you can use discrete attribute
names FROM emp
Gives:
EMPNO NAME - -
ADDRESS(STREET, CITY, STATE, IP)
-101 Adam ADDRESS_OBJ('1 A St.', 'Mobile', 'AL', '36608')
102 Baker ADDRESS_OBJ('2 B St.', 'Pensacola', 'FL', '32504')
103 Charles ADDRESS_OBJ('3 C St.', 'Bradenton', 'FL', '34209')
Trang 2COLUMN Formatting in SELECT
Since the above output looks sloppy, some column matting is in order:
for-SQL> COLUMN name FORMAT a9
SQL> COLUMN empno FORMAT 999999
SQL> COLUMN address FORMAT a50
SQL> /
Now the above query would give:
EMPNO NAME ADDRESS(STREET, CITY, STATE, ZIP)
- -
-101 Adam ADDRESS_OBJ('1 A St.', 'Mobile', 'AL', '36608')
102 Baker ADDRESS_OBJ('2 B St.', 'Pensacola', 'FL', '32504')
103 Charles ADDRESS_OBJ('3 C St.', 'Bradenton', 'FL', '34209')
Note that here we formatted the entire address fieldand not the individual attributes of the column objects
SELECTing Only One Column in the Composite
Fields within the column object may be addressed vidually A query that recalls names and cities in ourexample might look like this:
indi-SELECT name, e.address.city
Trang 3You must use a table alias and the qualifier
“ADDRESS” with the alias If the alias is not used, thequery will fail with a syntax error
SELECT with a WHERE Clause
In a WHERE clause, alias and qualifier are also used:
SELECT name, e.address.city FROM emp e
WHERE e.address.state = 'FL'
Gives:
NAME ADDRESS.CITY - - Baker Pensacola
Charles Bradenton
Using UPDATE with TYPEed Columns
To use UPDATE, the alias must also be used:
UPDATE emp SET address.zip = '34210' WHERE address.city like 'Brad%'
Gives:
UPDATE emp set address.zip = '34210' WHERE address.city like 'Brad%'
* ERROR at line 1:
ORA-00904: invalid column name
Trang 4Now type,
UPDATE emp e SET e.address.zip = '34210' WHERE e.address.city LIKE 'Brad%'
And,
SELECT * FROM emp
Gives:
EMPNO NAME ADDRESS(STREET, CITY, STATE, ZIP)
- -
-101 Adam ADDRESS_OBJ('1 A St.', 'Mobile', 'AL', '36608')
102 Baker ADDRESS_OBJ('2 B St.', 'Pensacola', 'FL', '32504')
103 Charles ADDRESS_OBJ('3 C St.', 'Bradenton', 'FL', '34210')
Create Row Objects — REF TYPE
What are “row objects”? They are tables containingrows of objects of a defined class that will be refer-enced using addresses to point to another table
Why would you want to use “row objects”? The son is that a table containing row objects is easier tomaintain than objects that are embedded into anothertable We can create a table of rows of a defined typeand then reference the rows in this object table usingthe REF predicate The following example illustratesthis
rea-Create a table that contains only the addressobjects:
CREATE TABLE address_table OF ADDRESS_OBJ
Trang 5Note that the syntax of this CREATE TABLE is ferent from an ordinary CREATE TABLE command
dif-in that the keyword OF plus the object type is used
So far, the newly created table of column objects isempty:
SELECT * FROM address_table
Trang 6Loading the “row object” Table
How do we load the Address_table with row objects?One way is to use the existing ADDRESS_OBJ values
in some other table (e.g., Emp) like this:
INSERT INTO Address_table
SELECT e.address
FROM emp e
Actually, the table alias is not necessary in this mand, but to be consistent, it is better to use the tablealias when it seems that it is required in some state-ments and not required in others
SELECT city
FROM address_table
Trang 7CITY - Mobile
Pensacola Bradenton
A second way to add data to Address_table is to insertjust as one would ordinarily do with a common SQLtable:
INSERT INTO address_table VALUES ('4 D St.', 'Gulf Breeze','FL','32563')
Thus:
SELECT * FROM address_table
Trang 8UPDATE Data in a Table of Row Objects
Updating data in the Address_table table of rowobjects is also straightforward:
In these examples note that no special syntax is
required for inserts or updates
Trang 9CREATE a Table that References Our Row Objects
Now, suppose we create a table that references ourtable of row objects The syntax is a little differentfrom other ordinary CREATE TABLE commands:
CREATE TABLE client (name VARCHAR2(20), address REF address_obj scope is address_table)
Now, if you type:
In the CREATE TABLE command, we defined thecolumn address as referencing address_obj, which iscontained in an object table, Address_table
INSERT Values into a Table that Contains Row Objects (TCRO)
How do we get values into this table that contains rowobjects? One way to begin is to insert into the clienttable and null the address_obj:
INSERT INTO client VALUES ('Jones',null)
Now,
SELECT * FROM client
Trang 10WHERE aa.city LIKE 'Mob%')
WHERE name = 'Jones'
In this query, we find an appropriate row in the
Address_table by constraining the subquery to somerow (here we used aa.city LIKE 'Mob%') Then, weconstrained the UPDATE to the Client table by using
a filter (WHERE name = 'Jones') in the outer query.The inner query must return only one row/value Ifthe subquery were written so that more than one rowwere returned, an error would result:
UPDATE client set address =
(SELECT REF(aa)
FROM address_table aa
WHERE aa.zip like '3%')
WHERE name = 'Jones'
SQL> /
Trang 11Will give the following error:
(SELECT REF(aa)
* ERROR at line 2:
ORA-01427: single-row subquery returns more than one row
SELECT from the TCRO — Seeing Row Addresses
Now that the Client table has been updated, it may beviewed If the statement “SELECT * FROM client” isused, only the address of the reference to the Address_table will be in the result set
SELECT * FROM client
-00002202089036C05DB23C4FDE9B82C00E36D92D0F864BF1821AF245BF97D37D2AC67D A996
DEREF (Dereference) the Row Addresses
If the desired output is the data itself and not theaddress of the data, we must dereference the referenceusing the DEREF function:
SELECT name, DEREF(address) FROM client
Trang 12-ADDRESS_OBJ('1 A St.', 'Mobile', 'AL', '36608')
One-step INSERTs into a TCRO
There is another way to insert data into the table Wecan use a reference to Address_table in the insert with-out going through the INSERT-null-UPDATE
sequence we introduced in the last section:
INSERT INTO client
SELECT 'Walsh', REF(aa)
-ADDRESS_OBJ('11 A Dr', 'Mobile', 'AL', '33608')
Smith
ADDRESS_OBJ('3 C St.', 'Bradenton', 'FL', '34209')
Trang 13Kelly ADDRESS_OBJ('2 B St.', 'Pensacola', 'FL', '32514')
Walsh ADDRESS_OBJ('4 D St.', 'Gulf Breeze', 'FL', '32563')
SELECTing Individual Columns in TCROs
Getting at individual parts of the referencedAddress_table is easier than looking at the whole
“DEREFed” field Recall the description of the Clienttable:
The following query shows that the dereferencing may
Trang 14Note that in the above query, the alias, c, was used forthe Client table A table alias has to be used here Asshown by the following query, you will get an errormessage if a table alias is not used:
SELECT name, address.city
FROM client
Gives the following error message:
SELECT name, address.city FROM client
*
ERROR at line 1:
ORA-00904: "ADDRESS"."CITY": invalid identifier
Deleting Referenced Rows
What happens if you delete a referenced row in
Now delete a row from Address_table:
DELETE FROM address_table
WHERE zip = '32563'
Trang 15And now, SELECT from the Client table that contains
a reference to the Address_table:
SELECT * FROM client
SELECT name, DEREF(address) FROM client
Trang 16-ADDRESS_OBJ('11 A Dr', 'Mobile', 'AL', '33608')
We can, of course, delete the row in the Client table:
DELETE FROM client
WHERE name LIKE 'Wa%'
The Row Object Table and the VALUE Function
Looking again at a version of the table that containsrow objects (TCRO):
Trang 17There is another way to look at the Address_table(which contains row objects) using the VALUEfunction:
SELECT VALUE(aa) FROM address_table aa
Which gives:
VALUE(AA)(STREET, CITY, STATE, ZIP) - ADDRESS_OBJ('11 A Dr', 'Mobile', 'AL', '36608')
ADDRESS_OBJ('22 B Dr', 'Pensacola', 'FL', '32504') ADDRESS_OBJ('33 C Dr', 'Bradenton', 'FL', '34210')
The VALUE function is used to show the values of umn objects, keeping all the attributes of the objecttogether
col-Creating User-defined Functions for Column Objects
In objected-oriented programming one expects notonly to be able to create objects with attributes per theclass definition, but also to be able to create functions
to handle the attributes Not only will the class exhibitproperties (it will have attributes), but it will also havedefined actions (methods) associated with the
attributes
While Oracle provides some aforementioned tions as built-ins (VALUE, REF, DEREF) for objectclasses, it may be convenient to define functions for aclass for some applications Following is an example of
func-a type crefunc-ation (func-a clfunc-ass definition), func-a tfunc-able contfunc-ainingthe type, and the use of a defined function for the class
Trang 18First a type is created as a class containing utes and a function:
attrib-CREATE OR REPLACE TYPE aobj AS object (
state CHAR(2), amt NUMBER(5),
MEMBER FUNCTION mult (times in number) RETURN number,
PRAGMA RESTRICT_REFERENCES(mult, WNDS))
Here, we have defined two columns (attributes) —
state and amt (amount) — as well as a MEMBER
FUNCTION for our class The PRAGMA statement isstandard Oracle practice and says that the function willnot update the database when it is used The function
mult will return the amt multiplied by the value of times When creating a TYPE with a MEMBER
FUNCTION, the line:
MEMBER FUNCTION mult (times in number) RETURN number
is called a “function prototype.” The word “in” in theparameter list of the function prototype means that thevalue of times will be input to the function
The complete definition of the TYPE, like the nition of packages, is called a “specification” or, moreappropriately, an “object specification” (a class defini-tion) To complete the definition of the function wehave to supply a “type body,” much like the packagebody of a CREATE PACKAGE exercise Here is thebody of the TYPE, aobj, for our example:
defi-CREATE OR REPLACE TYPE BODY aobj AS
MEMBER FUNCTION mult (times in number) RETURN number
IS
BEGIN
RETURN times * self.amt; /* SEE BELOW */
END; /* end of begin */
END; /* end of create body */
Trang 19The TYPE BODY must contain the MEMBERFUNCTION line exactly as it appears in the specifica-tion If the function needs to be changed, then thewhole sequence of “create-the-type,” then “create-the-type-body” has to be repeated For packages, the term
“synchronized” is used to describe body, specification matching
type-Now, suppose we create a table that has an ute with our newly defined TYPE (that contains afunction) in it:
attrib-CREATE TABLE aobjtable (arow aobj)
is necessary because to use an object, the object mustfirst be instantiated with the default constructor, aobj.The definition of the “type as object” does not really
create an object per se, but rather creates a class that
is used to instantiate objects To ask Oracle to multiply
some number times a value of amt in an object requires
that you first tell Oracle which object you are
Trang 20referencing To show how this comes together in atable containing objects, we first created a table
(above) that uses our defined class, aobj We may theninsert some values into our table like this (note the use
of the constructor aobj):
INSERT INTO aobjtable VALUES (aobj('FL',25))
INSERT INTO aobjtable VALUES (aobj('AL',35))
INSERT INTO aobjtable VALUES (aobj('OH',15))
To check what we have done, we can use the wildcardSELECT * (SELECT all) like this:
Trang 21And, to use the function we created, we must also usethe table alias in our SELECT as well as the qualifier,arow:
SELECT x.arow.state, x.arow.amt, x.arow.mult(2) FROM aobjtable x
This gives:
AR AROW.AMT X.AROW.MULT(2) - -
erence the value of amt for that row (the row itself).
Look at the following:
CREATE OR REPLACE TYPE BODY aobj AS MEMBER FUNCTION mult (times in number) RETURN NUMBER IS
BEGIN
RETURN times * self.amt;
END; /* end of begin */
END; /* end of create body */
Methods have available a special tuple variable SELF,which refers to the “current” tuple If SELF is used inthe definition of the method, then the context must besuch that a particular tuple is referred to.1
So we must get a row (a tuple) and use the value inthat row to make a calculation, and the self refers tothe value of the object (as created by the constructor,arow) for that row
Why the PRAGMA?
1 From the article “Object-Relational Features of Oracle” by J Ullman.
Trang 22Note the PRAGMA that says the length methodwill not modify the database (WNDS = write no data-base state) This clause is necessary if we are to uselength in queries.
In the article, “length” was the name of their tion example and “mult” is the name of ours
func-VARRAYs
In the last section we saw how to create objects andtables of objects with composite attributes and withand without functions We will now turn our attention
to tables that contain other types of non-atomic umns In this section, we will create an example thatuses a repeating group The term “repeating group” isfrom the 1970s when one referred to non-atomic valuesfor some column in what was then called a “not quiteflat file.” A repeating group, aka an array of values, has
col-a series of vcol-alues col-all of the scol-ame type In Orcol-acle thisrepeating group is called a VARRAY (a variable array)
We will use some built-in methods for theVARRAY construction during this process and thendemonstrate how to “write your own” methods forVARRAYs
Suppose we had some data on a local club (socialclub, science club, whatever), and suppose that the datalooks like this:
Club(Name, Address, City, Phone, (Members))
where (Members) is a repeating group
Trang 23Here is some data in a file/record format:
Club
Name Address City Phone Members
AL 111 First St Mobile 222-2222 Brenda, Richard
FL 222 Second St Orlando 333-3333 Gen, John, Steph, JJ
Technically, you cannot call this a table because theterm “table” in relational databases refers to a two-dimensional arrangement of atomic data Since “Mem-bers” contains a repeating group it is not atomic
In relational databases we convert the data in thetable to two or more two-dimensional tables — we nor-malize it To normalize the above file, we decompose itinto two tables — one containing the atomic parts ofClub, and the other containing the repeating groupwith a reference to the key of Club The normalizedversion of this small database would look like this:
Trang 24Name in Club_members is a foreign key referencingthe primary key, Name, in Club_details.
The focus on this section is not on the traditionalrelational database representation, but rather on howone might create the un-normalized version of the data
CREATE TYPE for VARRAYs
As with ordinary programming language arrays (like in
C or Visual BASIC), with VARRAYs we can create acollection of variables all of the same type The basicOracle syntax for the CREATE TYPE statement for aVARRAY type definition would be:
CREATE OR REPLACE TYPE name-of-type IS VARRAY(nn) of type
Where name-of-type is a valid attribute name, nn is the number of elements (maximum) in the array, and type
is the data type of the elements of the array
An example could look like this:
SQL> CREATE OR REPLACE TYPE mem_type IS VARRAY(10) of
variables A data type defines the kinds of operations
and the range of values that declared variables of thattype may use and take on For example, if we defined avariable to be of type NUMBER(3,0), we expect to be