Sie sind auf Seite 1von 24

Bulk Collections

and Inserts in
Oracle 9i & 10g

Simay Alpöge

Next Information Systems, Inc.

April 14, 2004 Next Information Systems 1


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 2


Performance Gains
with Bulk Binding
Context Switching

SQL

PL/SQL Engine SQL Engine

Procedural statement SQL Statement


Executor Executor

DATA

April 14, 2004 Next Information Systems 3


Bulk Binding Categories
 With SELECT or FETCH statements
BULK COLLECT INTO

 In-Bind binding.
INSERT or UPDATE

 Out-Bind binding.
RETURNING clause
April 14, 2004 Next Information Systems 4
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 – 9.0.2.3 and above

Nested tables – 8i and above


April 14, 2004 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-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-JAN-2004’, ‘DD-MON-RRRR’) AND
TRUNC(SYSDATE);
BEGIN
OPEN c1;
FETCH c1 BULK COLLECT INTO Custs;
CLOSE c1;
END;

April 14, 2004 Next Information Systems 7


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-JAN-2004’ , ‘DD-MON-RRRR’) AND
TRUNC(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-Jan-2004’, ‘DD-MON-RRRR’) ANDTRUNC(SYSDATE);
TYPE 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
DECLARE
CURSOR c1
SELECT Customer_Account_Id, Effective_Date,Expired_Date
FROM Customer
WHERE Effective_Date BETWEEN TO_DATE(’01-Jan-2003’, ‘DD-MON-
RRRR’) And TO_DATE(’01-Jan-2004’, ‘DD-MON-RRRR’);
TYPE 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.

April 14, 2004 Next Information Systems 15


Out-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-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-Jan-2003’, ‘DD-MON-RRRR’) And
TO_DATE(’01-Jan-2004’, ‘DD-MON-RRRR’);

END;

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

Das könnte Ihnen auch gefallen