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

Oracle PL/SQL Language Pocket Reference- P13

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 (168.44 KB, 50 trang )

10.5.3 Nonsequential Use of PL/SQL Table
Of course, the idea of using a minimum and maximum row assumes that the rows in the table are
used sequentially. That is, you fill row one, then row two, etc. This is a perfectly reasonable way to
fill a table's rows; to do this you absolutely must know the value of the row last filled. You are not,
however, required to fill rows in this way. You can place a value in any row of the table you wish,
regardless of the primary key value of the last row you filled.
The following example illustrates filling a PL/SQL table's rows randomly rather than sequentially:
DECLARE
TYPE countdown_tests_tabtype IS TABLE OF VARCHAR2(20)
INDEX BY BINARY_INTEGER;
countdown_test_list countdown_tests_tabtype;
BEGIN
countdown_test_list (1) := 'All systems go';
countdown_test_list (43) := 'Internal pressure';
countdown_test_list (255) := 'Engine inflow';
END;
In this situation, the minimum and maximum values do not have much significance.
The ability to randomly place values in a table can come in very handy when the primary key value
for the table's row is actually not sequentially derived, but is instead based on data in your
application. This use of "intelligent" primary key values is explored in more detail in
Section 10.9.2,
"Data-Smart Row Numbers in PL/SQL Tables" later in this chapter.
10.5.4 Passing PL/SQL Tables as Parameters
You can also pass a PL/SQL table as a parameter in a procedure or function; with this approach you
can, in a single call, pass all the values in a table into the module. In the following package
specification I define two modules that pass PL/SQL tables as parameters. The send_promos
procedure sends a promotional mailing to all the companies in my table. The companies_overdue
function returns a table filled with the names of companies that have overdue bills.
PACKAGE company_pkg
IS
TYPE primary_keys_tabtype IS TABLE OF company.


company_id%TYPE NOT NULL
INDEX BY BINARY_INTEGER;
company_keys_tab primary_keys_tabtype;
emp_keys_tab primary_keys_tabtype;
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
/* Table type and table for company names */
TYPE company_names_tabtype IS TABLE OF company.name%
TYPE
INDEX BY BINARY_INTEGER;
company_names_tab company_names_tabtype;
/* Parameter is a table of company primary keys */
PROCEDURE send_promos (company_table_in IN
primary_keys_tabtype);
/* Function returns a table of company names */
FUNCTION companies_overdue (overdue_date_in IN DATE)
RETURN company_names_tabtype;
/* Returns company ID for name. */
FUNCTION id (name in IN company.name%TYPE)
RETURN company.company id%TYPE
END company_pkg;
Now that I have a package containing both the table type and the programs referencing those types, I
can call these programs. The only tricky part to remember here is that you must declare a PL/SQL
table based on the type before you can use any of the programs. Here is an example of returning a PL/
SQL table as a function's return value:
CREATE OR REPLACE PROCEDURE
send_promos_for_overdue_companies
(date_in IN DATE := SYSDATE)
IS
v_row PLS_INTEGER;
/* Declare a PL/SQL table based on the packaged type.

*/
cnames company_pkg.company_names_tabtype;
BEGIN
cnames := company_pkg.companies_overdue (date_in);
/*
|| In PL/SQL 2.3 I can use navigation methods to
traverse.
|| Notice that I do not assume that rows are filled
sequentially.
*/
v_row := cnames.FIRST;
LOOP
EXIT WHEN v_row IS NULL;
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
DBMS_OUTPUT.PUT_LINE (cnames(v_row));
v_row := cnames.NEXT (v_row);
END LOOP;
END;
/
Notice that I could also have avoided declaring my own PL/SQL table, cnames, by using the
predefined table in the package:
company_pkg.company_names_tab :=
company_pkg.companies_overdue (date_in);
If I had taken this approach, however, any rows already defined in this "global" table would have
been erased.
Here is an example of calling a procedure, passing a PL/SQL table as an argument in the parameter
list:
DECLARE
v_row PLS_INTEGER;
/* Table of primary keys for company */

