You are on page 1of 24

Bulk Collections and Inserts in Oracle 9i & 10g

Simay Alpge

Next Information Systems, Inc.

April 14, 2004

Next Information Systems

AGENDA
 

   

Performance gains with Bulk Binding Array processing with BULK COLLECT and FORALL Error handling. Native Dynamic SQL with Bulk binding. Typical problems. Oracle 10g FORALL improvements.

April 14, 2004

Next Information Systems

Performance Gains with Bulk Binding


Context Switching
SQL

PL/SQL Engine Procedural statement Executor


DATA

SQL Engine SQL Statement Executor

April 14, 2004

Next Information Systems

Bulk Binding Categories




With SELECT or FETCH statements


BULK COLLECT INTO

In-Bind binding. InINSERT or UPDATE OutOut-Bind binding. RETURNING clause


Next Information Systems 4

April 14, 2004

SELECT / FETCH statements


Data may be Bulk Collected/Fetched into : Table.column%TYPE 8i and above Record of arrays 8i and above Table%ROWTYPE 9.0.2.3 and above Cursor%ROWTYPE 9.0.2.3 and above Array of records Nested tables
April 14, 2004

9.0.2.3 and above 8i and above


Next Information Systems 5

SELECT statement Table.column%TYPE


DECLARE TYPE cust_tab IS TABLE OF customer.customer_account_id%TYPE INDEX BY BINARY_INTEGER; Custs cust_tab; BEGIN SELECT customer_account_id BULK COLLECT INTO custs FROM customer WHERE effective_date BETWEEN TO_DATE(01-Jan-2004,DD-MONTO_DATE(01-Jan-2004,DD-MON-RRRR) AND TRUNC(SYSDATE); END;
April 14, 2004 Next Information Systems 6

FETCH statements
Table.column%TYPE
DECLARE TYPE CustList IS TABLE OF Customer.Customer_Account_Id%TYPE INDEX BY BINARY_INTEGER; Custs CustList; CURSOR c1 IS SELECT customer_account_id FROM Customer WHERE effective_date BETWEEN TO_DATE(01-JANTO_DATE(01-JAN-2004, DD-MON-RRRR) AND DD-MONTRUNC(SYSDATE); BEGIN OPEN c1; FETCH c1 BULK COLLECT INTO Custs; CLOSE c1; END;

April 14, 2004

Next Information Systems

FETCH statement:Record of Arrays


DECLARE TYPE CustRec IS RECORD (R_Customer_Account_id Customer.Customer_Account_id%TYPE, R_Effective_date Customer.Effective_Date%TYPE, R_Expired_date Customer.Expired_Date%TYPE); v_Custrec CustRec; v_Array_Size NUMBER := 100; CURSOR c1 IS SELECT Customer_Account_Id, Effective_Date, Expired_Date FROM Customer; BEGIN OPEN c1; LOOP FETCH c1 BULK COLLECT INTO v_Custrec.R_Customer_account_id,v_Custrec.R_Effective_Date, v_Custrec.R_Expired_Date LIMIT v_Array_Size; END LOOP; CLOSE c1; END;
April 14, 2004 Next Information Systems 8

SELECT statement
Table%ROWTYPE
DECLARE TYPE Cust_tab IS TABLE OF Customers_Active%ROWTYPE; Custs Cust_tab; BEGIN SELECT Customer_Account_Id, Effective_Date, Expired_Date BULK COLLECT INTO Custs FROM Customers_Active WHERE Effective_date BETWEEN TO_DATE(01-JANTO_DATE(01-JAN-2004 , DD-MON-RRRR) AND DD-MONTRUNC(SYSDATE); END;
April 14, 2004 Next Information Systems 9

FETCH statement
CURSOR%ROWTYPE
DECLARE CURSOR c1 IS SELECT Customer_Account_Id, Effective_Date,Expired_Date FROM Customer WHERE Effective_Date BETWEEN TO_DATE(01-JanTO_DATE(01-Jan-2004, DD-MON-RRRR) ANDTRUNC(SYSDATE); DD-MONTYPE Cust_tab IS TABLE OF C1%ROWTYPE; Custs Cust_tab; BEGIN OPEN c1; LOOP FETCH c1 BULK COLLECT INTO Custs LIMIT 100; EXIT WHEN c1%NOTFOUND; END LOOP; END ;
April 14, 2004 Next Information Systems 10

FETCH statement: Array Of Records


DECLARE TYPE CustRec IS RECORD (R_Customer_Account_id Customer.Customer_Account_id%TYPE, R_Effective_Date Customer.Effective_Date%TYPE, R_Expired_Date Customer.Expired_Date%TYPE); TYPE CustRecTab IS TABLE OF CustRec; Cust_Recs CustRecTab; v_Array_Size NUMBER := 100; CURSOR c1 IS SELECT Customer_Account_Id, Effective_Date, Expired_Date FROM Customer; BEGIN OPEN c1; FETCH c1 BULK COLLECT INTO Cust_Recs LIMIT v_Array_Size; CLOSE c1; END;
April 14, 2004 Next Information Systems 11

FETCH statement Nested Tables


CREATE TYPE Coords AS OBJECT (x NUMBER, y NUMBER); CREATE TABLE grid (num NUMBER, loc Coords); INSERT INTO grid VALUES(10, Coords(1,2)); INSERT INTO grid VALUES(20, Coords(3,4)); DECLARE TYPE CoordsTab IS TABLE OF Coords; pairs CoordsTab; BEGIN SELECT loc BULK COLLECT INTO pairs FROM grid; -- now pairs contains (1,2) and (3,4) END;

April 14, 2004

Next Information Systems

12

In-Bind Binding InDECLARE CURSOR c1 SELECT Customer_Account_Id, Effective_Date,Expired_Date FROM Customer WHERE Effective_Date BETWEEN TO_DATE(01-Jan-2003, DD-MONTO_DATE(01-JanDD-MONRRRR) And TO_DATE(01-Jan-2004, DD-MON-RRRR); TO_DATE(01-JanDD-MONTYPE Cust_tab IS TABLE OF C1%ROWTYPE; Custs Cust_tab; BEGIN OPEN c1; LOOP FETCH c1 BULK COLLECT INTO Custs LIMIT 100; END LOOP; FORALL i IN 1 .. Custs.COUNT SAVE EXCEPTIONS INSERT into Customer_History VALUES Custs (i); .
April 14, 2004 Next Information Systems 13

FORALL Error Handling


No more FULL rollback in case of an EXCEPTION  SAVE EXCEPTIONS  SQL%BULK_EXCEPTIONS Collection of records  SQL%BULK_EXCEPTIONS(i).ERROR_INDEX stores itireration when exception is raised.  SQL%BULK_EXCEPTIONS(i).ERROR_CODE - stores Oracle error code.

April 14, 2004

Next Information Systems

14

Typical Problems
FORALL limitations


SINGLE DML (INSERT, UPDATE, DELETE) statement is allowed. No IF condition within FORALL. For multi table INSERT/UPDATE use WHEN clause instead of IF condition. No DBMS_OUTPUT or other OUTPUT statements within FORALL. No SELECT .. BULK COLLECT within FORALL statement.
Next Information Systems 15

April 14, 2004

OutOut-Bind binding
DECLARE TYPE AcctTab IS TABLE OF Acct_Install.Customer_Account_id%TYPE; Acusts AcctTab; BEGIN DELETE FROM Acct_Install WHERE INSTALL_DATE = TRUNC(TO_DATE(01-jan-1970,DD-MONTRUNC(TO_DATE(01-jan-1970,DD-MON-RRRR) RETURNING Customer_Account_Id BULK COLLECT INTO Acusts; END;

April 14, 2004

Next Information Systems

16

NATIVE Dynamic SQL


EXECUTE IMMEDIATE FORALL RETURNING INTO USING COLLECT INTO %BULK_ROWCOUNT - cursor attribute shows total cumulative execution.
April 14, 2004 Next Information Systems 17

NATIVE Dynamic SQL


DECLARE TYPE CustList IS TABLE OF NUMBER; TYPE NameList IS TABLE OF VARCHAR2(15); Custnos CustList; Custnames NameList; BEGIN Custnos := CustList(1,2,3,4,5); FORALL i IN 1..5 EXECUTE IMMEDIATE 'UPDATE Customer SET Cust_Name = TRIM(Cust_name) WHERE Custno = :1 RETURNING Cust_Name INTO :2' USING Custnos(i) RETURNING BULK COLLECT INTO Custnames; ... END;
April 14, 2004 Next Information Systems 18

Oracle 10g FORALL


Indices of
When binding area contains gaps

Values of Subset of element


selection in the array

April 14, 2004

Next Information Systems

19

Oracle 10g FORALL VALUES OF


DECLARE TYPE CUST_IDS IS TABLE OF CUSTOMER.CUSTOMER_ID%TYPE; TYPE PHONE_NOS IS TABLE OF CUSTOMER.PHONE_NBR%TYPE; TYPE EDATES IS TABLE OF CUSTOMER.EFF_DATE%TYPE; TYPE EXPDATES IS TABLE OF CUSTOMER.EXPIRED_DATE%TYPE; TYPE A_INDX IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER; EXPIRED_CUSTS A_INDX; ACTIVE_CUSTS A_INDX;

April 14, 2004

Next Information Systems

20

Oracle 10g FORALL VALUES OF (Continue)


CUSTID CUST_ID; PHONES PHONE_NOS; EFFDTS EDATES; EXPDTS EXPDATES; V_I BINARY_INTEGER

BEGIN
SELECT CUSTOMER_ID, PHONE_NBR, EFF_DATE, EXPIRED_DATE BULK COLLECT INTO CUSTIDS, PHONES, EFFDTS, EXPDTS; FROM CUSTOMER WHERE Effective_Date BETWEEN TO_DATE(01-JanTO_DATE(01-Jan-2003, DD-MON-RRRR) And DD-MONTO_DATE(01-JanTO_DATE(01-Jan-2004, DD-MON-RRRR); DD-MONEND;

April 14, 2004

Next Information Systems

21

Oracle 10g FORALL VALUES OF (Continue)


FOR v_i IN CUSTIDS.FIRST .. CUSTIDS.LAST LOOP IF FN_EXPIRED THEN EXPIRED_CUSTS (V_I) := v_i; ELSE ACTIVE_CUSTS(V_I) := v_i; END IF; END LOOP; BEGIN FORALL V_ I VALUES OF EXPIRED_CUSTS SAVE EXCEPTIONS INSERT INTO CUSTOMER_HISTORY VALUES (CUSTIDS (V_I), PHONES(V_I), EFFDTS(V_I), EXPDTS(V_); FORALL V_ I VALUES OF ACTIVE_CUSTS SAVE EXCEPTIONS INSERT INTO CUSTOMER_ACTIVE VALUES (CUSTIDS (V_I), PHONES(V_I), EFFDTS(V_I), EXPDTS(V_); COMMIT; END;

April 14, 2004

Next Information Systems

22

Questions

April 14, 2004

Next Information Systems

23

THANK YOU
dbasig@nyoug.org alpoge@nextinfosys.com

April 14, 2004

Next Information Systems

24

You might also like