Upload
jacqueline-hardway
View
216
Download
0
Embed Size (px)
Citation preview
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 11
Bulk CollectionsBulk Collectionsand Inserts inand Inserts in
Oracle 9i & 10gOracle 9i & 10g
Simay AlpögeSimay Alpöge
Next Information Systems, Inc.Next Information Systems, Inc.
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 22
AGENDAAGENDA
PerformancePerformance gains with Bulk Bindinggains with Bulk Binding Array processing with BULK COLLECT and Array processing with BULK COLLECT and
FORALL FORALL Error handling.Error handling. Native Dynamic SQL with Bulk binding.Native Dynamic SQL with Bulk binding. Typical problems.Typical problems. Oracle 10g FORALL improvements.Oracle 10g FORALL improvements.
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 33
SQL
DATA
Context Switching
Performance GainsPerformance Gainswith Bulk Bindingwith Bulk Binding
PL/SQL Engine SQL Engine
SQL Statement Executor
Procedural statement Executor
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 44
Bulk Binding CategoriesBulk Binding Categories
With SELECT or FETCH statements With SELECT or FETCH statements BULK COLLECT INTOBULK COLLECT INTO
In-Bind binding. In-Bind binding. INSERT or UPDATEINSERT or UPDATE
Out-Bind binding. Out-Bind binding. RETURNING clauseRETURNING clause
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 55
SELECT / FETCH statementsSELECT / FETCH statements
Data may be Bulk Collected/Fetched into :Data may be Bulk Collected/Fetched into :
Table.column%TYPE – 8i and aboveTable.column%TYPE – 8i and above
Record of arrays – 8i and aboveRecord of arrays – 8i and above
Table%ROWTYPE – 9.0.2.3 and aboveTable%ROWTYPE – 9.0.2.3 and above
Cursor%ROWTYPE – 9.0.2.3 and aboveCursor%ROWTYPE – 9.0.2.3 and above
Array of records – 9.0.2.3 and aboveArray of records – 9.0.2.3 and above
Nested tables – 8i and aboveNested tables – 8i and above
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 66
SELECT statementSELECT statementTable.column%TYPETable.column%TYPE
DECLAREDECLARE
TYPE cust_tab IS TABLE OF customer.customer_account_idTYPE cust_tab IS TABLE OF customer.customer_account_id%TYPE%TYPEINDEX BY BINARY_INTEGER;INDEX BY BINARY_INTEGER;
Custs cust_tab;Custs cust_tab;BEGINBEGIN
SELECT customer_account_id SELECT customer_account_id BULK COLLECT INTO custsBULK COLLECT INTO custs
FROM customerFROM customerWHERE effective_date BETWEEN WHERE effective_date BETWEEN
TO_DATE(‘01-Jan-2004’,’DD-MON-RRRR’) AND TO_DATE(‘01-Jan-2004’,’DD-MON-RRRR’) AND TRUNC(SYSDATE); TRUNC(SYSDATE);
END;END;
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 77
FETCH statements FETCH statements Table.column%TYPETable.column%TYPE
DECLARE DECLARE TYPE CustList IS TABLE OF Customer.Customer_Account_Id%TYPETYPE CustList IS TABLE OF Customer.Customer_Account_Id%TYPEINDEX BY BINARY_INTEGER; INDEX BY BINARY_INTEGER;
Custs CustList; Custs CustList;
CURSOR c1 IS CURSOR c1 IS SELECT customer_account_id FROM Customer SELECT customer_account_id FROM Customer
WHERE effective_date BETWEEN WHERE effective_date BETWEEN TO_DATE(’01-JAN-2004’, ‘DD-MON-RRRR’) AND TO_DATE(’01-JAN-2004’, ‘DD-MON-RRRR’) AND
TRUNC(SYSDATE); TRUNC(SYSDATE);BEGIN BEGIN
OPEN c1; OPEN c1; FETCH c1 BULK COLLECT INTO Custs; FETCH c1 BULK COLLECT INTO Custs;
CLOSE c1; CLOSE c1; END; END;
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 88
DECLAREDECLARETYPE CustRec TYPE CustRec IS IS RECORDRECORD
(R_Customer_Account_id Customer.Customer_Account_id%TYPE,(R_Customer_Account_id Customer.Customer_Account_id%TYPE, R_Effective_date R_Effective_date Customer.Effective_Date%TYPE,Customer.Effective_Date%TYPE, R_Expired_date R_Expired_date Customer.Expired_Date%TYPE);Customer.Expired_Date%TYPE);v_Custrec CustRec;v_Custrec CustRec;v_Array_Size v_Array_Size NUMBER := 100;NUMBER := 100;
CURSOR c1 IS CURSOR c1 IS SELECT Customer_Account_Id, Effective_Date, Expired_Date SELECT Customer_Account_Id, Effective_Date, Expired_Date FROM Customer;FROM Customer;
BEGINBEGINOPEN c1;OPEN c1;
LOOPLOOPFETCH c1 BULK COLLECT INTO FETCH c1 BULK COLLECT INTO v_Custrec.R_Customer_account_id,v_Custrec.R_Effective_Date, v_Custrec.R_Customer_account_id,v_Custrec.R_Effective_Date, v_Custrec.R_Expired_Date v_Custrec.R_Expired_Date LIMIT LIMIT v_Array_Size; v_Array_Size;
END LOOP;END LOOP;CLOSE c1; END; CLOSE c1; END;
FETCH statement:FETCH statement:Record of Arrays Record of Arrays
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 99
SELECT statement SELECT statement Table%ROWTYPETable%ROWTYPE
DECLAREDECLARETYPE Cust_tab IS TABLE OF TYPE Cust_tab IS TABLE OF
Customers_Active%ROWTYPE;Customers_Active%ROWTYPE;Custs Cust_tab;Custs Cust_tab;
BEGINBEGINSELECT Customer_Account_Id, Effective_Date,SELECT Customer_Account_Id, Effective_Date,
Expired_DateExpired_Date BULK COLLECT INTO CustsBULK COLLECT INTO Custs
FROM Customers_ActiveFROM Customers_ActiveWHERE Effective_date BETWEEN WHERE Effective_date BETWEEN
TO_DATE(’01-JAN-2004’ , ‘DD-MON-RRRR’) TO_DATE(’01-JAN-2004’ , ‘DD-MON-RRRR’) AND TRUNC(SYSDATE);AND TRUNC(SYSDATE);
END;END;
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 1010
FETCH statementFETCH statementCURSOR%ROWTYPECURSOR%ROWTYPE
DECLAREDECLARECURSOR c1 CURSOR c1 ISISSELECT Customer_Account_Id, Effective_Date,Expired_DateSELECT Customer_Account_Id, Effective_Date,Expired_Date FROM CustomerFROM CustomerWHERE Effective_Date BETWEEN WHERE Effective_Date BETWEEN TO_DATE(’01-Jan-2004’, ‘DD-MON-RRRR’) ANDTRUNC(SYSDATE);TO_DATE(’01-Jan-2004’, ‘DD-MON-RRRR’) ANDTRUNC(SYSDATE);TYPE Cust_tab IS TABLE OF C1%ROWTYPE;TYPE Cust_tab IS TABLE OF C1%ROWTYPE;Custs Cust_tab;Custs Cust_tab;
BEGINBEGINOPEN c1;OPEN c1;
LOOPLOOPFETCHFETCH c1 BULK COLLECT INTO Custs LIMIT 100; c1 BULK COLLECT INTO Custs LIMIT 100;
EXIT WHEN c1%NOTFOUND;EXIT WHEN c1%NOTFOUND;END LOOP;END LOOP;
END ;END ;
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 1111
FETCH statement: FETCH statement: Array Of RecordsArray Of RecordsDECLAREDECLARETYPE CustRec IS RECORDTYPE CustRec IS RECORD(R_Customer_Account_id Customer.Customer_Account_id%TYPE,(R_Customer_Account_id Customer.Customer_Account_id%TYPE, R_Effective_Date R_Effective_Date Customer.Effective_Date%TYPE, Customer.Effective_Date%TYPE, R_Expired_Date R_Expired_Date Customer.Expired_Date%TYPE); Customer.Expired_Date%TYPE);
TYPE CustRecTab IS TABLE OF CustRec;TYPE CustRecTab IS TABLE OF CustRec;Cust_Recs Cust_Recs CustRecTab;CustRecTab;v_Array_Size v_Array_Size NUMBER := 100;NUMBER := 100;
CURSOR c1 IS CURSOR c1 IS SELECT Customer_Account_Id, Effective_Date, Expired_Date SELECT Customer_Account_Id, Effective_Date, Expired_Date FROM Customer;FROM Customer;
BEGINBEGINOPEN c1;OPEN c1;FETCH c1 BULK COLLECT INTO Cust_Recs LIMIT v_Array_Size;FETCH c1 BULK COLLECT INTO Cust_Recs LIMIT v_Array_Size;
CLOSE c1; CLOSE c1; END; END;
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 1212
FETCH statementFETCH statementNested TablesNested Tables
CREATE TYPE Coords AS OBJECT (x NUMBER, y NUMBER); CREATE TYPE Coords AS OBJECT (x NUMBER, y NUMBER);
CREATE TABLE grid (num NUMBER, loc Coords); CREATE TABLE grid (num NUMBER, loc Coords);
INSERT INTO grid VALUES(10, Coords(1,2)); INSERT INTO grid VALUES(10, Coords(1,2)); INSERT INTO grid VALUES(20, Coords(3,4)); INSERT INTO grid VALUES(20, Coords(3,4));
DECLARE DECLARE TYPE CoordsTab IS TABLE OF Coords; TYPE CoordsTab IS TABLE OF Coords; pairs CoordsTab; pairs CoordsTab;
BEGIN BEGIN SELECT loc BULK COLLECT INTO pairs FROM grid; -- now pairs contains SELECT loc BULK COLLECT INTO pairs FROM grid; -- now pairs contains (1,2) and (3,4) (1,2) and (3,4)
END; END;
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 1313
In-Bind BindingIn-Bind BindingDECLAREDECLARECURSOR c1CURSOR c1SELECT Customer_Account_Id, Effective_Date,Expired_DateSELECT Customer_Account_Id, Effective_Date,Expired_Date FROM CustomerFROM CustomerWHERE Effective_Date BETWEEN TO_DATE(’01-Jan-2003’, ‘DD-MON-WHERE Effective_Date BETWEEN TO_DATE(’01-Jan-2003’, ‘DD-MON-
RRRR’) And TO_DATE(’01-Jan-2004’, ‘DD-MON-RRRR’);RRRR’) And TO_DATE(’01-Jan-2004’, ‘DD-MON-RRRR’);TYPE Cust_tab IS TABLE OF C1%ROWTYPE;TYPE Cust_tab IS TABLE OF C1%ROWTYPE;Custs Cust_tab;Custs Cust_tab;
BEGINBEGINOPEN c1;OPEN c1;
LOOPLOOPFETCH c1 BULK COLLECT INTO Custs LIMIT 100;FETCH c1 BULK COLLECT INTO Custs LIMIT 100;
END LOOP;END LOOP;FORALLFORALL i IN 1 .. Custs.COUNT i IN 1 .. Custs.COUNTSAVE EXCEPTIONSSAVE EXCEPTIONSINSERT into Customer_History VALUES Custs (i);INSERT into Customer_History VALUES Custs (i);……..
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 1414
FORALL Error HandlingFORALL Error Handling
No more FULL rollback in case of an EXCEPTIONNo more FULL rollback in case of an EXCEPTION
SAVE EXCEPTIONSSAVE EXCEPTIONS
SQL%BULK_EXCEPTIONS – Collection of recordsSQL%BULK_EXCEPTIONS – Collection of records
SQL%BULK_EXCEPTIONS(i).ERROR_INDEXSQL%BULK_EXCEPTIONS(i).ERROR_INDEX –– stores stores itireration when exception is raised.itireration when exception is raised.
SQL%BULK_EXCEPTIONS(i).ERROR_CODE - stores Oracle SQL%BULK_EXCEPTIONS(i).ERROR_CODE - stores Oracle error code.error code.
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 1515
Typical ProblemsTypical ProblemsFORALL limitationsFORALL limitations
SINGLE DML (INSERT, UPDATE, DELETE) statement is allowed.SINGLE DML (INSERT, UPDATE, DELETE) statement is allowed.
No IF condition within FORALL. No IF condition within FORALL.
For multi table INSERT/UPDATE use WHEN clause instead of IF For multi table INSERT/UPDATE use WHEN clause instead of IF condition.condition.
No DBMS_OUTPUT or other OUTPUT statements within FORALL.No DBMS_OUTPUT or other OUTPUT statements within FORALL.
No SELECT .. BULK COLLECT within FORALL statement.No SELECT .. BULK COLLECT within FORALL statement.
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 1616
Out-Bind bindingOut-Bind binding
DECLAREDECLARETYPE AcctTab IS TABLE OF Acct_Install.Customer_Account_id%TYPE; TYPE AcctTab IS TABLE OF Acct_Install.Customer_Account_id%TYPE; Acusts AcctTab; Acusts AcctTab;
BEGIN BEGIN DELETE FROM Acct_InstallDELETE FROM Acct_InstallWHERE INSTALL_DATE =WHERE INSTALL_DATE =TRUNC(TO_DATE(’01-jan-1970’,’DD-MON-RRRR’) TRUNC(TO_DATE(’01-jan-1970’,’DD-MON-RRRR’) RETURNING Customer_Account_Id RETURNING Customer_Account_Id BULK COLLECT INTO Acusts; BULK COLLECT INTO Acusts;
END; END;
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 1717
NATIVE Dynamic SQLNATIVE Dynamic SQL
• EXECUTE IMMEDIATEEXECUTE IMMEDIATE
• FORALLFORALL
• RETURNING INTORETURNING INTO
• USING USING
• COLLECT INTOCOLLECT INTO
• %BULK_ROWCOUNT - cursor attribute shows %BULK_ROWCOUNT - cursor attribute shows total cumulative execution. total cumulative execution.
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 1818
NATIVE Dynamic SQLNATIVE Dynamic SQL
DECLARE DECLARE
TYPE CustList IS TABLE OF NUMBER; TYPE CustList IS TABLE OF NUMBER;
TYPE NameList IS TABLE OF VARCHAR2(15); TYPE NameList IS TABLE OF VARCHAR2(15);
Custnos CustList; Custnos CustList; Custnames NameList; Custnames NameList;
BEGIN Custnos := CustList(1,2,3,4,5); BEGIN Custnos := CustList(1,2,3,4,5); FORALL i IN 1..5 FORALL i IN 1..5 EXECUTE IMMEDIATE 'UPDATE Customer SET Cust_Name = EXECUTE IMMEDIATE 'UPDATE Customer SET Cust_Name =
TRIM(Cust_name) WHERE Custno = :1 TRIM(Cust_name) WHERE Custno = :1 RETURNING Cust_Name INTO :2' RETURNING Cust_Name INTO :2' USING Custnos(i) USING Custnos(i) RETURNING BULK COLLECT INTO Custnames; ...RETURNING BULK COLLECT INTO Custnames; ...END; END;
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 1919
Oracle 10g FORALLOracle 10g FORALL
Indices ofIndices of –– When binding area contains When binding area contains gaps gaps
Values ofValues of – – Subset of element Subset of element selection in the array selection in the array
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 2020
Oracle 10g FORALLOracle 10g FORALL VALUES OF VALUES OF
DECLAREDECLARETYPE CUST_IDS IS TABLE OF CUSTOMER.CUSTOMER_ID%TYPE;TYPE CUST_IDS IS TABLE OF CUSTOMER.CUSTOMER_ID%TYPE;TYPE PHONE_NOS IS TABLE OF CUSTOMER.PHONE_NBRTYPE PHONE_NOS IS TABLE OF CUSTOMER.PHONE_NBR
%TYPE; %TYPE; TYPE EDATES IS TABLE OF CUSTOMER.EFF_DATE%TYPE;TYPE EDATES IS TABLE OF CUSTOMER.EFF_DATE%TYPE;TYPE EXPDATES IS TABLE OF CUSTOMER.EXPIRED_DATETYPE EXPDATES IS TABLE OF CUSTOMER.EXPIRED_DATE
%TYPE;%TYPE;
TYPE A_INDX IS TABLE OF PLS_INTEGERTYPE A_INDX IS TABLE OF PLS_INTEGERINDEX BY PLS_INTEGER;INDEX BY PLS_INTEGER;
EXPIRED_CUSTS A_INDX;EXPIRED_CUSTS A_INDX;ACTIVE_CUSTS A_INDX;ACTIVE_CUSTS A_INDX;
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 2121
Oracle 10g FORALLOracle 10g FORALL VALUES OF (Continue) VALUES OF (Continue)
CUSTID CUST_ID;CUSTID CUST_ID;PHONES PHONE_NOS;PHONES PHONE_NOS;EFFDTS EDATES;EFFDTS EDATES;EXPDTS EXPDATES;EXPDTS EXPDATES;
V_IV_I BINARY_INTEGERBINARY_INTEGER
BEGINBEGIN
SELECT CUSTOMER_ID, PHONE_NBR, EFF_DATE, EXPIRED_DATESELECT CUSTOMER_ID, PHONE_NBR, EFF_DATE, EXPIRED_DATEBULK COLLECT INTO CUSTIDS, PHONES, EFFDTS, EXPDTS; BULK COLLECT INTO CUSTIDS, PHONES, EFFDTS, EXPDTS; FROM CUSTOMERFROM CUSTOMERWHERE Effective_Date BETWEEN WHERE Effective_Date BETWEEN TO_DATE(’01-Jan-2003’, ‘DD-MON-RRRR’) And TO_DATE(’01-Jan-2003’, ‘DD-MON-RRRR’) And TO_DATE(’01-Jan-2004’, ‘DD-MON-RRRR’);TO_DATE(’01-Jan-2004’, ‘DD-MON-RRRR’);
END;END;
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 2222
Oracle 10g FORALLOracle 10g FORALL VALUES OF (Continue) VALUES OF (Continue)
FOR v_i IN CUSTIDS.FIRST .. CUSTIDS.LASTFOR v_i IN CUSTIDS.FIRST .. CUSTIDS.LASTLOOPLOOPIF FN_EXPIRED THEN IF FN_EXPIRED THEN EXPIRED_CUSTS (V_I) := v_i;EXPIRED_CUSTS (V_I) := v_i;ELSEELSEACTIVE_CUSTS(V_I) := v_i;ACTIVE_CUSTS(V_I) := v_i;END IF;END IF;END LOOP;END LOOP;
BEGINBEGINFORALL V_ I FORALL V_ I VALUES VALUES OFOF EXPIRED_CUSTS EXPIRED_CUSTSSAVE EXCEPTIONSSAVE EXCEPTIONSINSERT INTO CUSTOMER_HISTORY INSERT INTO CUSTOMER_HISTORY VALUES VALUES (CUSTIDS (V_I), PHONES(V_I), EFFDTS(V_I), EXPDTS(V_);(CUSTIDS (V_I), PHONES(V_I), EFFDTS(V_I), EXPDTS(V_);FORALL V_ I FORALL V_ I VALUES VALUES OFOF ACTIVE_CUSTS ACTIVE_CUSTSSAVE EXCEPTIONSSAVE EXCEPTIONSINSERT INTO CUSTOMER_ACTIVE INSERT INTO CUSTOMER_ACTIVE VALUES VALUES (CUSTIDS (V_I), PHONES(V_I), EFFDTS(V_I), EXPDTS(V_);(CUSTIDS (V_I), PHONES(V_I), EFFDTS(V_I), EXPDTS(V_);COMMIT;COMMIT;
END;END;
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 2323
QuestionsQuestions
April 14, 2004April 14, 2004 Next Information SystemsNext Information Systems 2424
THANK YOUTHANK YOU
[email protected]@nyoug.org
[email protected]@nextinfosys.com