company_ids company_pkg.primary_keys_tabtype;
BEGIN
/* Populate the table with names of overdue companies.
*/
company_pkg.company_names_tab :=
company_pkg.companies_overdue (date_in);
/* For each company name, look up the ID and pass it
to the
|| PL/SQL table of company IDs.
*/
v_row := company_pkg.company_names_tab.FIRST;
LOOP
EXIT WHEN v_row IS NULL;
company_ids (NVL (company_ids.LAST, 0) + 1) :=
company_pkg.id(company_pkg.company_name_tab
(v_row));
v_row := company_pkg.company_names_tab.NEXT (v_row);
END LOOP;
/* Now send out promotional flyers to those companies.
*/
company_pkg.send_promos (company_ids);
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
/* Delete all the rows from the company names table. */
company_pkg.company_names_tab.DELETE;
END company_pkg;
Previous: 10.4 Declaring a
PL/SQL Table
Oracle PL/SQL
Programming, 2nd Edition
Next: 10.6 Filling the Rows

of a PL/SQL Table
10.4 Declaring a PL/SQL
Table
Book Index
10.6 Filling the Rows of a PL/
SQL Table
The Oracle Library
Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Previous: 10.5 Referencing
and Modifying PL/SQL
Table Rows
Chapter 10
PL/SQL Tables
Next: 10.7 Clearing the PL/
SQL Table

10.6 Filling the Rows of a PL/SQL Table
You can assign values to rows of a table in several ways:

Direct assignment

Iterative assignment

Aggregate assignment
These methods are described in the following sections.
10.6.1 Direct Assignment
As shown in previous examples, you can simply assign a value to a row with the assignment

operator:
countdown_test_list (43) := 'Internal pressure';
company_names_table (last_name_row) := 'Johnstone
Clingers';
Direct assignment makes sense when you need to make a change to a specific row. But what do you
use when you want to fill a whole set of rows, for example, unloading a whole cursor-full of
information from a database table? Here, iterative assignment may be more appropriate.
10.6.2 Iterative Assignment
In order to fill up multiple rows of a table, I recommend taking advantage of a PL/SQL loop. Within
the loop you will still perform direct assignments to set the values of each row, but the primary key
value will be set by the loop rather than hardcoded into the assignment itself.
In the following example, I use a WHILE loop to fill and then display a PL/SQL date table with the
next set of business days, as specified by the ndays_in parameter:
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
/* Filename on companion disk: bizdays.sp */
CREATE OR REPLACE PROCEDURE show_bizdays
(start_date_in IN DATE := SYSDATE, ndays_in IN
INTEGER := 30)
IS
TYPE date_tabtype IS TABLE OF DATE INDEX BY
BINARY_INTEGER;
bizdays date_tabtype;
/* The row in the table containing the nth_day */
nth_day BINARY_INTEGER := 1;
v_date DATE := start_date_in;
BEGIN
/* Loop through the calendar until enough biz days are
found */
WHILE nth_day <= ndays_in
LOOP

/* If the day is not on the weekend, add to the
table. */
IF TO_CHAR (v_date, 'DY') NOT IN ('SAT', 'SUN')
THEN
bizdays (nth_day) := v_date;
DBMS_OUTPUT.PUT_LINE (v_date);
nth_day := nth_day + 1;
END IF;
v_date := v_date + 1;
END LOOP;
END show_bizdays;
/
As you can see from this example, using the WHILE loop produces a neat, sequential load of the PL/
SQL table.
10.6.3 Aggregate Assignment
Just as you can assign one entire record to another record of the same type and structure, you can
perform aggregate assignments with tables as well. In order to transfer the values of one table to
another, the datatype of the two tables must be compatible. Beyond that you simply use the
assignment operator (:=) to transfer the values of one table to the other. The following example
contains an example of an aggregate table assignment:
DECLARE
TYPE name_table IS TABLE OF VARCHAR2(100) INDEX BY
BINARY_INTEGER;
old_names name_table;
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
new_names name_table;
BEGIN
/* Assign values to old_names table */
old_names(1) := 'Smith';
old_names(2) := 'Harrison';

/* Assign values to new_names table */
new_names(111) := 'Hanrahan';
new_names(342) := 'Blimey';
/* Transfer values from new to old */
old_names := new_names;
/* This assignment will raise NO_DATA_FOUND */
DBMS_OUTPUT.PUT_LINE (old_names (1));
END;
A table-level assignment completely replaces the previously defined rows in the table. In the
preceding example, rows 1 and 2 in old_names are defined before the last, aggregate assignment.
After the assignment, only rows 111 and 342 in the old_names table have values.
Previous: 10.5 Referencing
and Modifying PL/SQL
Table Rows
Oracle PL/SQL
Programming, 2nd Edition
Next: 10.7 Clearing the PL/
SQL Table
10.5 Referencing and
Modifying PL/SQL Table
Rows
Book Index
10.7 Clearing the PL/SQL
Table
The Oracle Library
Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Previous: 10.6 Filling the

