Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
50
Добавлен:
16.04.2013
Размер:
5.97 Mб
Скачать

Using Collection Methods

-- assign an empty table to v2(35) and try again v2(35) := v5;

v2(35)(2) := 78; -- it works now end;

/

Example 5–33 Multilevel Collections and Bulk SQL

create type t1 is varray(10) of integer;

/

create table tab1 (c1 t1);

insert into tab1 values (t1(2,3,5));

insert into tab1 values (t1(9345, 5634, 432453));

declare

type t2 is table of t1; v2 t2;

begin

select c1 BULK COLLECT INTO v2 from tab1; dbms_output.put_line(v2.count); -- prints 2 end;

/

drop table tab1; drop type t1;

Using Collection Methods

These collection methods make collections easier to use, and make your applications easier to maintain:

EXISTS

COUNT

LIMIT

FIRST and LAST

PRIOR and NEXT

EXTEND

TRIM

DELETE

A collection method is a built-in function or procedure that operates on collections and is called using dot notation.

Collection methods cannot be called from SQL statements.

EXTEND and TRIM cannot be used with associative arrays.

EXISTS, COUNT, LIMIT, FIRST, LAST, PRIOR, and NEXT are functions; EXTEND,

TRIM, and DELETE are procedures.

EXISTS, PRIOR, NEXT, TRIM, EXTEND, and DELETE take parameters corresponding to collection subscripts, which are usually integers but can also be strings for associative arrays.

Only EXISTS can be applied to atomically null collections. If you apply another method to such collections, PL/SQL raises COLLECTION_IS_NULL.

Using PL/SQL Collections and Records 5-23

Using Collection Methods

Checking If a Collection Element Exists (EXISTS Method)

EXISTS(n) returns TRUE if the nth element in a collection exists. Otherwise, EXISTS(n) returns FALSE. By combining EXISTS with DELETE, you can work with sparse nested tables. You can also use EXISTS to avoid referencing a nonexistent element, which raises an exception. When passed an out-of-range subscript, EXISTS returns FALSE instead of raising SUBSCRIPT_OUTSIDE_LIMIT.

DECLARE

TYPE NumList IS TABLE OF INTEGER; n NumList := NumList(1,3,5,7);

BEGIN

n.DELETE(2); -- Delete the second element IF n.EXISTS(1) THEN

dbms_output.put_line('OK, element #1 exists.'); END IF;

IF n.EXISTS(2) = FALSE THEN

dbms_output.put_line('OK, element #2 has been deleted.'); END IF;

IF n.EXISTS(99) = FALSE THEN

dbms_output.put_line('OK, element #99 does not exist at all.'); END IF;

END;

/

Counting the Elements in a Collection (COUNT Method)

COUNT returns the number of elements that a collection currently contains:

DECLARE

TYPE NumList IS TABLE OF NUMBER;

n NumList := NumList(2,4,6,8); -- Collection starts with 4 elements. BEGIN

dbms_output.put_line('There are ' || n.COUNT || ' elements in N.'); n.EXTEND(3); -- Add 3 new elements at the end. dbms_output.put_line('Now there are ' || n.COUNT || ' elements in N.'); n := NumList(86,99); -- Assign a completely new value with 2 elements. dbms_output.put_line('Now there are ' || n.COUNT || ' elements in N.'); n.TRIM(2); -- Remove the last 2 elements, leaving none. dbms_output.put_line('Now there are ' || n.COUNT || ' elements in N.');

END;

/

COUNT is useful because the current size of a collection is not always known. For example, you can fetch a column of Oracle data into a nested table, where the number of elements depends on the size of the result set.

For varrays, COUNT always equals LAST. You can increase or decrease the size of a varray using the EXTEND and TRIM methods, so the value of COUNT can change, up to the value of the LIMIT method.

For nested tables, COUNT normally equals LAST. But, if you delete elements from the middle of a nested table, COUNT becomes smaller than LAST. When tallying elements, COUNT ignores deleted elements.

Checking the Maximum Size of a Collection (LIMIT Method)

For nested tables and associative arrays, which have no maximum size, LIMIT returns NULL. For varrays, LIMIT returns the maximum number of elements that a varray can

5-24 PL/SQL User's Guide and Reference

Using Collection Methods

contain/ You specify this limit in the type definition, and can change it later with the TRIM and EXTEND methods. For instance, if the maximum size of varray PROJECTS is 25 elements, the following IF condition is true:

DECLARE

TYPE Colors IS VARRAY(7) OF VARCHAR2(64); c Colors := Colors('Gold','Silver');

