Sunteți pe pagina 1din 16

Programming with Objects

rogramming with the new Object constructions in Oracle8 can be challenging. This chapter shows how to work with Objects in PL/SQL blocks and with JDBC.
CrossReference

25
C H A P T E R

In This Chapter

Writing PL/SQL code for querying Objects Updating Objects with PL/SQL Inserting data into Objects with PL/SQL Using JDBC to query Objects Updating Objects with JDBC

This chapter uses the Objects and Object Tables created in Chapter 24, which examines the concepts behind Oracle8 Objects and illustrates some sample PL/SQL code. Review Chapter 24 before you tackle this chapter. Chapter 18 discusses basic construction techniques for PL/SQL programming. Refer to this chapter if you need to brush up on PL/SQL programming techniques. Each section in this chapter has sample code that runs using the sample Tables included on the CD-ROM. Follow the instructions in Appendix B to install the Tables in your database.

CrossReference

Reviewing the Sample Object Tables


In Chapter 24, you learned how to create a set of Object Tables for use in a library. These Object Tables are used in this chapter to show real examples of PL/SQL procedures to manipulate Objects. The following two Object Tables are used here: 3 BOOK_TABLE_T 3 PERSON_TABLE_T Figure 25-1 shows the Object Table called BOOK_TABLE_T and all its components. Elements in the figure surrounded by a box indicate the element is an Object datatype.

648

Chapter 25 3 Programming with Objects

BOOK TABLE T (table of BOOKS T) BOOK_ID integer (PK) BOOK_PUBLISHER varchar2(50) BOOK_AUTHOR_NAME
FIRST_NAME LAST_NAME varchar2(25) varchar2(25)

books_t name_t

BOOK_TITLE varchar2(100) BOOK_SUBJECT varchar2(50) BOOK_RESERVED_LIST reserved_list_t


PERSON_ID ref PERSON_T WAIT_NO integer

varray(10) of books_reserved_t books_reserved_t

Figure 25-1: The Object Table BOOK_TABLE_T is one of the sample Tables.

The BOOK_TABLE_T contains a combination of regular Columns with Oracle datatypes and User-defined datatypes. The Column BOOK_AUTHOR_NAME is of the type name_t, which is a User-defined Object type. The name_t Object type is defined as containing two VARCHAR2 Columns: FIRST_NAME and LAST_NAME. The BOOK_TABLE_T also contains a collection. The Column BOOK_RESERVED_LIST is a User-defined datatype called reserved_list_t. Reserved_list_t is a VARRAY containing ten rows of another User-defined datatype called books_ reserved_t. The books_reserved_t Object type contains two Columns: PERSON_ID, a reference to the PERSON_T datatype; and WAIT_NO, an integer. The PERSON_ID Column connects a record in the VARRAY to a row in the PERSON_TABLE_T Table, similar to a Foreign Key Column. The other Object Table is called PERSON_TABLE_T. Figure 25-2 shows a diagram of this Object Table structure. The PERSON_TABLE_T Object Table has a variety of Column structures. PERSON_ID is the Primary Key. PERSON_NAME is a User-defined datatype of name_t. PERSON_ADDRESS is another User-defined datatype of address_t. PERSON_TABLE_T contains the following two collections: 3 PERSON_PHONE. This collection is a VARRAY of ten records of the Object type phone_t. The phone_t type itself consists of two VARCHAR2 Columns: PHONE_TYPE and PHONE_NUMBER. 3 PERSON_BK_LOANED. This collection is a nested Table of records of the Object type book_loaned_t. The book_loaned_t type consists of three Columns: BOOK_ID, a reference to BOOKS_T (which acts as a Foreign Key to the BOOK_ TABLE_T); LOAN__DATE, a date Column; and FINE, a number Column.

Chapter 25 3 PL/SQL with Oracle8 Objects

649

PERSON TABLE T (table of PERSON T) PERSON_ID PERSON_NAME


FIRST_NAME LAST_NAME

integer (PK)
varchar2(25) varchar2(25)

name_t

person_t

PERSON ADDRESS
STREET CITY STATE ZIP varchar2(50) varchar2(25) varchar2(25) number

address_t

PERSON PHONE phone_list_t


PHONE_TYPE PHONE_NUMBER varchar2(20) varchar2(20) phone_t varray (10) of phone_t