Rows of a PL/SQL Table
Chapter 10
PL/SQL Tables
Next: 10.8 PL/SQL Table
Enhancements in PL/SQL
Release 2.3

10.7 Clearing the PL/SQL Table
What happens when you are done with a PL/SQL table and want to remove it from memory? If a PL/
SQL table is like a table, we should be able to DELETE the rows of that table or DROP it entirely,
right? It's a nice idea, but you can't perform a SQL DELETE statement on a PL/SQL table because it
is not stored in the database. You also cannot DROP a PL/SQL table.
You can set a single row to NULL with the following kind of assignment:
company_names_table (num_rows) := NULL;
But this assignment doesn't actually remove the row or make it undefined; it just sets the value of the
row to NULL.
The only way to actually empty a PL/SQL table of all rows is to perform an aggregate assignment
with a table that is empty -- a table, that is, with no rows defined.
With this approach, for every PL/SQL table you want to be able to empty, you declare a parallel,
empty table of the same table type. When you are finished working with your table, simply assign the
empty table to the actual table. This will unassign all the rows you have used. The following example
demonstrates this technique:
DECLARE
TYPE company_names_tabtype IS TABLE OF company.name%
TYPE
INDEX BY BINARY_INTEGER;
company_names_tab company_names_tabtype;
/* Here is the empty table declaration */
empty_company_names_tab company_names_tabtype;
BEGIN

... set values in company names table ...
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
/* The closest you can come to "dropping" a PL/SQL
table */
company_names_tab := empty_company_names_tab;
END;
NOTE: PL/SQL Release 2.3 offers a DELETE operator so that you can delete all or
some rows of a PL/SQL table.
Previous: 10.6 Filling the
Rows of a PL/SQL Table
Oracle PL/SQL
Programming, 2nd Edition
Next: 10.8 PL/SQL Table
Enhancements in PL/SQL
Release 2.3
10.6 Filling the Rows of a PL/
SQL Table
Book Index
10.8 PL/SQL Table
Enhancements in PL/SQL
Release 2.3
The Oracle Library
Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Previous: 10.7 Clearing the
PL/SQL Table
Chapter 10
PL/SQL Tables

Next: 10.9 Working with
PL/SQL Tables

10.8 PL/SQL Table Enhancements in PL/SQL Release 2.3
PL/SQL Release 2.3 offers significantly enhanced functionality for PL/SQL tables. These new
features include:

Records supported as elements of PL/SQL tables. Prior to Release 2.3, the element or single
column of the PL/SQL table could only be a scalar datatype, such as VARCHAR2 or
BOOLEAN or DATE. Release 2.3 allows you to define table types whose element datatype is
defined with the %ROWTYPE declaration attribute or is a named RECORD type.

New operations on PL/SQL tables. PL/SQL Release 2.3 offers a set of new built-in functions
and procedures which return information about, or modify the contents of, a PL/SQL table.
These operations are shown in Table 10.1.
These new features allow you to use PL/SQL tables for a wider range of applications and also
manipulate the data in tables in a more natural and efficient manner. You can now create local PL/
SQL data structures which mimic precisely the structure of a table stored in the database. You do not
have to create separate tables and manage them in parallel to emulate the multiple-column SQL table
structure.
You can use the built-ins to obtain PL/SQL table information that previously was unavailable. For
example, you can use the COUNT function to determine the number of elements defined in a table.
You no longer have to keep track of that number yourself.
Table 10.1: PL/SQL Release 2.3 Built-in Functions and Procedures for Tables
Operator Description
COUNT Returns the number of elements currently contained in the PL/SQL table.
DELETE Deletes one or more elements from the PL/SQL table.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
EXISTS Returns FALSE if a reference to an element at the specified index would raise the
NO_DATA_FOUND exception.

