How to handle data in BULK
| What Is a PL/SQL Collection ?
A collection is an ordered group of elements, all of the same type. PL/SQL offers these collection types:
You can define collection types in a procedure, function, or package and pass collection variables as parameters, Nested Tables, Varrays and Associative arrays Within the database, nested tables can be considered one-column database tables. A varray stores elements in an order and allows to reference individual elements easily Associative arrays are sets of key-value pairs, where each key is unique
Manipulating Collections 1) Defining Collection Types declare TYPE number_table is TABLE of number(10); TYPE emptab is TABLE of emp%rowtype; TYPE empsaltype is table of number index by varchar2(50); TYPE int_array_type IS VARRAY(50) OF INTEGER; As database object SQL> create or replace type emptab as object(empno number, ename varchar2(50)); 2) Initializing and Referencing Collections To initialize a nested table or varray, you use a constructor, a system-defined function declare TYPE number_table is TABLE of number(10); TYPE int_array_type IS VARRAY(50) OF INTEGER; nt numbet_table := number_table(); int_arr int_array_type := int_array_type(null, null, null, null); 3) Using Collection Methods The following collection methods help generalize code, 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. The syntax follows:
collection_name.method_name[(parameters)]
i) EXISTS(n) returns TRUE if the nth element in a collection exists.
ii) COUNT returns the number of elements that a collection currently contains
iii) For varrays, LIMIT returns the maximum number of elements that a varray can contain
iv) FIRST and LAST return the first and last (smallest and largest) index numbers in a collection.
v) To increase the size of a nested table or varray, use EXTEND. You cannot use EXTEND with index-by tables.
This procedure has three forms:
EXTEND appends one null element to a collection.
EXTEND(n) appends n null elements to a collection.
EXTEND(n,i) appends n copies of the ith element to a collection.
vi) TRIM decreasing the Size of a Collection (TRIM Method)
This procedure has two forms:
TRIM removes one element from the end of a collection.
TRIM(n) removes n elements from the end of a collection.
vii) Deleting Collection Elements (DELETE Method)
This procedure has various forms:
DELETE removes all elements from a collection.
DELETE(n) removes the nth element from an associative array with a numeric key or a nested table.
If the associative array has a string key, the element corresponding to the key value is deleted.
If n is null, DELETE(n) does nothing.
DELETE(m,n) removes all elements in the range m..n from an associative array or nested table.
If m is larger than n or if m or n is null, DELETE(m,n) does nothing.
Avoiding Collection Exceptions In most cases, if you reference a nonexistent collection element, PL/SQL raises a predefined exception. Consider the following example: DECLARE TYPE NumList IS TABLE OF NUMBER; nums NumList; -- atomically null BEGIN /* Assume execution continues despite the raised exceptions. */ nums(1) := 1; -- raises COLLECTION_IS_NULL (1) nums := NumList(1,2); -- initialize table nums(NULL) := 3 -- raises VALUE_ERROR (2) nums(0) := 3; -- raises SUBSCRIPT_OUTSIDE_LIMIT (3) nums(3) := 3; -- raises SUBSCRIPT_BEYOND_COUNT (4) nums.DELETE(1); -- delete element 1 IF nums(1) = 1 THEN ... -- raises NO_DATA_FOUND (5) In the first case, the nested table is atomically null. In the second case, The following list shows when a given exception is raised:
In some cases, you can pass invalid subscripts to a method without raising an exception. DECLARE TYPE NumList IS TABLE OF NUMBER; nums NumList := NumList(10,20,30); -- initialize table BEGIN nums.DELETE(-1); -- does not raise SUBSCRIPT_OUTSIDE_LIMIT nums.DELETE(3); -- delete 3rd element dbms_output.put_line(nums.COUNT); -- prints 2 nums(3) := 30; -- allowed; does not raise NO_DATA_FOUND dbms_output.put_line(nums.COUNT); -- prints 3 END; Reducing Loop Overhead for Collections with Bulk Binds Collections can be used to bulk bind data values with SQL statement BULK COLLECT declare TYPE emptab is TABLE of emp%rowtype; et emptab; n1 number; BEGIN select * BULK COLLECT INTO et from emp; for n1 in et.FIRST..et.LAST LOOP dbms_output.put_line(et(n1).ename); END LOOP; END; / A DML statement can transfer all the elements of a collection in a single operation, a process known as bulk binding BULK DML declare TYPE numtab is table of number; type chartab is table of varchar2(200); v_empno numtab; v_ename chartab; v_sal numtab; n1 number; BEGIN select empno, ename, sal BULK COLLECT INTO v_empno,v_ename, v_sal from emp; for n1 in v_sal.FIRST..v_sal.LAST LOOP v_sal(n1) := v_sal(n1)*1.1; END LOOP; forall n1 in v_empno.first..v_empno.last update emp set sal=v_sal(n1) where empno=v_empno(n1); END; / Using rowid for BULK update or delete declare TYPE numtab is table of number; type chartab is table of varchar2(200); type rowidtab is table of rowid; v_empno numtab; v_ename chartab; v_sal numtab; v_rid rowidtab; n1 number; BEGIN select rowid, empno, ename, sal BULK COLLECT INTO v_rid, v_empno,v_ename, v_sal from emp; v_sal(n1) := v_sal(n1)*1.1; END LOOP; forall n1 in v_empno.first..v_empno.last update emp set sal=v_sal(n1) where rowid=v_rid(n1); END; / Upsert using values from external table Task
1) Read external table
2) Check whether record exists in the database table CUSTOMER for the key value custno
3) If records is not present then insert else update
declare
TYPE numtab is table of number;
type chartab is table of varchar2(200);
type rowidtab is table of rowid;
v_custno numtab;
v_custname chartab;
v_custtype numtab;
v_c1 numtab;
v_c2 chartab;
v_rid rowidtab;
n1 number;
nr number;
BEGIN
select rowid, custno, custname, custtype,b.c1, b.c2 BULK COLLECT INTO v_rid, v_custno,v_custname, v_custtype, v_c1, v_c2
from customer a, ext_table b where a.custno(+)=b.c1 order by 1 nulls first,2;
-- The data is ordered by riowid. Nulls values first
-- The first set of rows where rowid is null is uded for insert
nr:=0;
forall n1 in v_custno.first..v_custno.last LOOP
if v_rid(n1) is null then nr:=n1; end if;
END IF;
if nr>0 then
forall n1 in 1..nr
insert into customer(custno,custname) values(v_c1(n1), v_c2(n1));
end if;
if nr < v_rid.count then
forall n1 in nr+1..v_rid.count
update customer set custname=v_c2(n1) where rowid=v_rid(n1);
end if;
END;
/
GLOBAL TEMPORARY TABLES In Oracle Specify GLOBAL TEMPORARY in the create table statemnt to indicate that the table is temporary. Temporary tables are useful in applications where a result set is to be buffered, perhaps because it is constructed by running multiple DML operations. CREATE GLOBAL TEMPORARY TABLE admin_work_area
(startdate DATE,
enddate DATE,
class CHAR(20))
ON COMMIT DELETE ROWS;
For a global temporary table
For small amount of data rows global temporary table is an alternative for collections. |