PERSON_BK_LOANED books_loan_list_t
BOOK_ID LOAN_DATE FINE ref BOOKS_T date number(5,2) table of book_loaned_t book_loaned_t

Figure 25-2: The Object Table PERSON_TABLE_T is one of the sample Tables.

PL/SQL with Oracle8 Objects


The following sections discuss how to use PL/SQL with the database.

Querying Object Tables


When querying portions of an Object Table that are not collections, you can use simple SQL to return rows and Columns. The secret: add a qualifier to identify the Column and element within the Column for User-defined Columns.

List all books


The following SQL displays a list of books from the BOOK_TABLE_T Object Table:
/* ----------------- book_report.sql -------- */ SELECT BOOK_ID, BOOK_PUBLISHER, BOOK_TITLE, BOOK_SUBJECT, B.BOOK_AUTHOR_NAME.FIRST_NAME, B.BOOK_AUTHOR_NAME.LAST_NAME FROM BOOK_TABLE_T B;

650

Chapter 25 3 Programming with Objects

In the preceding query command, the Columns FIRST_NAME and LAST_NAME are qualified with the Object type Column BOOK_AUTHOR_NAME. The two Columns are also qualified with a Table alias. Both components are necessary to execute the query successfully. The two Columns appear in the query as follows:
... B.BOOK_AUTHOR_NAME.FIRST_NAME, B.BOOK_AUTHOR_NAME.LAST_NAME ...

The results of this query appear as follows. The headings are removed to compress the Column listing into single lines:
1 IDG Rough Guide to British Columbia Travel Amy Chandi 2 IDG Hiking Maui Travel Iolani Kalani 3 SCIFI Press Foundation Science Fiction Isaac Asimov 4 SCIFI Press Best of Science Fiction Science Fiction Isaac Asimov 5 SCIFI Press The Illustrated Man Science Fiction Ray Bradbury 6 Time Life The Technical Drummer Music Joe Banks 7 Time Life Slide Guitar Music Joe Dieter 16 HARDY PRESS Moonlight Science Fiction James Tiptree 8 rows returned.

List all persons


The following SQL lists all rows of the PERSON_TABLE_T Object Table.
/* ----------- PERSON_REPORT ------------ */ SELECT A.PERSON_ID, A.PERSON_NAME.FIRST_NAME, A.PERSON_NAME.LAST_NAME, A.PERSON_ADDRESS.STREET, A.PERSON_ADDRESS.CITY, A.PERSON_ADDRESS.STATE, A.PERSON_ADDRESS.ZIP, A.PERSON_BL_STATUS FROM PERSON_TABLE_T A;

Again, the Object datatype Columns, PERSON_NAME and PERSON_ADDRESS, are split into their component Columns using the Column name and the component Column name. The Table alias is also required for this kind of Column, such as in the following statement:

Chapter 25 3 PL/SQL with Oracle8 Objects

651

... A.PERSON_NAME.FIRST_NAME, ...

The following lists the results of the query. The Column headings are removed to compress to data into single lines per data row:
1 Tony Prem 78759 Y 2 Amy Chandi 78759 Y 3 Cortney Dumas 78799 Y 4 Patrick Mohyde 12345 Y 4 rows selected. 11316 Jollyville 100 West Main St 215 E Dewey St 80 Kealani St Austin Dallas Austin TX TX HI TX

Honolulu

List a persons loaned books


This query requires a PL/SQL block because it retrieves information stored in a nested Table in the PERSON_TABLE_T Table. Refer to Figure 25-2 to review the nested Table structure of the PERSON_BK_LOANED Column. The following PL/SQL Procedure shows all loaned books for one person. The Procedure requires an input parameter: the PERSON_ID. For simplicity, the output is displayed on the command line using the DBMS_OUTPUT package built into the default database.
/* ------------ LIST_LOANED_BOOKS.SQL ----------- */ SET SERVEROUTPUT ON CREATE OR REPLACE PROCEDURE LIST_LOANED_BOOKS ( I_PERSON_ID IN NUMBER ) AS BEGIN DECLARE V_PERSON_BK_LOANED BOOKS_LOAN_LIST_T; V_BOOK_LOANED BOOK_LOANED_T; V_BOOK BOOKS_T; V_REF_BOOK REF BOOKS_T; V_FIRST_NAME VARCHAR2(25); V_LAST_NAME VARCHAR2(25); BEGIN /* ------------------- READ IN LOANED LIST ------ */ BEGIN SELECT P.PERSON_BK_LOANED, P.PERSON_NAME.FIRST_NAME, P.PERSON_NAME.LAST_NAME