FIRST Returns the smallest index of the PL/SQL table for which an element is defined.
LAST Returns the greatest index of the PL/SQL table for which an element is defined.
NEXT Returns the smallest index of the PL/SQL table containing an element which is greater
than the specified index.
PRIOR Returns the greatest index of the PL/SQL table containing an element which is less
than the specified index.
These functions and procedures are described in detail later in this chapter.
10.8.1 PL/SQL Tables of Records
To declare a PL/SQL table, you must first declare a PL/SQL table TYPE. The syntax for the TYPE
statement is as follows:
TYPE <type name> IS TABLE OF <datatype>
INDEX BY BINARY_INTEGER;
With PL/SQL Release 2.3, the <datatype> may be a record type. This record type can be defined
using the %ROWTYPE declaration attribute. You can also specify a previously defined record
structure defined with the TYPE statement for records.
When you do create a PL/SQL table based on a record structure, that record may only be composed
of scalar fields. A nested record type (in which a field in the record is yet another record type) may
not be used to define a table type.
The following examples illustrate the different ways to declare table types based on records:

Declare a PL/SQL table type with same structure as the employee table:
TYPE local_emp_table IS TABLE OF employee%ROWTYPE
INDEX BY BINARY_INTEGER;

Declare a PL/SQL table type to correspond to the data returned by a cursor:
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CURSOR emp_cur IS SELECT * FROM employee;
TYPE cursor_emp_table IS TABLE OF emp_cur%ROWTYPE
INDEX BY BINARY_INTEGER;


Declare a PL/SQL table type based on a programmer-defined record:
TYPE emp_rectype IS
RECORD (employee_id INTEGER, emp_name VARCHAR2
(60));
TYPE emp_table IS TABLE OF emp_rectype
INDEX BY BINARY_INTEGER;
Notice that when you use a programmer-defined record type you do not append the %ROWTYPE
attribute to the record type. That is only done when you are using a table-based or cursor-based
record.
10.8.1.1 Referencing fields of record elements in PL/SQL tables
References to fields of elements of PL/SQL tables which are records have the following syntax:
<table name>(<index expression>).<field name>
where <table name> is the name of the table, <index expression> is an expression (constant, variable,
or computed expression) which evaluates to a number and <field name> is the name of the field in
the record used to define the PL/SQL table.
If, for example, you have created a PL/SQL table named emp_tab based on a record structure with a
field named emp_name, then the following assignment sets the employee name in the 375th row of
the PL/SQL table to SALIMBA:
emp_tab(375).emp_name := 'SALIMBA';
The index to the table does not have to be a constant. In the following example, the index is
calculated:
IF names_table (old_name_row + 1).last_name = 'SMITH'
THEN
You can define functions which return PL/SQL tables. As a result, you can also reference a field in a
PL/SQL table's record with the following syntax:
<function name>(<argument list>)(<index expression>).
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
<field name>
An example will make it easier to understand this complicated syntax. Suppose that I have defined a
function as follows:

