Professional Documents
Culture Documents
Collection Methods
Collection Methods
Collection methods are PL/SQL’s in-built functions and procedures which can be used in
conjunction with collections.
Using PL/SQL collection method you can get the information as well as alter the content of
the collection.
In Oracle PL/SQL, collection methods can be used using Dot (.) notation. syntax.
===========================================================================
--Q. Does collection method COUNT ( ) works the same with a Nested Table?
No. This is because COUNT ( ), returns the number of non-empty elements in a nested table
since it is possible for a collection nested table to have individual elements that are empty.
As Associative Arrays don’t require initialization, thus you will not get this exception with
them.
===========================================================================
-- Examples of Collection Method COUNT ( )
DECLARE
TYPE my_nested_table IS TABLE OF number;
var_nt my_nested_table := my_nested_table (9,18,27,36,45,54,63,72,81,90);
BEGIN
DBMS_OUTPUT.PUT_LINE ('The Size of the Nested Table is ' ||var_nt.count);
END;
DECLARE
TYPE my_nested_table IS TABLE OF number;
var_nt my_nested_table := my_nested_table (9,18,27,36,45,54,63,72,81,90);
BEGIN
IF var_nt.count >= 10 THEN
DBMS_OUTPUT.PUT_LINE (‘you have already inserted 10 elements in your Nested table);
DBMS_OUTPUT.PUT_LINE ('Are you sure you want to insert more?');
END IF;
END;
Example 3. Similarly you can use the collection method COUNT ( ) with Loops.
DECLARE
TYPE my_nested_table IS TABLE OF number;
var_nt my_nested_table := my_nested_table (9,18,27,36,45,54,63,72,81,90);
BEGIN
for i in 1..var_nt.count
loop
dbms_output.put_line ('value stored at index '||i||'is'||var_nt(i));
end loop;
end;
===========================================================================
Collection Method: EXISTS
You can use EXISTS ( ) function to check the existence of a specific row within the collection.
EXISTS function takes the subscript/index number of a cell of the collection as an Input and
searches it in the collection.If it finds any element corresponding to index number then it
returns TRUE otherwise it returns FALSE.
--Q. What if I remove an already existed row using TRIM or DELETE function?
If you remove a row using Trim or Delete function then collection method EXISTS ( ) will
return FALSE for the index of that row.
--Q. If it does not raise an exception then what will happen if I applied this function to an
uninitialized collection?
Collection method EXISTS ( ) returns false, if it is applied either to an uninitialized collection
or to an initialize collection with no elements.
DECLARE
TYPE my_nested_table IS TABLE OF VARCHAR2 (20);
var_1 my_nested_table := my_nested_table('Super Man','Iron Man','Bat Man');
BEGIN
IF var_1.EXISTS (1) THEN
DBMS_OUTPUT.PUT_LINE ('Hey we found '|| var_1 (1));
ELSE
DBMS_OUTPUT.PUT_LINE ('Sorry, no data at this INDEX');
END IF;
END;
In the above program we are checking if there is any element at index 1 into the collection
‘my_nested_table’ or not.
If there is an element at the specified index then the IF part of the IF-ELSE statement will
execute otherwise the ELSE part will come into the action.
declare
type t1 is table of number;
v_t t1 := t1(1,2,3,4,5);
begin
if v_t.exists (6) then
dbms_output.put_line (v_t(6));
else
dbms_output.put_line ('Data is not present you can add the data');
v_t.extend;
v_t(6):=6;
dbms_output.put_line ('New data inserted');
end if;
for i in v_t.first..v_t.last loop
dbms_output.put_line (v_t(i));
end loop;
end;
===========================================================================
Collection Methods: FIRST & LAST
--Q. Can we use these collection methods with any type of collection?
Yes! You can use both these functions with all three types of collections that are Associative
Array, Nested table and VARRAYs.
--Q. When does collection method FIRST ( ) and LAST ( ) return null?
Both the functions return null when applied to an empty collection or when applied to an
initialize collection that has no elements.
--Example: How to use collection function FIRST and LAST with collection?
DECLARE
TYPE nt_tab IS TABLE OF NUMBER;
col_var nt_tab := nt_tab(10, 20, 30, 40, 50);
BEGIN
DBMS_OUTPUT.PUT_LINE ('First Index of the Nested table is ' || col_var.FIRST);
DBMS_OUTPUT.PUT_LINE ('Last Index of the Nested table is ' || col_var.LAST);
END;
/
In the above example we have created a nested table with the name NT_TAB and initialized
it using collection variable col_var.
This nested table has 5 indexes into which we have stored the values.
Thus on execution the result from the first DBMS_OUTPUT will be 1 and from the second
DBMS_OUTPUT statement will be 5.
--Q. What if we delete the first element of the nested table? What will then be the output
of collection function FIRST?
If you delete the first element of the collection function then the collection function FIRST
will return the subscript which is greater than 1 and is holding some data.
Let’s see the example:
DECLARE
TYPE nt_tab IS TABLE OF NUMBER;
col_var nt_tab := nt_tab(10, 20, 30, 40, 50);
BEGIN
col_var.DELETE(1);
col_var.DELETE(5);
DBMS_OUTPUT.PUT_LINE ('First Index after DELETE is ' || col_var.FIRST);
DBMS_OUTPUT.PUT_LINE ('Last Index after DELETE is ' || col_var.LAST);
END;
/
After deleting the first element which is 10 on index 1 the new lowest subscript is now 2
which has some data stored into it. Thus on execution the result will be 2.
--Q. What if I delete the element from the middle of the collection?
If you delete the data from the middle then the collection function LAST will return a value
which is greater than the value returned by COUNT method.
--Q. Can we see the data stored into the indexes of the collection using FIRST and LAST
collection methods?
yes! Of course. You can use these functions to see the data stored in lowest and highest
index of the collection.
--For example
DECLARE
TYPE nt_tab IS TABLE OF NUMBER;
col_var nt_tab := nt_tab(10, 20, 30, 40, 50);
BEGIN
DBMS_OUTPUT.PUT_LINE ('Value stored at First Index is ' || col_var(col_var.FIRST));
DBMS_OUTPUT.PUT_LINE ('Value stored at First Index is ' || col_var(col_var.LAST));
END;
In order to see the data stored into the first and last index you just have to place the
function calls of these function inside
the parenthesis of collection variable which is col_var just like we did in the above example.
===========================================================================
Collection Method: LIMIT
--Q. Does this function works with other two collection Nested Tables and Associative
Array also?
Collection method LIMIT only works with VARRAY. If it applied to Nested table or
associative array then this function will either return a NULL or No value. So the answer is,
No, the collection function LIMIT does not work with Nested tables and Associative Arrays.
--Q. Does the collection function LIMIT raises any exception? If yes, then when?
Yes the function LIMIT raises COLLECTION_IS_NULL exception if it is applied to an
uninitialized nested table or a VARRAY.
-- Don’t we have the function COUNT which gives the same information?
The collection function LIMIT returns the total number of indexes of a VARRAY regardless of
whether these indexes are empty or holding some data.
While the collection function COUNT returns the number of Indexes which are not empty
and holding some data.
DECLARE
TYPE t1 IS VARRAY ( 5 ) OF NUMBER;
V_t t1 := t1 ();
BEGIN
V_t.extend;
v_t(1) := 10 * 2;
dbms_output.put_line('Total Number of Index ' || v_t.limit);
dbms_output.put_line('Total Number of Index which are occupied ' || v_t.count);
END;
In the above code we have a VARRAY which is capable of holding 5 elements of NUMBER
datatype. Result of LIMIT function will return 5 because that is the total strength of our
VARRAY while the count function return 1 because among those 5 indexes there is only one
index which has some data stored into it.
--Example-Finding out the number of vacant index for your use in a VARRAY is very easy.
If you subtract the result of count function from the result of the LIMIT function you will get
the total number of elements left un-used for you to store data into a varray.
DECLAR
TYPE t1 IS VARRAY ( 5 ) OF NUMBER;
V_t t1:= t1 ();
BEGIN
v_t.extend;
v_t (1) := 10 * 2;
dbms_output.put_line('Total Number of Index ' || v_t.limit);
dbms_output.put_line('Total Number of Index which are occupied ' || v_t.count);
dbms_output.put_line('Total Number of Vacant index left for use '
|| (v_t.limit - v_t.count) );
END;
===========================================================================
Collection Method: PRIOR & NEXT
--Q. Can we use both these functions with all three types of collections?
Yes, both Prior and Next collection functions can be used with all the three types of
collections.
--Q. When will PL/SQL Collection Methods Prior and Next return null?
Collection Method Prior returns null when there are no lower subscript values available and
Collection method Next returns null when there are no higher subscript values available to
return.
--Q. What will be the output of Collection method Next and Prior if we use them with
associative array?
If collection method PRIOR and NEXT are used with associative arrays then they will return
an output of VARCHAR2 or LONG datatype.
Output-
Index prior to index 3 is 2
Value before 3rd Index is 18
The first output statement will return the index number prior to the Index number 3 which
has some value stored into it.
In the second output statement we called the Prior function and supplied it as an input to
the collection object.
var_nt(var_nt.PRIOR(3))
--Q. What will happen if we delete the Previous Lowest Index from the nested table?
In that case, result will definitely not be the same. Prior function returns the previous
lowest index. But that Index must contain some value.
DECLARE
TYPE my_nested_table IS TABLE OF NUMBER;
var_nt my_nested_table := my_nested_table(9,18,27,36,45,54,63,72,81,90);
BEGIN
var_nt.DELETE(2);
dbms_output.put_line('Index prior to index 3 is '||var_nt.PRIOR(3));
dbms_output.put_line('Value before 3rd Index is '||var_nt(var_nt.PRIOR(3)));
END;
/
Output-
Prior index is:1
Prior index is:9
The first output statement will return the next non-empty index number while the second
one will return the data stored into that index. The working of both these statements will
be the same as we discussed above.
===========================================================================
Collection Method: DELETE Procedure
--Q. Can we use DELETE Procedure in Oracle Database with all the collections?
Yes, collection method DELETE can be used with all three types of collections.
These are – Nested table, VARRAYs and Associative arrays.
--Q. if we use the procedure DELETE with VARRAYs then won’t it make a sparse
collection?
As VARRAY is not a sparse collection hence we cannot delete individual rows from it.
Furthermore, the only procedure call that we can execute with VARRAY is the first one.
Which is collection method DELETE without any arguments which removes all the elements
from the collection.
The only way of removing an individual row from a VARRAY is by trimming it from its end
using another procedure
call TRIM.
DECLARE
TYPE my_nested_table IS TABLE OF NUMBER;
var_nt my_nested_table := my_nested_table(2,4,6,8,10,12,14,16,18,20);
BEGIN
DBMS_OUTPUT.PUT_LINE('After Deleted');
--Delete Specific Index
var_nt.DELETE(5);
IF var_nt.EXISTS(5) THEN
DBMS_OUTPUT.PUT_LINE('Value at Index [5] is '|| var_nt(5));
ELSE
DBMS_OUTPUT.PUT_LINE('Data is Deleted');
END IF;
END;
/
DECLARE
TYPE my_nested_table IS
TABLE OF NUMBER;
var_nt my_nested_table := my_nested_table(2,4,6,8,10,12,14,16,18,20);
BEGIN
--Delete Range
var_nt.DELETE(2,6);
FOR i IN 1..var_nt.LAST LOOP
IF var_nt.EXISTS(i) THEN
DBMS_OUTPUT.PUT_LINE('Value at Index is’ || var_nt(i));
END IF;
END LOOP;
END;
/
Here you have to specify two Indexes and the procedure deletes the range of elements
which fall between starting-index and ending-index.
===========================================================================
Collection method: EXTEND procedure
--Q. What if I apply the collection method EXTEND to an uninitialized Nested table or
VARRAY?
If PL/SQL Collection Method EXTEND is applied to an uninitialized collection then it will
show a ‘COLLECTION_IS_NULL’ exception.
DECLARE
TYPE my_nestedTable IS TABLE OF number;
v_t my_nestedTable := my_nestedTable();
BEGIN
v_t.EXTEND;
v_t (1) := 28;
DBMS_OUTPUT.PUT_LINE ('Data at index 1 is '|| v_t (1));
v_t.EXTEND(5,1);
DBMS_OUTPUT.PUT_LINE ('Data at index 4 is '|| v_t (4));
END;
/
o/p
Data at index 1 is 28
Data at index 4 is 28
DECLARE
TYPE my_Varray IS VARRAY (5) OF NUMBER;
v_t my_Varray := my_Varray();
BEGIN
v_t.EXTEND;
v_t (1) := 10;
DBMS_OUTPUT.PUT_LINE('Data at index 1 is '|| v_t (1));
END;
===========================================================================
Collection Method: Trim Procedure
--Q. In how many ways can we call the collection method TRIM procedure in Oracle
Database?
As PL/SQL Collection Method TRIM is an Overloaded procedure thus we can call it in two
different ways.
--TRIM: Trim procedure without parameter :-
If we use TRIM procedure without any parameters then it will remove only one element
from the end of the collection.
Info: Trim procedure will raise an error if there is an attempt to trim space below zero
elements.
--Q. Can we use PL/SQL collection method TRIM with all the three types of collections?
Unfortunately no, we cannot. Similar to PL/SQL Collection procedure EXTEND, procedure
TRIM can only be used with collection Nested Tables and VARRAYs.
However we cannot use it with Associative Arrays.
--Q. What will happen if we use PL/SQL Collection Procedure TRIM with an Associative
array?
If collection method Trim of Oracle Database versions is used with an Associative Array then
you will get a compile time error.
--Q. Are there any other exceptions associated with PL/SQL Collection method Trim which
we should know about?
Yes, there is one more exception associated with TRIM procedure and that is
COLLECTION_IS_NULL exception.
Whenever you apply collection procedure TRIM to an uninitialized Nested Table or VARRAY
then the compiler will raise COLLECTION_IS_NULL exception.
--examples
DECLARE
TYPE my_nestedTable IS TABLE OF number;
v_t my_nestedTable := my_nestedTable(1,2,3,4,5);
BEGIN
v_t.TRIM;
DBMS_OUTPUT.PUT_LINE ('After TRIM procedure');
FOR i IN 1.. v_t.COUNT LOOP
DBMS_OUTPUT.PUT_LINE (v_t (i));
END LOOP;
END;
/
Output-
After TRIM procedure
1
2
3
4
DECLARE
TYPE my_nestedTable IS TABLE OF number;
v_t my_nestedTable := my_nestedTable(1,2,3,4,5);
BEGIN
v_t.TRIM (3);
DBMS_OUTPUT.PUT_LINE ('After TRIM procedure');
FOR i IN 1.. v_t.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE (v_t (i));
END LOOP;
END;
/
Output-
After TRIM procedure
1
2
DECLARE
TYPE my_nestedTable IS TABLE OF number;
v_t my_nestedTable := my_nestedTable(1,2,3,4,5);
BEGIN
v_t.TRIM(6);
DBMS_OUTPUT.PUT_LINE ('After TRIM procedure');
FOR i IN 1.. v_t.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE (v_t (i));
END LOOP;
END;
/
SUBSCRIPT_BEYOND_COUNT exception occurs when we pass an argument greater than the
total number of elements of the collection.
DECLARE
TYPE inBlock_vry IS VARRAY (5) OF NUMBER;
v_t inBlock_vry := inBlock_vry(1, 2, 3, 4, 5);
BEGIN
--TRIM without parameter
v_t.TRIM;
DBMS_OUTPUT.PUT_LINE ('After TRIM procedure');
FOR i IN 1.. v_t.COUNT LOOP
DBMS_OUTPUT.PUT_LINE (v_t (i));
END LOOP;
--TRIM with Parameter
v_t.TRIM (2);
DBMS_OUTPUT.PUT_LINE ('After TRIM procedure');
FOR i IN 1.. v_t.COUNT LOOP
DBMS_OUTPUT.PUT_LINE (v_t (i));
END LOOP;
END;
Collection Exceptions
The following table provides the collection exceptions and when they are raised −
Collection Exception Raised in Situations
=============================THE END======================================