652

Chapter 25 3 Programming with Objects

INTO V_PERSON_BK_LOANED, V_FIRST_NAME, V_LAST_NAME FROM PERSON_TABLE_T P WHERE P.PERSON_ID = I_PERSON_ID; EXCEPTION WHEN NO_DATA_FOUND THEN V_PERSON_BK_LOANED := BOOKS_LOAN_LIST_T(NULL); END; DBMS_OUTPUT.PUT_LINE(BOOKS ON LOAN TO:); DBMS_OUTPUT.PUT_LINE(PERSON# ||I_PERSON_ID || ||V_FIRST_NAME || || V_LAST_NAME || *****************************); FOR V_COUNTER IN 1..V_PERSON_BK_LOANED.COUNT LOOP /* ---- LOOP THROUGH EACH ROW IN THE NESTED TABLE. ---*/ V_BOOK_LOANED := V_PERSON_BK_LOANED(V_COUNTER); V_REF_BOOK := V_BOOK_LOANED.BOOK_ID; /* ---------- USE DEREF TO RETRIEVE THE BOOK_TABLE_T ROW THAT IS REFERENCED ------------- */ SELECT DEREF(V_REF_BOOK) INTO V_BOOK FROM DUAL; /* ----- DISPLAY DETAILS ABOUT THE BOOK. ----------- */ DBMS_OUTPUT.PUT_LINE(BOOK# ||V_BOOK.BOOK_ID || ||V_BOOK.BOOK_TITLE); DBMS_OUTPUT.PUT_LINE( LOAN DATE: || V_BOOK_LOANED.LOAN_DATE); DBMS_OUTPUT.PUT_LINE( FINE: || V_BOOK_LOANED.FINE); END LOOP; DBMS_OUTPUT.PUT_LINE(DONE); END; END;

To run the procedure after creation, type the following SQL command in SQL Worksheet or SQL*Plus:
EXECUTE LIST_LOANED_BOOKS(n);

Replace n with the PERSON_ID you wish to list. For example, the following command lists the loaned books of Tony Prem (PERSON_ID=1):
EXECUTE LIST_LOANED_BOOKS(1);

The resulting listing follows:


BOOKS ON LOAN TO: PERSON# 1 Tony Prem***************************** BOOK# 1 Rough Guide to British Columbia LOAN DATE: 10-MAR-98 FINE: 2

Chapter 25 3 PL/SQL with Oracle8 Objects

653

BOOK# 2 Hiking Maui LOAN DATE: 12-MAR-98 FINE: 1.5 BOOK# 4 Best of Science Fiction LOAN DATE: 16-MAR-98 FINE: .5 BOOK# 5 The Illustrated Man LOAN DATE: 25-MAR-98 FINE: 0 DONE PL/SQL procedure successfully completed.

When using PL/SQL to reach data within a nested Table, you must set up variables with datatypes that match the datatypes in the Object Table. For example, the PERSON_BK_LOANED Column is of datatype books_loan_List_t. Therefore, you can define a variable, V_PERSON_BK_LOANED of datatype BOOKS_LOAN_LIST_T. Now that you have a PL/SQL variable containing the nested Table, you can use the usual collection processing commands within PL/SQL: 3 To find out how many rows are in the nested Table, use the COUNT method. In the preceding sample Procedure, the COUNT method appears in the LOOP command:
FOR V_COUNTER IN 1..V_PERSON_BK_LOANED.COUNT LOOP

3 Use a subscript to refer to an individual row in the nested Table. In the preceding Procedure, the V_COUNTER variable is used as a subscript within the LOOP. The following command in the Procedure assigns one row of the nested Table to a PL/SQL variable defined as datatype BOOK_LOANED_T:
V_BOOK_RESERVED := V_PERSON_BK_LOANED(V_COUNTER);

Now you have a final challenge: deciphering the BOOK_ID Column of this record. Because BOOK_ID in the nested Table row has a datatype of REF BOOKS_T, you must use the DEREF function to extract the corresponding row in the BOOK_TABLE_T. This sequence involves the following two steps: 3 Define a PL/SQL variable with the BOOK_T datatype. In the preceding Procedure, the variable is declared in the following manner:
V_BOOK BOOKS_T;

3 Use the DEREF command to populate the variable with a row from the referenced Table. The following command is found in the preceding Procedure. The DEREF command can only be used in the context of a SQL command, so the command is a SELECT command:
SELECT DEREF(V_REF_BOOK) INTO V_BOOK FROM DUAL;

654

Chapter 25 3 Programming with Objects

Finally, display information about the book by extracting it from the variable (V_BOOK) containing the BOOK_TABLE_T record. The preceding Procedure displays the books BOOK_ID and BOOK_TITLE in the following command:
DBMS_OUTPUT.PUT_LINE(BOOK# ||V_BOOK.BOOK_ID || ||V_BOOK.BOOK_TITLE);
Tip

VARRAYs are handled like nested Tables in a PL/SQL block. The only difference: VARRAYs have a limited number of records.

Updating a nested Table


One of the Columns in the nested Table found in the PERSON_TABLE_T is called FINE. In the following example, you learn how to assess a fine of twenty-five cents per day for every book checked out for more than seven days. The following PL/SQL procedure uses a loop to step through each row in the
PERSON_TABLE_T and then uses another loop to step through each row in the nested Table of loaned books (PERSON_BK_LOANED Column). /* ----- UPDATE_FINES.SQL ------- */ SET SERVEROUTPUT ON CREATE OR REPLACE PROCEDURE UPDATE_FINES AS BEGIN DECLARE ERROR_FOUND EXCEPTION; V_ERROR VARCHAR2(20); V_REF_BOOK REF BOOKS_T; V_BOOK_RESERVED BOOK_LOANED_T; V_PERSON_BK_LOANED BOOKS_LOAN_LIST_T; V_ID NUMBER; V_BOOK BOOKS_T; CURSOR C1 IS SELECT A.PERSON_ID, A.PERSON_BK_LOANED FROM PERSON_TABLE_T A FOR UPDATE; BEGIN /* ------------ PERSON LOOP -----------------*/ FOR C1REC IN C1 LOOP V_PERSON_BK_LOANED := C1REC.PERSON_BK_LOANED; DBMS_OUTPUT.PUT_LINE(PERSON_ID= || C1REC.PERSON_ID); /* ------------------- UPDATE FINES LOOP ------- */ FOR V_COUNTER IN 1..V_PERSON_BK_LOANED.COUNT LOOP V_BOOK_RESERVED := V_PERSON_BK_LOANED(V_COUNTER); V_REF_BOOK := V_BOOK_RESERVED.BOOK_ID; /* ------- GET THE BOOK_ID OF THE CURRENT ROW ----- */ SELECT DEREF(V_REF_BOOK) INTO V_BOOK

Chapter 25 3 PL/SQL with Oracle8 Objects

655

FROM DUAL; IF TRUNC(SYSDATE) - 7 > V_BOOK_RESERVED.LOAN_DATE THEN /* --------- FINE IS 25 CENTS A DAY AFTER 7 DAYS ---- */ /* ---------- UPDATE ROW VARIABLE --- */ V_BOOK_RESERVED.FINE := .25 * (TRUNC(SYSDATE) TRUNC(V_BOOK_RESERVED.LOAN_DATE) - 7); /* ---------- UPDATE NESTED TABLE VARIABLE --- */ V_PERSON_BK_LOANED(V_COUNTER) := V_BOOK_RESERVED; DBMS_OUTPUT.PUT_LINE(FINE IS || V_BOOK_RESERVED.FINE); ELSE /* ------- BOOK IS NOT OVERDUE -------------- */ DBMS_OUTPUT.PUT_LINE(NOT A FINE! BOOK ID: || V_BOOK.BOOK_ID || LOAN_DATE = || V_BOOK_RESERVED.LOAN_DATE); END IF; END LOOP; /* ------- UPDATE PERSON_TABLE_T ROW WITH NESTED TABLE VARIABLE ---*/ UPDATE PERSON_TABLE_T SET PERSON_BK_LOANED = V_PERSON_BK_LOANED WHERE CURRENT OF C1; END LOOP; COMMIT; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(ERROR #|| SQLCODE || MSG: || SQLERRM); END; END;

To execute the Procedure, type the following command in SQL Worksheet or SQL*Plus:
EXECUTE UPDATE_FINES

The Procedure displays status lines as follows:


PERSON_ID=1 FINE IS 2.75 FINE IS 2.25 FINE IS 1.25 NOT A FINE! BOOK ID:5LOAN_DATE = 25-MAR-98 PERSON_ID=2 FINE IS 1.25 PERSON_ID=3 PERSON_ID=4 PL/SQL procedure successfully completed.

656

Chapter 25 3 Programming with Objects

The trick to this Procedure is extracting the data into ever-simpler variables until you are at a data manipulation level. Then you can rebuild the modified data back up to the complex datatype and update the whole record. The UPDATE command uses the usual SQL syntax. It can only be executed within a PL/SQL block because it needs a variable with an Object datatype, however. The nested Table variable is declared as follows:
V_PERSON_BK_LOANED BOOKS_LOAN_LIST_T;

The UPDATE command follows:


UPDATE PERSON_TABLE_T SET PERSON_BK_LOANED = V_PERSON_BK_LOANED WHERE CURRENT OF C1;

Inserting into a nested Table


To insert a row into a nested Table, use a new addition to the INSERT syntax that was built especially for inserting into nested Tables. The syntax follows:
INSERT INTO THE (sub_query) [VALUES (sql_expression_1[,sql_expression_2,,sql_expression_n ]) | sub_query)]

The first sub_query must select the nested Table. The VALUES section or the second sub_query must contain Columns that match the Columns in one occurrence of the nested Table. The following PL/SQL Procedure loans a library book to a person. It checks to see if the person already has borrowed the book. If so, a message is sent. If not, the book is added to that persons list of loaned books.
/* -------- LOAN_A_BOOK.SQL --------------- */ SET SERVEROUTPUT ON CREATE OR REPLACE PROCEDURE LOAN_A_BOOK ( I_PERSON_ID IN NUMBER DEFAULT NULL, I_BOOK_ID IN INTEGER DEFAULT NULL ) AS BEGIN DECLARE ERROR_FOUND EXCEPTION; V_ERROR VARCHAR2(20); V_PERSON_BK_LOANED BOOKS_LOAN_LIST_T; V_ID NUMBER; V_BOOK_SUBSCRIPT NUMBER; V_BOOK_RESERVED BOOK_LOANED_T;

Chapter 25 3 PL/SQL with Oracle8 Objects

657

V_REF_BOOK REF BOOKS_T; V_BOOK BOOKS_T; BEGIN IF I_PERSON_ID IS NULL OR I_BOOK_ID IS NULL THEN RAISE ERROR_FOUND; END IF; SELECT PERSON_BK_LOANED INTO V_PERSON_BK_LOANED FROM PERSON_TABLE_T WHERE PERSON_ID = I_PERSON_ID; /* ------------ IS THE BOOK ALREADY CHECKED OUT? ------- */ FOR V_COUNTER IN 1..V_PERSON_BK_LOANED.COUNT LOOP V_BOOK_RESERVED := V_PERSON_BK_LOANED(V_COUNTER); V_REF_BOOK := V_BOOK_RESERVED.BOOK_ID; SELECT DEREF(V_REF_BOOK) INTO V_BOOK FROM DUAL; IF V_BOOK.BOOK_ID = I_BOOK_ID THEN /* ------------- BOOK ALREADY LOANED TO THIS PERSON ---- */ V_BOOK_SUBSCRIPT := V_COUNTER; END IF; END LOOP; IF V_BOOK_SUBSCRIPT IS NOT NULL THEN DBMS_OUTPUT.PUT_LINE(BOOK ALREADY LOANED. PERSON: || I_PERSON_ID || , BOOK: || I_BOOK_ID); ELSE /* ------------------- LOAN A BOOK ------- */ INSERT INTO THE( SELECT A.PERSON_BK_LOANED FROM PERSON_TABLE_T A WHERE A.PERSON_ID = I_PERSON_ID ) SELECT REF(C), SYSDATE, 0 FROM BOOK_TABLE_T C WHERE C.BOOK_ID = I_BOOK_ID; DBMS_OUTPUT.PUT_LINE(BOOK LOANED. PERSON: || I_PERSON_ID || , BOOK: || I_BOOK_ID); END IF; EXCEPTION WHEN ERROR_FOUND THEN DBMS_OUTPUT.PUT_LINE(MISSING PARAMETER. PLEASE ENTER PERSON_ID AND BOOK_ID); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(ERROR #|| SQLCODE || MSG: || SQLERRM); END; END;

To execute the Procedure, type the following command:


EXECUTE LOAN_A_BOOK(person_id, book_id);

658

Chapter 25 3 Programming with Objects

Replace person_id with the actual PERSON_ID borrowing the book and replace book_id with the actual BOOK_ID to be loaned. The results follow:
BOOK LOANED. PERSON: 1, BOOK: 6 PL/SQL procedure successfully completed.

The INSERT command in the Procedure follows:


INSERT INTO THE( SELECT A.PERSON_BK_LOANED FROM PERSON_TABLE_T A WHERE A.PERSON_ID = I_PERSON_ID ) SELECT REF(C), SYSDATE, 0 FROM BOOK_TABLE_T C WHERE C.BOOK_ID = I_BOOK_ID;

This command can also be run in SQL without using PL/SQL.

Deleting from a nested Table


Deleting from a nested Table requires work in a PL/SQL block. First, you must extract the nested Table into a PL/SQL variable. Next, use the DELETE method to delete one row of the nested Table. The syntax of the DELETE method follows:
nested_table_variable.DELETE(subscript);

Replace nested_table_variable with the PL/SQL variable with a nested Table datatype. Replace subscript with an integer. For example, to delete the third row, replace subscript with 3. The following PL/SQL Procedure enables a person to return a book to the library. The Procedure performs this action by removing a row from the PERSON_BK_ LOANED Column. The Procedure reads one persons row from the PERSON_TABLE_T Object Table using the parameter I_PERSON_ID. The Procedure looks for the row that matches the BOOK_ID passed as the incoming parameter, I_BOOK_ID. The Procedure code follows:
/* ---------- RETURN_A_BOOK.SQL --------- */ SET SERVEROUTPUT ON CREATE OR REPLACE PROCEDURE RETURN_A_BOOK (I_PERSON_ID IN NUMBER, I_BOOK_ID IN NUMBER) AS BEGIN DECLARE

Chapter 25 3 PL/SQL with Oracle8 Objects

659

ERROR_FOUND EXCEPTION; V_ERROR VARCHAR2(20); V_REF_BOOK REF BOOKS_T; V_BOOK_RESERVED BOOK_LOANED_T; V_PERSON_BK_LOANED BOOKS_LOAN_LIST_T; V_ID NUMBER; V_BOOK BOOKS_T; V_DELETE_BOOK_SUBSCRIPT NUMBER; CURSOR C1 IS SELECT A.PERSON_ID, A.PERSON_BK_LOANED FROM PERSON_TABLE_T A WHERE PERSON_ID = I_PERSON_ID FOR UPDATE; BEGIN FOR C1REC IN C1 LOOP V_PERSON_BK_LOANED := C1REC.PERSON_BK_LOANED; DBMS_OUTPUT.PUT_LINE(PERSON_ID= || C1REC.PERSON_ID); /* ------------------- FIND THE BOOK ------- */ FOR V_COUNTER IN 1..V_PERSON_BK_LOANED.COUNT LOOP V_BOOK_RESERVED := V_PERSON_BK_LOANED(V_COUNTER); V_REF_BOOK := V_BOOK_RESERVED.BOOK_ID; SELECT DEREF(V_REF_BOOK) INTO V_BOOK FROM DUAL; IF V_BOOK.BOOK_ID = I_BOOK_ID THEN /* ---------- SAVE THE SUBSCRIPT FOR THIS BOOK ----*/ V_DELETE_BOOK_SUBSCRIPT := V_COUNTER; ELSE DBMS_OUTPUT.PUT_LINE(DID NOT REMOVE BOOK: || V_BOOK.BOOK_ID); END IF; END LOOP; IF V_DELETE_BOOK_SUBSCRIPT IS NULL THEN DBMS_OUTPUT.PUT_LINE(BOOK NOT ON LOAN); ELSE V_PERSON_BK_LOANED.DELETE(V_DELETE_BOOK_SUBSCRIPT); DBMS_OUTPUT.PUT_LINE(REMOVED BOOK: || V_BOOK.BOOK_ID || SUBSCRIPT: || V_DELETE_BOOK_SUBSCRIPT); UPDATE PERSON_TABLE_T SET PERSON_BK_LOANED = V_PERSON_BK_LOANED WHERE CURRENT OF C1; END IF; END LOOP; COMMIT; DBMS_OUTPUT.PUT_LINE( ************* DONE ******************* ); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(ERROR #|| SQLCODE || MSG: || SQLERRM); END; END;

660

Chapter 25 3 Programming with Objects

Type the following statement to run the Procedure:


EXECUTE RETURN_A_BOOK(person_id, book_id);

Replace person_id and book_id with the person returning the book and the returned book, respectively. The results follow:
PERSON_ID=1 DID NOT REMOVE BOOK: 1 DID NOT REMOVE BOOK: 2 DID NOT REMOVE BOOK: 4 REMOVED BOOK:5 SUBSCRIPT: 4 ************* DONE ******************* PL/SQL procedure successfully completed.

The Procedure uses a multiple step process: 1. Read the PERSON_TABLE_T rows entire nested Table (PERSON_BK_LOANED) into a PL/SQL variable (V_PERSON_BK_LOANED). 2. Loop through all rows in the nested Table variable until you find the BOOK_ID to be removed. Remember the subscript of this row. 3. Delete the appropriate row from the nested Table variable. 4. Update the PERSON_TABLE_T rows nested Table (PERSON_BK_LOANED) with the nested Table variable (V_PERSON_BK_LOANED).
See Reference Section

Chapter 24 shows how to insert rows into Object Tables. The next section shows how to perform the same functions described in these sections (display, update, and delete records in a nested Table) using JDBC.

JDBC with Oracle8 Objects


JDBC enables you to reach into the database using Java. The application may be on the Web or on any platform that supports Java.

List a persons loaned books


This query requires a PL/SQL block because it retrieves information stored in a nested Table in the PERSON_TABLE_T Table. Refer to Figure 25-2 to review the nested Table structure of the PERSON_BK_LOANED Column.

Chapter 25 3 Summary

661

The JDBC program shows all loaned books for one person. The program requires an input parameter: the PERSON_ID.
On the CD-ROM

The code for this JDBC program is on the CD-ROM that accompanies this book.

Updating a nested Table


One of the Columns in the nested Table found in the PERSON_TABLE_T is called FINE. In this example, you learn how to assess a fine of twenty-five cents per day for every book checked out for more than seven days. The JDBC program code updates all nested Table rows in the PERSON_TABLE_T.
On the CD-ROM

The code for this JDBC program is on the CD-ROM that accompanies this book.

Inserting into a nested Table


The JDBC program code loans a library book to a person. It checks to see if the person already has borrowed the book. If so, a message is sent. If not, the book is added to that persons list of loaned books.
On the CD-ROM

The code for this JDBC program is on the CD-ROM that accompanies this book.

Deleting from a nested Table


The JDBC program enables a person to return a book to the library. The program performs this action by removing a row from the PERSON_BK_LOANED Column.
On the CD-ROM

The code for this JDBC program is on the CD-ROM that accompanies this book.

Summary
Oracle8 Object Tables contain Columns that consist of User-defined datatypes. This chapter reviews the two Object Tables created and described in Chapter 24. The BOOK_TABLE_T Table contains rows of the datatype BOOKS_T. The BOOKS_T datatype includes regular Columns, Object type Columns, and a VARRAY Column. The PERSON_TABLE_T Table contains rows of the datatype PERSON_T. The PERSON_T datatype contains normal Columns (such as the PERSON_ID) and Object type Columns (such as PERSON_ADDRESS). The PERSON_T Object type also contains a VARRAY of telephone numbers and a nested Table of loaned books.

662

Chapter 25 3 Programming with Objects

View all books in the Object Table BOOK_TABLE_T and PERSON_TABLE_T with SQL unless you need to list details contained in the VARRAY. To list the data in the nested Table in the PERSON_TABLE_T Object Table, you must use a PL/SQL block. The Procedure LIST_LOANED_BOOKS has variables with Userdefined datatypes that match those in the Object Table. After placing the entire nested Table into the PL/SQL variable, use regular collection processing (subscripts and loops) to retrieve and display data from the nested Table. A new extension to the SQL INSERT command enables you to insert a row into a nested Table without resorting to complex PL/SQL block. The extension, called THE, enables you to use a subquery in place of the Object Table name in the INSERT command. When deleting a row from a nested Table, you must use a PL/SQL block where you have declared a variable of the same Object type as the nested Table.

S-ar putea să vă placă și