FUNCTION best_company (year_in IN INTEGER)
RETURN company_tabtype;
where company_tabtype is a PL/SQL table type with a record structure for its element. Then the
following call to PUT_LINE displays the name of the company found in the tenth row of the returned
table:
DBMS_OUTPUT.PUT_LINE
(best_company(1995)(10).company_name || ' was tenth
best!');
To make sense of this expression, break it up into its components:
best_company(1995)
Returns a table, each row of which contains information about a company.
best_company(1995)(10)
Returns the tenth row of that table.
best_company(1995)(10).company_name
Returns the name of the company found in the tenth row of the table.
You can improve the readability of such a statement by separating it as follows:
current_company_rec := best_company(1995)(10);
DBMS_OUTPUT.PUT_LINE
(current_company.company_name || ' was tenth best!')
where current_company_rec is a record defined with the same type as the RETURN clause of the
best_company function. Now you have two statements where only one is really needed, but the code
can be more easily understood and therefore maintained.
10.8.1.2 Assigning records in PL/SQL tables
You can assign a whole record fetched from the database directly into the row of a PL/SQL table as
shown below (where both the cursor and the PL/SQL table use the same company%ROWTYPE row
type declaration):
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
FOR company_rec IN company_cur
LOOP
/* Get last row used and add one. */

next_row := NVL (company_table.LAST, 0) + 1;
company_table(next_row) := company_rec;
END LOOP;
10.8.2 PL/SQL Table Built-ins
Each of the PL/SQL table built-in procedures and functions provides different information about the
referenced PL/SQL table, except for DELETE, which removes rows from the PL/SQL table. The
syntax for using the table built-ins for PL/SQL tables is different from the syntax I described in
Part
3, Built-In Functions of this book. It employs a "member method" syntax, common in object-oriented
languages such as C++.
To give you a feeling for member-method syntax, consider the LAST function. It returns the greatest
index value in use in the PL/SQL table. Using standard function syntax, you might expect to call
LAST as follows:
IF LAST (company_table) > 10 THEN ... /* Invalid syntax */
In other words, you would pass the PL/SQL table as an argument. In contrast, by using the member-
method syntax, the LAST function is a method which "belongs to" the object, in this case the PL/
SQL table. So the correct syntax for using LAST is:
IF company_table.LAST > 10 THEN ... /* Correct syntax */
The general syntax for calling these PL/SQL table built-ins is either of the following:

An operation which takes no arguments:
<table name>.<operation>

An operation which takes a row index for an argument:
<table name>.<operation>(<index number> [,
<index_number>])
The following statement, for example, returns TRUE if the 15th row of the company_tab PL/SQL
table is defined:
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
company_tab.EXISTS(15)

By using the member-method syntax, Oracle is able to distinguish the PL/SQL table functions such
as EXISTS and DELETE from the SQL operations of the same name (which never appear with dot-
qualified notation).
The following sections describe each of the table built-ins.
10.8.2.1 The COUNT function
The COUNT function returns the number of elements currently defined in the PL/SQL table. The
specification for the function is:
FUNCTION COUNT RETURN INTEGER;
You call COUNT as follows:
total_rows := emp_table.COUNT;
Notice that if the emp_table structure were defined inside a package, then double dot notation would
be needed to get the count:
total_rows := employee_pkg.emp_table.COUNT;
Prior to PL/SQL Release 2.3, the only way to determine this count was to manually keep track of the
number of elements defined in the table.
10.8.2.2 The DELETE procedure
The DELETE procedure deletes elements from the specified PL/SQL table. The specifications for the
procedure are overloaded, as shown in the following table.
Procedure Header Description of Use
PROCEDURE DELETE;
Just as with SQL, this simplest form of the
DELETE build-in (which takes no
arguments at all) has the most sweeping
impact: delete all rows from the PL/SQL
table.
PROCEDURE DELETE
(index_in IN INTEGER);
Delete the row specified by that index.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
PROCEDURE DELETE

(start_index_in IN INTEGER,
end_index_in IN INTEGER);
Deletes all the rows defined between the
start and end indexes. If end_index_in is
less than start_index_in, then no rows are
deleted.
If any of the arguments to DELETE is NULL, then the operation does not remove any rows at all.
You call DELETE as shown in the following examples:

Delete all the rows from the names table:
names_tab.DELETE;

Delete the 77th row from the globals table:
ps_globals.DELETE (77);

Delete all rows in the temperature readings table between the 0th row and the -15,000th row,
inclusive:
temp_reading_tab.DELETE (-15000, 0);
Prior to PL/SQL Release 2.3, the only way to delete rows from a PL/SQL table was to assign an
empty table to the existing PL/SQL table. The DELETE procedure gives you much finer control over
the memory required by your PL/SQL tables.
10.8.2.3 The EXISTS function
The EXISTS function returns TRUE if an element is defined at the specified index in a PL/SQL
table. Otherwise, it returns FALSE. The specification for the function is:
FUNCTION EXISTS (index_in IN INTEGER) RETURN BOOLEAN;
You call EXISTS as follows:
IF seuss_characters_table.EXISTS(1) THEN ...
Prior to PL/SQL Release 2.3, you could emulate the EXISTS function with your own function
looking something like this:
/* Filename on companion disk: rowexist.sf */

FUNCTION row_exists
(table_in IN <table type>, row_in IN INTEGER) RETURN
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
BOOLEAN
IS
stg VARCHAR2(20);
BEGIN
stg := table_in (row_in);
RETURN TRUE;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
RETURN FALSE;
END;
Unfortunately, you would need a different version of the function for each PL/SQL table TYPE,
which makes this a very undesirable approach. The EXISTS function is a big improvement.
10.8.2.4 The FIRST function
The FIRST function returns the lowest value index for which an element is defined in the specified
PL/SQL table. The specification for the function is:
FUNCTION FIRST RETURN INTEGER;
You call FIRST as follows:
first_entry_row := employee_table.FIRST;
If the PL/SQL table does not contain any elements at all, FIRST returns NULL.
10.8.2.5 The LAST function
The LAST function returns the highest value index for which an element is defined in the specified
PL/SQL table. The specification for the function is:
FUNCTION LAST RETURN INTEGER;
You call LAST as follows:
last_entry_row := employee_table.LAST;
If the PL/SQL table does not contain any elements at all, LAST returns NULL.

If you plan to use the PL/SQL table to fill rows sequentially from, say, the first row, you will want to
make sure to use the NVL function (see
Chapter 13, Numeric, LOB, and Miscellaneous Functions) to
convert the NULL to a zero, as shown in this example.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
The following block uses a cursor FOR loop to transfer data from the database to a PL/SQL table of
records. When the first record is fetched, the company_table is empty, so the LAST operator will
return NULL. NVL converts that value to zero. I then add one and I am on my way:
FOR company_rec IN company_cur
LOOP
/* Get last row used and add one. */
next_row := NVL (company_table.LAST, 0) + 1;
/* Set the (next_row) values for ID. */
company_table(next_row).company_id :=
company_rec.company_id;
END LOOP;
10.8.2.6 The NEXT function
The NEXT function returns the next greater index after the specified index at which some element is
defined in the specified PL/SQL table. The specification for the function is:
FUNCTION NEXT (index_in IN INTEGER) RETURN INTEGER;
You call NEXT as follows:
next_index := employee_table.NEXT (curr_index);
Remember that PL/SQL tables are sparse: if the tenth and 2005th rows are defined, there is no
guarantee that the 11th row is also defined. NEXT gives you a way to find the next defined element,
"skipping over" any undefined row numbers.
The table.NEXT procedure will return NULL if there aren't any elements defined after the specified
row.
10.8.2.7 The PRIOR function
The PRIOR function returns the prior greater index after the specified index at which some element is
defined in the specified PL/SQL table. The specification for the function is:

FUNCTION PRIOR (index_in IN INTEGER) RETURN INTEGER;
You call PRIOR as follows:
prev_index := employee_table.PRIOR (curr_index);
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Remember that, as we described in the preceding section, PL/SQL tables are sparse. PRIOR gives
you a way to find the previously defined element, "skipping over" any undefined row numbers.
The table.PRIOR procedure will return NULL if there aren't any elements defined before the
specified row.
Previous: 10.7 Clearing the
PL/SQL Table
Oracle PL/SQL
Programming, 2nd Edition
Next: 10.9 Working with
PL/SQL Tables
10.7 Clearing the PL/SQL
Table
Book Index
10.9 Working with PL/SQL
Tables
The Oracle Library
Navigation

Copyright (c) 2000 O'Reilly & Associates. All rights reserved.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Previous: 10.8 PL/SQL
Table Enhancements in PL/
SQL Release 2.3
Chapter 10
PL/SQL Tables
Next: III. Built-In

Functions

10.9 Working with PL/SQL Tables
The remainder of this chapter provides you with lots of examples of ways to use PL/SQL tables in
your applications.
10.9.1 Transferring Database Information to PL/SQL Tables
You cannot use a SQL SELECT statement to transfer data directly from a database table to a PL/SQL
table. You need to take a programmatic approach. A cursor FOR loop usually makes the most sense
for this process, which requires the following steps:
1. Define a PL/SQL table TYPE for each datatype found in the columns of the database table.
2. Declare PL/SQL tables which will each receive the contents of a single column.
3. Declare the cursor against the database table.
4. Execute the FOR loop. The body of the loop will contain a distinct assignment of one column
into one PL/SQL table.
In PL/SQL Release 2.3, this process would be much simpler. You could define a PL/SQL table with
the same structure as the database table by creating a table-based record. Prior to that release,
unfortunately, you need a separate PL/SQL table for each column. You do not, on the other hand,
need a separate table TYPE for each column. If you have two date columns, for example, you can
declare two separate PL/SQL tables both based on the same TYPE.
In the following example I load the company ID, incorporation date, and filing date from the database
table to three different PL/SQL tables. Notice that there are only two types of PL/SQL tables
declared:
/* Filename on companion disk: db2tab1.sql (see db2tab2.
sql for the PL/SQL Release 2.3 version of same transfer)
*/
DECLARE
/* The cursor against the database table. */
CURSOR company_cur
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.

×