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

Using PL/SQL Collections with SQL Statements

Example 5–24 Comparing Nested Tables with Set Operators

You can test certain properties of a nested table, or compare two nested tables, using ANSI-standard set operations:

DECLARE

TYPE nested_typ IS TABLE OF NUMBER; nt1 nested_typ := nested_typ(1,2,3); nt2 nested_typ := nested_typ(3,2,1); nt3 nested_typ := nested_typ(2,3,1,3); nt4 nested_typ := nested_typ(1,2,4); answer BOOLEAN;

howmany NUMBER;

PROCEDURE testify(truth BOOLEAN DEFAULT NULL, quantity NUMBER DEFAULT NULL) IS BEGIN

IF truth IS NOT NULL THEN

dbms_output.put_line(CASE truth WHEN TRUE THEN 'True' WHEN FALSE THEN 'False' END);

END IF;

IF quantity IS NOT NULL THEN dbms_output.put_line(quantity);

END IF; END;

BEGIN

answer := nt1 IN (nt2,nt3,nt4); -- true, nt1 matches nt2 testify(truth => answer);

answer := nt1 SUBMULTISET OF nt3; -- true, all elements match testify(truth => answer);

answer := nt1 NOT SUBMULTISET OF nt4; -- also true testify(truth => answer);

howmany := CARDINALITY(nt3); -- number of elements in nt3 testify(quantity => howmany);

howmany := CARDINALITY(SET(nt3)); -- number of distinct elements testify(quantity => howmany);

answer := 4 MEMBER OF nt1; -- false, no element matches testify(truth => answer);

answer := nt3 IS A SET; -- false, nt3 has duplicates testify(truth => answer);

answer := nt3 IS NOT A SET; -- true, nt3 has duplicates testify(truth => answer);

answer := nt1 IS EMPTY; -- false, nt1 has some members testify(truth => answer);

END;

/

Using PL/SQL Collections with SQL Statements

Collections let you manipulate complex datatypes within PL/SQL. Your program can compute subscripts to process specific elements in memory, and use SQL to store the results in database tables.

Example 5–25 Creating a SQL Type Corresponding to a PL/SQL Nested Table

In SQL*Plus, you can create SQL types whose definitions correspond to PL/SQL nested tables and varrays:

SQL> CREATE TYPE CourseList AS TABLE OF VARCHAR2(64);

Using PL/SQL Collections and Records 5-17

Using PL/SQL Collections with SQL Statements

You can use these SQL types as columns in database tables:

SQL>

CREATE TABLE department (

2

name

VARCHAR2(20),

3

director

VARCHAR2(20),

4

office

VARCHAR2(20),

5

courses

CourseList)

6

NESTED TABLE courses STORE AS courses_tab;

Each item in column COURSES is a nested table that will store the courses offered by a given department. The NESTED TABLE clause is required whenever a database table has a nested table column. The clause identifies the nested table and names a system-generated store table, in which Oracle stores the nested table data.

Example 5–26 Inserting a Nested Table into a Database Table

Now, you can populate the database table. The table constructor provides values that all go into the single column COURSES:

BEGIN

INSERT INTO department

VALUES('English', 'Lynn Saunders', 'Breakstone Hall 205', CourseList('Expository Writing',

'Film and Literature', 'Modern Science Fiction', 'Discursive Writing', 'Modern English Grammar',

'Introduction to Shakespeare', 'Modern Drama',

'The Short Story', 'The American Novel'));

END;

Example 5–27 Using PL/SQL Nested Tables with INSERT, UPDATE, DELETE, and SELECT Statements

You can retrieve all the courses offered by the English department into a PL/SQL nested table:

CREATE TYPE ColorList AS TABLE OF VARCHAR2(64);

/

CREATE TABLE flowers (name VARCHAR2(20), colors ColorList) NESTED TABLE colors STORE AS colors_tab;

BEGIN

INSERT INTO flowers VALUES('Rose', ColorList('Red','Yellow','White'));

INSERT INTO flowers VALUES('Tulip', ColorList('Red','White','Yellow', 'Blue')); INSERT INTO flowers VALUES('Iris', ColorList('White','Purple'));

COMMIT;

END;

/

DECLARE

--This type declaration is not needed, because PL/SQL can see the SQL type.

--TYPE ColorList IS TABLE OF VARCHAR2(64);

--Declare a variable that can hold a set of colors. my_colors ColorList;

--Declare a record that can hold a row from the table.

