Parameter Description reference The reference to the object object The value of the object selected from the database if supplied If you call LOCK_OBJECT and do not provide a second argu
Trang 1,object IN OUT ANY);
Parameters are summarized in the following table
Parameter Description
reference The reference to the object
object The value of the object selected from the database (if supplied)
If you call LOCK_OBJECT and do not provide a second argument, then the object will be locked, but that object will not be returned to the calling program
This program effectively substitutes for the following type of SQL statement:
SELECT VALUE (t)
INTO object
FROM the_underlying_object_table t
WHERE REF (t) = reference
FOR UPDATE;
In contrast to this SQL statement, with LOCK_OBJECT you will not need to specify the name of the
underlying database object table to retrieve the object
NOTE: It is not necessary to lock an object before you update or delete it By requesting a
lock, however, you ensure that another session cannot even attempt to make changes to that
same object until you commit or roll back
9.2.5.2.1 Restrictions
Note the following restrictions on calling LOCK_OBJECT:
•
The program does not assert a purity level with the RESTRICT_REFERENCES pragma
•
You cannot call this program from within an SQL statement, either directly or indirectly
9.2.5.3 The UTL_REF.SELECT_OBJECT procedure
Use the SELECT_OBJECT procedure to retrieve an object for a given reference The header follows:
PROCEDURE UTL_REF.SELECT_OBJECT
(reference IN REF ANY
,object IN OUT ANY);
Parameters are summarized in the following table
Parameter Description
reference The reference to the object
object The value of the object selected from the database
This program effectively substitutes for the following type of SQL statement:
SELECT VALUE (t)
INTO object
FROM the_underlying_object_table t
WHERE REF (t) = reference;
Trang 2In contrast to this SQL statement, with SELECT_OBJECT you will not need to specify the name of the underlying database object table to retrieve the object
9.2.5.3.1 Restrictions
Note the following restrictions on calling SELECT_OBJECT:
•
The program does not assert a purity level with the RESTRICT_REFERENCES pragma
•
You cannot call this program from within an SQL statement, either directly or indirectly
9.2.5.3.2 Example
In the following procedure, I use the SELECT_OBJECT built−in to retrieve the object based on the passed−in reference:
CREATE OR REPLACE PROCEDURE show_emp (emp_in IN REF employee_t)
IS
emp_obj employee_t
BEGIN
UTL_REF.SELECT_OBJECT (emp_in, emp_obj);
DBMS_OUTPUT.PUT_LINE (emp_obj.name);
END;.
9.2.5.4 The UTL_REF.UPDATE_OBJECT procedure
Use the UPDATE_OBJECT procedure to replace an object in the database specified by a given reference with your "replacement" object Here's the header:
PROCEDURE UTL_REF.UPDATE_OBJECT
(reference IN REF ANY
,object IN ANY);
Parameters are summarized in the following table
Parameter Description
reference The reference to the object
object The object that is to be placed in the row of the object table specified by the reference
This program effectively substitutes for the following type of SQL statement:
UPDATE the_underlying_object_table t
SET VALUE (t) = object
WHERE REF (t) = reference;
In contrast to this SQL statement, with UPDATE_OBJECT you will not need to specify the name of the underlying database object table to retrieve the object
9.2.5.4.1 Restrictions
Note the following restrictions on calling UPDATE_OBJECT:
•
The program does not assert a purity level with the RESTRICT_REFERENCES pragma
Trang 3You cannot call this program from within an SQL statement, either directly or indirectly.
9.2.6 UTL_REF Example
Let's start with an object type that can hold various types of documents
CREATE OR REPLACE TYPE Document_t AS OBJECT (
doc_id NUMBER,
author VARCHAR2(65),
created DATE,
revised DATE,
body BLOB,
MEMBER PROCEDURE update_revised
);
/
To keep this example simple, we'll implement only a single object method:
CREATE OR REPLACE TYPE BODY Document_t
AS
MEMBER PROCEDURE update_revised
IS
BEGIN
revised := SYSDATE;
END;
END;
/
Here's a table that will hold any kind of document:
CREATE TABLE documents OF Document_t;
We might have a requisition type that has a special type of document Each requisition contains a REF to a particular document
CREATE OR REPLACE TYPE Requisition_t AS OBJECT (
doc_ref REF Document_t,
needed DATE,
approved DATE,
MEMBER PROCEDURE update_revision_date,
MEMBER FUNCTION has_valid_need_date RETURN BOOLEAN
);
/
In a moment, we're going to look at an example of UTL_REF that implements the type body of Requisition_t But let's first look at life without UTL_REF Not only do we have to write SQL, we also have to know the table name in each statement where we need access to a persistent object In fact, the following methods are hard−coded to work with only one particular table implementation (not good):
CREATE OR REPLACE TYPE BODY Requisition_t
AS
MEMBER FUNCTION has_valid_need_date RETURN BOOLEAN
IS
document Document_t;
CURSOR doc_cur IS /* Ugly! */
SELECT VALUE(d)
FROM documents d
WHERE REF(d) = SELF.doc_ref;
BEGIN
OPEN doc_cur;
FETCH doc_cur INTO document; /* Ditto */
CLOSE doc_cur;
Trang 4IF document.created > SELF.approved
THEN
RETURN FALSE;
ELSE
RETURN TRUE;
END IF;
END;
MEMBER PROCEDURE update_revision_date
IS
BEGIN
UPDATE documents d /* Even uglier */
SET revised = SYSDATE
WHERE REF(d) = SELF.doc_ref;
END;
END;
/
Let's turn now to see what UTL_REF can do for us:
CREATE OR REPLACE TYPE BODY Requisition_t
AS
MEMBER FUNCTION has_valid_need_date RETURN BOOLEAN
IS
document Document_t;
BEGIN
/* UTL_REF.SELECT_OBJECT allows us to retrieve the document object
|| from persistent database storage into a local variable No muss,
|| no fetch, no bother! SELECT_OBJECT finds the table and object
|| for us.
*/
UTL_REF.SELECT_OBJECT (SELF.doc_ref, document);
/* Now that we have retrieved the document object, we can
|| easily gain access to its attributes:
*/
IF document.created > SELF.approved
THEN
RETURN FALSE;
ELSE
RETURN TRUE;
END IF;
END;
MEMBER PROCEDURE update_revision_date
IS
document Document_t;
BEGIN
/* To update the revision date of the requisition object,
|| we'll simply "delegate" to the referenced document.
|| First we retrieve it
*/
UTL_REF.SELECT_OBJECT (SELF.doc_ref, document);
/* then we can invoke a method on the newly retrieved
|| (but transient) object Notice that we do NOT update
|| the attribute directly, but rely instead on the public
|| method supplied for this purpose.
*/
document.update_revised;
/* and now we easily update the data in the underlying table
|| (whatever table it is we don't know or care!)
*/
UTL_REF.UPDATE_OBJECT(SELF.doc_ref, document);
END;
END;
/
Since UTL_REF frees us from dependence on the specific underlying table, it allows us to achieve greater reuse, portability, modularity, and resilience to change
Trang 59.1 DBMS_ROWID:
Working with the ROWID
Pseudo−Column (Oracle8
only)
10 Miscellaneous
Packages
Copyright (c) 2000 O'Reilly & Associates All rights reserved.