BEGIN

dbms_output.put_line('C has ' || c.COUNT || ' elements now.'); dbms_output.put_line('C''s type can hold a maximum of ' || c.LIMIT || '

elements.');

dbms_output.put_line('The maximum number you can use with C.EXTEND() is ' || (c.LIMIT - c.COUNT));

END;

/

Finding the First or Last Collection Element (FIRST and LAST Methods)

FIRST and LAST return the first and last (smallest and largest) index numbers in a collection that uses integer subscripts.

For an associative array with VARCHAR2 key values, the lowest and highest key values are returned. By default, the order is based on the binary values of the characters in the string. If the NLS_COMP initialization parameter is set to ANSI, the order is based on the locale-specific sort order specified by the NLS_SORT initialization parameter.

If the collection is empty, FIRST and LAST return NULL.

If the collection contains only one element, FIRST and LAST return the same index value.

The following example shows how to use FIRST and LAST to iterate through the elements in a collection that has consecutive subscripts:

DECLARE

TYPE NumList IS TABLE OF NUMBER;

n NumList := NumList(1,3,5,7); counter INTEGER;

BEGIN

dbms_output.put_line('N''s first subscript is ' || n.FIRST); dbms_output.put_line('N''s last subscript is ' || n.LAST);

-- When the subscripts are consecutive starting at 1, it's simple to loop through them.

FOR i IN n.FIRST .. n.LAST LOOP

dbms_output.put_line('Element #' || i || ' = ' || n(i)); END LOOP;

n.DELETE(2); -- Delete second element.

--When the subscripts have gaps or the collection might be uninitialized,

--the loop logic is more extensive. We start at the first element, and

--keep looking for the next element until there are no more. IF n IS NOT NULL THEN

counter := n.FIRST; WHILE counter IS NOT NULL LOOP

dbms_output.put_line('Element #' || counter || ' = ' || n(counter)); counter := n.NEXT(counter);

END LOOP;

Using PL/SQL Collections and Records 5-25

Using Collection Methods

ELSE

dbms_output.put_line('N is null, nothing to do.'); END IF;

END;

/

For varrays, FIRST always returns 1 and LAST always equals COUNT.

For nested tables, normally FIRST returns 1 and LAST equals COUNT. But if you delete elements from the beginning of a nested table, FIRST returns a number larger than 1. If you delete elements from the middle of a nested table, LAST becomes larger than

COUNT.

When scanning elements, FIRST and LAST ignore deleted elements.

Looping Through Collection Elements (PRIOR and NEXT Methods)

PRIOR(n) returns the index number that precedes index n in a collection. NEXT(n) returns the index number that succeeds index n. If n has no predecessor, PRIOR(n) returns NULL. If n has no successor, NEXT(n) returns NULL.

For associative arrays with VARCHAR2 keys, these methods return the appropriate key value; ordering is based on the binary values of the characters in the string, unless the NLS_COMP initialization parameter is set to ANSI, in which case the ordering is based on the locale-specific sort order specified by the NLS_SORT initialization parameter.

These methods are more reliable than looping through a fixed set of subscript values, because elements might be inserted or deleted from the collection during the loop. This is especially true for associative arrays, where the subscripts might not be in consecutive order and so the sequence of subscripts might be (1,2,4,8,16) or ('A','E','I','O','U').

DECLARE

TYPE NumList IS TABLE OF NUMBER;

n NumList := NumList(1966,1971,1984,1989,1999); BEGIN

dbms_output.put_line('The element after #2 is #' || n.NEXT(2)); dbms_output.put_line('The element before #2 is #' || n.PRIOR(2)); n.DELETE(3); -- Delete an element to show how NEXT can handle gaps. dbms_output.put_line('Now the element after #2 is #' || n.NEXT(2)); IF n.PRIOR(n.FIRST) IS NULL THEN

dbms_output.put_line('Can''t get PRIOR of the first element or NEXT of the last.');

END IF; END;

/

You can use PRIOR or NEXT to traverse collections indexed by any series of subscripts. The following example uses NEXT to traverse a nested table from which some elements have been deleted:

DECLARE

TYPE NumList IS TABLE OF NUMBER;

n NumList := NumList(1,3,5,7); counter INTEGER;

BEGIN

n.DELETE(2); -- Delete second element.

--When the subscripts have gaps, the loop logic is more extensive. We start at

the

--first element, and keep looking for the next element until there are no more. counter := n.FIRST;

5-26 PL/SQL User's Guide and Reference

Соседние файлы в папке Oracle 10g