--One of the record fields is a set of colors. my_flower flowers%ROWTYPE;

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

Using PL/SQL Collections with SQL Statements

new_colors ColorList; BEGIN

--Look up a name and query just the associated colors.

SELECT colors INTO my_colors FROM flowers WHERE name = 'Rose'; FOR i IN my_colors.FIRST .. my_colors.LAST

LOOP

dbms_output.put_line('Rose color = ' || my_colors(i)); END LOOP;

--Look up a name and query the entire row.

SELECT * INTO my_flower FROM flowers WHERE name = 'Iris';

--Now COLORS is a field in a record, so we access it with dot notation. FOR i IN my_flower.colors.FIRST .. my_flower.colors.LAST

LOOP

--Because we have all the table columns in the record, we can refer to NAME also.

dbms_output.put_line(my_flower.name || ' color = ' || my_flower.colors(i)); END LOOP;

--We can replace a set of colors by making a new collection and using it

--in an UPDATE statement.

new_colors := ColorList('Red','Yellow','White','Pink'); UPDATE flowers SET colors = new_colors WHERE name = 'Rose';

--Or we can modify the original collection and use it in the UPDATE.

--We'll add a new final element and fill in a value. my_flower.colors.EXTEND(1); my_flower.colors(my_flower.colors.COUNT) := 'Yellow';

UPDATE flowers SET colors = my_flower.colors WHERE name = my_flower.name;

--We can even treat the nested table column like a real table and

--insert, update, or delete elements.

--The TABLE operator makes the statement apply to the nested table produced by the subquery.

INSERT INTO TABLE(SELECT colors FROM flowers WHERE name = 'Rose') VALUES('Black');

DELETE FROM TABLE(SELECT colors FROM flowers WHERE name = 'Rose') WHERE column_ value = 'Yellow';

UPDATE TABLE(SELECT colors FROM flowers WHERE name = 'Iris') SET column_value = 'Indigo' WHERE column_value = 'Purple';

COMMIT;

END;

/

DROP TABLE flowers;

DROP TYPE ColorList;

Within PL/SQL, you can manipulate the nested table by looping through its elements, using methods such as TRIM or EXTEND, and updating some or all of the elements. Afterwards, you can store the updated table in the database again.

Example 5–28 Updating a Nested Table within a Database Table

You can revise the list of courses offered by the English Department:

DECLARE

new_courses CourseList := CourseList('Expository Writing',

'Film and Literature',

'Discursive Writing',

Using PL/SQL Collections and Records 5-19

Using PL/SQL Collections with SQL Statements

'Modern English Grammar',

'Realism and Naturalism', 'Introduction to Shakespeare', 'Modern Drama',

'The Short Story', 'The American Novel', '20th-Century Poetry',

'Advanced Workshop in Poetry');

BEGIN

UPDATE department

SET courses = new_courses WHERE name = 'English';

END;

Using PL/SQL Varrays with INSERT, UPDATE, and SELECT Statements

This example shows how you can transfer varrays between PL/SQL variables and SQL tables. You can insert table rows containing varrays, update a row to replace its varray, and select varrays into PL/SQL variables. You cannot update or delete individual varray elements directly with SQL; you have to select the varray from the table, change it in PL/SQL, then update the table to include the new varray.

--By using a varray, we put an upper limit on the number of elements

--and ensure they always come back in the same order.

CREATE TYPE RainbowTyp AS VARRAY(7) OF VARCHAR2(64);

/

CREATE TABLE rainbows (language VARCHAR2(64), colors RainbowTyp);

BEGIN

INSERT INTO rainbows VALUES('English', RainbowTyp('Red','Orange','Yellow','Green','Blue','Indigo','Violet'));

INSERT INTO rainbows VALUES('Francais', RainbowTyp('Rouge','Orange','Jaune','Vert','Bleu','Indigo','Violet'));

COMMIT;

END;

/

DECLARE

new_colors RainbowTyp := RainbowTyp('Crimson','Orange','Amber','Forest','Azure','Indigo','Violet');

some_colors RainbowTyp; BEGIN

UPDATE rainbows SET colors = new_colors WHERE language = 'English'; COMMIT;

SELECT colors INTO some_colors FROM rainbows WHERE language = 'Francais'; FOR i IN some_colors.FIRST .. some_colors.LAST

LOOP

dbms_output.put_line('Color = ' || some_colors(i)); END LOOP;

END;

/

DROP TABLE rainbows;

DROP TYPE RainbowTyp;

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

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