Professional Documents
Culture Documents
html
VARRAY Similar to Nested tables with the difference that the number of
element is fixed in VARRAY.
Associative arrays
Associative arrays were introduced in Oracle 7 release, with the name PL/SQL
tables. Due to their structure, they were recalled as Index by tables in Oracle 8
and above releases. Owing to its similarity with the conventional arrays, Oracle
10g called it as Associative array.
Associative arrays are simplest unit of ordered set of elements in a form of an
array or list which can hold any number of elements. They are physically not
stored in the database; instead they are declared within a PL/SQL block and are
persistent within the scope of an anonymous block execution (in which they are
declared).
As stated earlier, associative array exist in index-value structure. In an
associative array, an element value can be located based on the cell index (also
known as subscript). The index has to be unique and can be of number or string
type.
Syntax [1]
TYPE [COLL NAME] IS TABLE OF [ELEMENT DATA TYPE] NOT NULL INDEX BY [INDEX
DATA TYPE (BINARY_INTEGER | PLS_INTEGER | VARCHAR2)]
In the above syntax, RAW, LONG RAW, ROWID, and CHAR are the unsupported
index data types.
Example [1]
The Associative array EX_MONTH_TAB holds the days in each month of the first
half of the year. Note the string subscript and number value.
DECLARE
TYPE EX_MONTH_TAB IS TABLE OF NUMBER INDEX BY VARCHAR2(10);
L_ARRAY EX_MONTH_TAB;
BEGIN
L_ARRAY('JAN') := 31 ;
L_ARRAY('FEB') := 28 ;
L_ARRAY('MAR') := 31 ;
L_ARRAY('APR') := 30 ;
L_ARRAY('MAY') := 31 ;
L_ARRAY('JUN') := 30 ;
END;
/
1. The PL/SQL block below uses a local procedure P_ARRAY to print the
associative array passed as input.
2. DECLARE
3.
4.
L_ARRAY EX_MONTH_TAB;
5.
6. I VARCHAR2(10);
7.
BEGIN
8. I := P_ARRAY.FIRST;
9. LOOP
10.DBMS_OUTPUT.PUT_LINE('Month '||I||' has '||P_ARRAY(I)|| days);
11.I := P_ARRAY.NEXT(I);
12.EXIT WHEN I IS NULL;
13.END LOOP;
14.
END;
15.BEGIN
16. L_ARRAY('JAN') := 31 ;
17. L_ARRAY('FEB') := 28 ;
18. L_ARRAY('MAR') := 31 ;
19. L_ARRAY('APR') := 30 ;
20. L_ARRAY('MAY') := 31 ;
21. L_ARRAY('JUN') := 30 ;
22. PRINT_ARRAY (L_ARRAY);
END;
In PL/SQL
DECLARE
TYPE type_name IS TABLE OF element_type [NOT NULL];
Element type can be a User defined type or primitive data type, but cannot be
REF CURSOR.
Syntax [2b]
In SQL
CREATE [OR REPLACE] TYPE type_name IS TABLE OF element_type;
TYPE created.
Note the syntax to create the table with a nested table column. The table
definition must specify an arbitrary name of separate storage table, which
would be used by the server to hold column data.
Example [3b]
SQL> CREATE TABLE EX_COLL_TABLE
(COL1 NUMBER,
COL2 EX_NEST_TAB)
NESTED TABLE COL2 STORE AS NESTED_COL2;
TABLE created.
TABLE_NAME
COLUMN_NAME
VIR
COL1
NO
EX_COLL_TABLE
COL2
YES
EX_COLL_TABLE
SYS_NC0000200003$
NO
Nested table in SQL as standalone type stored in database: In SQL, nested table
is physically stored in the database. Later it can be used in an anonymous
PL/SQL block or during table creation. We shall see the DML operations on
nested tables and their Selection.
Insertion: INSERT statement can be prepared using the nested table collection
type.
Example [4a]
SQL> INSERT INTO EX_COLL_TABLE VALUES (1, EX_NEST_TAB(100,200,300));
1 ROW inserted.
1 ROW inserted.
1 ROW inserted.
SQL> COMMIT;
Commit complete.
Selection: Conventional way of data selection from a table would get the data
in complex and instance format.
Example [4b]
SQL> SELECT * FROM EX_COLL_TABLE;
COL1 COL2
---- ---1 EX_NEST_TAB(100,200,300)
11 EX_NEST_TAB(123,694,212,341)
23 EX_NEST_TAB(42,20)
To get the data in the readable format, TABLE function can be used. It brings the
nested table column data in relational format, thereby making it easy inferable.
Example [4c]
SQL> SELECT T1.COL1 COL1, T2.*
FROM EX_COLL_TABLE T1, TABLE(T1.COL2) T2;
COL1 COLUMN_VALUE
---- -----------1
100
200
300
11
123
11
694
11
212
11
341
23
42
23
20
The update statement below updates the collection column in the table.
Alternatively, it can be done using a PL/SQL block too.
SQL> UPDATE EX_COLL_TABLE
SET COL2 = EX_NEST_TAB (93,81)
WHERE COL1 = 23;
1 ROW updated.
COL1 COLUMN_VALUE
---- -----------1
100
200
1
300
11
123
11
694
11
212
11
341
23
93
23
81
The procedure P_CHECK_ARRAY counts of even and odd numbers in the input
array. The PL/SQL block below uses the above procedure to verify the objective.
SQL> CREATE OR REPLACE PROCEDURE P_CHECK_ARRAY (P_NEST EX_NEST_TAB)
IS
L_EVE NUMBER := 0;
L_ODD NUMBER := 0;
BEGIN
IF P_NEST.FIRST IS NULL THEN
DBMS_OUTPUT.PUT_LINE ('Empty Collection');
ELSE
FOR I IN 1..P_NEST.COUNT
LOOP
IF MOD(P_NEST(I),2) = 0 THEN
L_EVE := L_EVE+1;
ELSE
L_ODD := L_ODD+1;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE ('Array contains '|| L_EVE||' even numbers');
DBMS_OUTPUT.PUT_LINE ('Array contains '|| L_ODD||' odd numbers');
END IF;
END;
PROCEDURE created.
SQL> DECLARE
L_ARRAY EX_NEST_TAB := EX_NEST_TAB();
BEGIN
P_CHECK_ARRAY (L_ARRAY);
DBMS_OUTPUT.PUT_LINE (----Populating array----);
L_ARRAY := EX_NEST_TAB (24,164,256,17,82,93,52);
P_CHECK_ARRAY (L_ARRAY);
END;
/
Empty collection
----Populating array---Array contains 5 even numbers
Array contains 2 odd numbers
A PL/SQL block declares initializes and prints two nested table collection arrays.
Collection methods used in the blocks are discussed later in this tutorial.
DECLARE
DBMS_OUTPUT.PUT_LINE('----Display L_INI_ARRAY----');
FOR I IN 1..L_INI_ARRAY.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE('Cell: '||I||' holds element '||L_INI_ARRAY(I));
END LOOP;
DBMS_OUTPUT.PUT_LINE('----Display L_VAL_ARRAY----');
FOR I IN 1..L_VAL_ARRAY.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE('Cell: '||I||' holds element '||L_VAL_ARRAY(I));
END LOOP;
END;
/
In SQL
CREATE [OR REPLACE] TYPE type_name IS {VARRAY | VARYING ARRAY}
(size_limit) OF element_type
Syntax [3b]
In PL/SQL
DECLARE
TYPE type_name IS {VARRAY | VARYING ARRAY} (size_limit) OF element_type [NOT
NULL];
VARRAYs can be locally declared in a PL/SQL block and can be referenced within
the scope of the block.
DECLARE
TYPE EX_VRR_TAB IS VARRAY(5) OF VARCHAR2(100);
L_BATSMAN EX_VRR_TAB := EX_VRR_TAB();
L_WICKET EX_VRR_TAB := EX_VRR_TAB();
L_BOWLER EX_VRR_TAB := EX_VRR_TAB();
BEGIN
L_BATSMAN := EX_VRR_TAB(Sachin,Sehwag,Gambhir,Kohli,Yuvraj,);
L_WICKET := EX_VRR_TAB(Dhoni,);
L_BOWLER := EX_VRR_TAB(Bhajji,Nehra,Zaheer,Praveen,Munaf);
END;
VARRAYs in SQL
Example [6b]
Example [6c]
Example [6d]
The VARRAY created can be used as a column type. The example demonstrates
the Insert and Update process.
SQL> CREATE OR REPLACE TYPE SALES_TYPE AS OBJECT ( SALES_DATE DATE,
SALES_QTY NUMBER);
TYPE created.
TYPE created.
TABLE created.
1 ROW inserted.
SQL>DECLARE
L_SALES SALES_VARRAY ;
BEGIN
SELECT ITEM_SALES
INTO L_SALES
FROM ORDERS
WHERE ORD_ID=100
FOR UPDATE OF ITEM_SALES;
L_SALES(2).SALES_QTY := 140 ; -- update the second element
UPDATE ORDERS
SET ITEM_SALES = L_SALES
WHERE ORD_ID=100;
END ;
SQL> COMMIT;
Commit complete.
Collection methods
Oracle provides set of inbuilt methods, which can be used with a non null
collection (except EXISTS), to yield some information and perform basic
operations on the collection subscript and element. The list below shows the
collections available and their applicability with the different collection types. If
the collection is NULL, system raises COLLECTION_IS_NULL exception.
The collection information includes their null behavior of the collection, and
element count. The basic utilities provided by Oracle are collection extension,
deletion, and trimming.
All collection methods are compiled along with their behavior, in the below
table.
Syntax [4]
collection_name.method_name[(parameters)]
These collection methods can be used as PL/SQL construct. Oracle does not
support the collection methods in SQL.
Now, we shall study the usage of collection methods.
EXISTS
The method checks a collection for the NULL property. It returns FALSE for null
collections while TRUE for initialized ones. It is the only collection method which
is capable to work with NULL collections.
Note that if the input index value is out of range of the collection, system raises
SUBSCRIPT_OUTSIDE_LIMIT exception.
Check the below illustration to demonstrate its use.
Example [7a]
IF EX_NEST_TAB.EXISTS (5) THEN
...
ELSE
END IF;
COUNT
The method counts the number of elements in a collection. Check the below
illustration.
Check the below illustration to demonstrate the use of COUNT method.
Example [7b]
DECLARE
TYPE T IS TABLE OF NUMBER;
L T := T();
BEGIN
FOR I IN 1..100
LOOP
L.EXTEND;
L(L.LAST):=NULL;
END LOOP;
DBMS_OUTPUT.PUT_LINE('The Collection has '||to_char(L.COUNT)||' elements');
END;
LIMIT
The method returns the maximum count of elements in a collection array. It
can only be used with VARRAYs.
Note the difference between COUNT and LIMIT methods in the below example.
Example [7c]
DECLARE
TYPE v IS VARRAY(10) OF NUMBER;
M V := V();
BEGIN
M := V(1,3,2,3,2,3);
DBMS_OUTPUT.PUT_LINE('The Collection has '||to_char(M.COUNT)||' elements');
DBMS_OUTPUT.PUT_LINE('The Collection can accommodate '||to_char(M.limit)||' elements');
END;
/
The methods return the first and last subscript of a collection. For an
uninitialized or empty collection, the method values are NULL. Check the below
illustration to demonstrate its use of the methods.
Example [7d]
DECLARE
TYPE T IS TABLE OF NUMBER;
M T := T();
BEGIN
DBMS_OUTPUT.PUT_LINE('FIRST and LAST subscripts for Empty collection are '||M.FIRST||'
and '||M.LAST);
M := T(272,4720,482,183,481,372,482,127,5943);
DBMS_OUTPUT.PUT_LINE('FIRST and LAST subscripts for populated collection are '||
M.FIRST||' and '||M.LAST);
END;
/
M T := T(12,15,73,1,87,22,89);
BEGIN
DBMS_OUTPUT.PUT_LINE('Subscript before the 5th element is:'||TO_CHAR(M.PRIOR(5)));
DBMS_OUTPUT.PUT_LINE('Subscript after the 5th element is:'||TO_CHAR(M.NEXT(5)));
END;
/
EXTEND
The method allows addition of new elements to a persistent collection. By
default, it appends one element to a collection. Upon specification, it can add N
elements to a collection. EXTEND(m,n) make m copies of nth element to a
collection.
Note that is cannot be used for Associative arrays.
Example [7f]
DECLARE
TYPE T IS TABLE OF NUMBER;
M T := T(12,15,73,1,87,22,89);
BEGIN
DBMS_OUTPUT.PUT_LINE('No of elements in Collection:'|| TO_CHAR(M.COUNT));
M.EXTEND;
DBMS_OUTPUT.PUT_LINE('No of elements in Collection after first extension:'||
TO_CHAR(M.COUNT));
M.EXTEND(5);
No OF elements IN Collection:7
No OF elements IN Collection after FIRST extension:8
No OF elements IN Collection after SECOND extension:13
No OF elements IN Collection after third extension:15
TRIM
As the name suggests, the method trims a persistent collection. By default, it
trims single element in a collection. It can also trim N elements, if the count is
specified with the method/
Note that is cannot be used for Associative arrays.
Example [7g]
DECLARE
TYPE T IS TABLE OF NUMBER;
M T := T(12,15,73,1,87,22,89);
BEGIN
DBMS_OUTPUT.PUT_LINE('Elements in Collection:'|| TO_CHAR(M.COUNT));
M.TRIM;
DBMS_OUTPUT.PUT_LINE('Elements in Collection after first trim:'|| TO_CHAR(M.COUNT));
M.TRIM(5);
DBMS_OUTPUT.PUT_LINE('Elements in Collection after second trim:'|| TO_CHAR(M.COUNT));
END;
/
Elements IN Collection:7
Elements IN Collection after FIRST TRIM:6
Elements IN Collection after SECOND TRIM:1
DELETE
The method drops a cell from a collection. It removes a single element by
default, but can remove N elements and even by range, if specified with the
method.
Example [7h]
DECLARE
TYPE T IS TABLE OF NUMBER;
M T := T(12,15,73,1,87,22,89);
BEGIN
DBMS_OUTPUT.PUT_LINE ('Count of elements before deletion:'||TO_CHAR(M.COUNT));
DBMS_OUTPUT.PUT_LINE ('Last index of elements before deletion:'||TO_CHAR(M.LAST));
M.DELETE(2);
DBMS_OUTPUT.PUT_LINE ('Count of elements after deletion:'||TO_CHAR(M.COUNT));
DBMS_OUTPUT.PUT_LINE ('Last subscript of elements after deletion:'||TO_CHAR(M.LAST));
END;
/