SlideShare une entreprise Scribd logo
1  sur  113
SAGE Computing Services
Customised Oracle Training Workshops and Consulting
BulkBinds
Be A Bulk Binding Baron
Sco tt We sle y
Syste m s Co nsultant
& Traine r
who_am_i;
http://strategy2c.wordpress.com/2009/01/10/strategy-for-goldfish-funny-illustration-by-frits/
bulk binds
been around since 8i
not used often enough
binding is the assignment of values to
placeholders in SQL statements
my_column = :my_value
Bulk Binding is binding an array of values
my_column = my_array(i)
in-bind
my_variable
insert
update
merge
out-bind
my_variable
returning
define
my_variable
fetch
select
multiset
A quick word on Collections
lists or sets of information
invaluable
can be faster than SQL
cache frequent access in PGA
my_module (pt_array IN OUT NOCOPY t_array)
types of collections
• Associative Arrays (aka index-by tables)
– Only PL/SQL
– Sparse
– Can have negative indexes
– Similar to hash table concept
– Different datatypes for indexes
– TYPE type _ nam e IS TABLE OF e le m e nt_ type [NOT NULL]
INDEX BY [PLS_INTEGER | BINARY_INTEGER |
VARCHAR2(siz e _ lim it)];
TYPE emp_tab IS TABLE OF employees
%ROWTYPE
INDEX BY PLS_INTEGER;
• Nested Tables
– Can use in SQL
– Unbounded
– Good for set operations
– TYPE type _ nam e IS TABLE OF e le m e nt_ type [NOT NULL];
TYPE top_emp IS TABLE OF
employees.employee_id%TYPE;
CREATE TYPE galaxy AS TABLE OF
star_object;
• VARRAY
– Specify maximums
– Dense
– Can use in SQL
– Most similar to 3GL array
– TYPE type _ nam e IS {VARRAY | VARYING ARRAY} (siz e _ lim it)
OF e le m e nt_ type [NOT NULL];
TYPE Calendar IS VARRAY(366) OF DATE;
CREATE TYPE rainbow AS VARRAY(7) OF VARCHAR2(64);
CREATE TYPE solar_system AS VARRAY(8) OF
planet_object;
back to the business of binds
from the 8.1.7 documentation
Conventional Bind
Performance penalty for many context switches
Oracle Server
PL/SQL Runtime Engine
PL/SQL block
Procedural
statement
executor
SQL Engine
SQL statement
executorFOR r_emp IN c_emp LOOP
UPDATE emp
SET sal = sal * 1.1
WHERE empno = r_emp.empno;
END LOOP;
Bulk Bind
Much less overhead
Oracle Server
PL/SQL Runtime Engine
PL/SQL block
Procedural
statement
executor
SQL Engine
SQL statement
executorFORALL i IN INDICES OF t_emp
UPDATE emp
SET sal = sal * 1.1
WHERE empno = t_emp(i);
when would you use it?
plsql_optimize_level = 42
lifesgoldenrule.com
no bulk bind – do it in SQL
“If the DML statement affects four or
more database rows, the use of bulk SQL
can improve performance considerably”
- Oracle Documentation
SELECT everyone
BULK COLLECT
INTO my_array
FROM the_worlds_idiots;
SELECT everyone
BULK COLLECT
INTO my_array LIMIT 100
FROM the_worlds_idiots;
reoccurring SQL within PL/SQL loop
multiple operations on dataset – BULK COLLECT
http://www.sharenator.com/Before_After/stinejensen_530-65109.html
11g compound triggers – auditing
finally some coding examples?
DML Bind Example
-- Slower method, running the UPDATE
-- statements within a regular loop
FOR i IN t_emp.FIRST..t_emp.LAST LOOP
UPDATE emp_largish
SET sal = sal * 1.1
WHERE empno = t_emp(i);
END LOOP;
1.94 seconds
-- Efficient method, using a bulk bind on a VARRAY
FORALL i IN t_emp.FIRST..t_emp.LAST
UPDATE emp_largish
SET sal = sal * 1.1
WHERE empno = t_emp(i);
1.40 seconds
Collect Example
-- Slower method, assigning each
-- collection element within a loop.
v_index := 0;
FOR r_emp IN c_emp LOOP
v_index := v_index + 1;
t_emp(v_index).empno := r_emp.empno;
t_emp(v_index).ename := r_emp.ename;
END LOOP;
0.19 seconds
-- Efficient method, using a bulk bind
OPEN c_emp;
FETCH c_emp BULK COLLECT INTO t_emp;
CLOSE c_emp;
0.09 seconds
Example of Combination
-- Slower method, running update
-- statement within regular loop,
-- returning individual elements
FOR i IN t_emp.FIRST..t_emp.LAST LOOP
UPDATE emp_largish
SET sal = sal * 1.1
WHERE empno = t_emp(i)
RETURNING sal
INTO t_sal(i);
END LOOP;
0.75 seconds
-- Efficient method, using a bulk bind
-- and bulk collect
FORALL i IN t_emp.FIRST..t_emp.LAST
UPDATE emp_largish
SET sal = sal * 1.1
WHERE empno = t_emp(i)
RETURNING sal BULK COLLECT
INTO t_sal;
0.29 seconds
when wouldn’t you use it
lifesgoldenrule.com
can you just do it in SQL?
when you only need one iteration
just filter records with
where/intersect/minus
when you haven't tested it
with & without
>= 10g may silently do it for you
too much data?
what if I have a sparse collection?
Uh oh…
DECLARE
TYPE emp_tab IS TABLE OF emp.empno%TYPE INDEX BY PLS_INTEGER;
t_emp emp_tab;
CURSOR c_emp IS
SELECT empno FROM emp;
BEGIN
OPEN c_emp;
FETCH c_emp BULK COLLECT INTO t_emp;
CLOSE c_emp;
-- ...do a bunch of processing, including
-- something like:
t_emp.DELETE(3);
FORALL i IN t_emp.FIRST..t_emp.LAST
UPDATE emp
SET sal = sal * 1.1
WHERE empno = t_emp(i);
END;
/
ORA-22160: element at index [3] does not exist
ORA-06512: at line 15
processing spare collections
introduced in 10g
INDICES OF
allows iteration of all index values,
not just from lower to upper bound
(tab.FIRST..tab.LAST)
VALUES OF
Create PL/SQL table effectively
indexing your collection
- process specific elements
- process in particular order
- process an element more than once
simple
FORALL i IN t_emp.FIRST..t_emp.LAST
UPDATE emp
SET sal = sal * 1.1
WHERE empno = t_emp(i);
FIRST
LAST
Updated all rows
In order of array listing
simple
FORALL i IN t_emp.FIRST..t_emp.LAST
UPDATE emp
SET sal = sal * 1.1
WHERE empno = t_emp(i);
FIRST
LAST
ORA-22160: element at index [3] does not exist
clever
FORALL i IN INDICES OF t_emp
UPDATE emp
SET comm = comm * 1.5
WHERE empno = t_emp(i);
7890
7988
7752
7521
7900
Updated rows within array
In order of array listing
t_emp(3) := 7890
t_emp(5) := 7988
t_emp(6) := 7752
t_emp(8) := 7521
t_emp(9) := 7900
advanced
7890
7988
7752
t_index(-2):= 6
t_index( 0):= 3
t_index( 3):= 5
t_index(10):= 6
t_emp(9) := 7900
t_emp(8) := 7521
t_emp(6) := 7752
t_emp(5) := 7988
t_emp(3) := 7890
FORALL i IN VALUES OF t_index
UPDATE emp
SET comm = comm * 1.5
WHERE empno = t_emp(i);
DECLARE
TYPE emp_tab IS TABLE OF emp.empno%TYPE INDEX BY PLS_INTEGER;
TYPE numlist IS TABLE OF PLS_INTEGER INDEX BY BINARY_INTEGER;
t_emp emp_tab;
t_indexes numlist;
BEGIN
t_emp(3) := 7890;
t_emp(5) := 7988;
t_emp(6) := 7752;
t_emp(8) := 7521;
t_emp(9) := 7900;
t_indexes(-2) := 6;
t_indexes(0) := 3;
t_indexes(3) := 5;
t_indexes(10) := 6;
what if I have 9i?
CREATE OR REPLACE PACKAGE BODY sw_bulk_insert IS
PROCEDURE sw_insert (sw_tab IN t_sw_tab) IS
BEGIN
$IF dbms_db_version.ver_le_9 $THEN
DECLARE
l_dense t_sw_tab;
ln_index PLS_INTEGER := sw_tab.FIRST;
BEGIN
<< dense_loop >>
WHILE (l_index IS NOT NULL) LOOP
l_dense(l_dense.COUNT + 1) := sw_tab(l_index);
l_index := sw_tab.NEXT(l_index);
END LOOP dense_loop;
FORALL i IN 1..l_dense.COUNT
INSERT INTO sw_table VALUES l_dense(i);
END;
$ELSE
FORALL i IN INDICES OF sw_tab
INSERT INTO sw_table
VALUES sw_tab(i);
$END
END sw_insert;
END sw_bulk_insert;
DECLARE
t_emp t_emp_obj;
BEGIN
SELECT emp_obj(empno, ename, job, mgr, hiredate, sal,
comm, deptno)
BULK COLLECT INTO t_emp
FROM emp;
-- Remove those with commission to create sparse
collection
FOR i IN 1..t_emp.COUNT LOOP
IF t_emp(i).comm IS NOT NULL THEN
t_emp.DELETE(i);
END IF;
END LOOP;
-- No need for FORALL
INSERT INTO emp2
SELECT * FROM TABLE(CAST(t_emp AS t_emp_obj));
END;
/
CREATE TABLE emp2 AS SELECT * FROM emp WHERE 1=0;
CREATE OR REPLACE TYPE emp_obj AS OBJECT
(empno NUMBER(4)
,ename VARCHAR2(10)
,job VARCHAR2(9)
,mgr NUMBER(4)
,hiredate DATE
,sal NUMBER(7,2)
,comm NUMBER(7,2)
,deptno NUMBER(2))
/
CREATE OR REPLACE TYPE t_emp_obj AS TABLE OF emp_obj
/
can I do this "bunch of processing" in bulk, outside the db?
DECLAREDECLARE
TYPE emp_tab IS TABLE OF emp.empno%TYPE INDEX BY PLS_INTEGER;TYPE emp_tab IS TABLE OF emp.empno%TYPE INDEX BY PLS_INTEGER;
t_emp emp_tab;t_emp emp_tab;
CURSOR c_emp ISCURSOR c_emp IS
SELECT empno FROM emp;SELECT empno FROM emp;
BEGINBEGIN
OPEN c_emp;OPEN c_emp;
FETCH c_emp BULK COLLECT INTO t_emp;FETCH c_emp BULK COLLECT INTO t_emp;
CLOSE c_emp;CLOSE c_emp;
-- ...do a bunch of processing, including
-- something like:
t_emp.DELETE(3);
FORALL i IN t_emp.FIRST..t_emp.LASTFORALL i IN t_emp.FIRST..t_emp.LAST
UPDATE empUPDATE emp
SET sal = sal * 1.1SET sal = sal * 1.1
WHERE empno = t_emp(i);WHERE empno = t_emp(i);
END;END;
//
-- ... Or just those employees that exist in another collection
-- t_emp intersect with t_emp_leaders;
MULTISET operations
nested tables ONLY
DECLARE
TYPE colours IS TABLE OF VARCHAR2(64);
comp1 colours;
comp2 colours;
result colours;
PROCEDURE show_table (p_table IN colours) IS
BEGIN
FOR i IN p_table.FIRST..p_table.LAST LOOP
DBMS_OUTPUT.PUT (p_table(i)||' ');
END LOOP;
DBMS_OUTPUT.NEW_LINE;
END;
BEGIN
comp1 := colours('Black','White','Red','Red');
comp2 := colours('Black','Red','Yellow');
result := comp1 MULTISET UNION comp2;
dbms_output.put_line ('multiset union is ');
show_table(result);
END;
/
multiset union is
Black White Red Red Black Red Yellow
...
BEGIN
comp1 := colours('Black','White','Red','Red');
comp2 := colours('Black','Red','Yellow');
result := comp1 MULTISET UNION DISTINCT comp2;
dbms_output.put_line ('multiset union distinct is ');
show_table(result);
END;
/
multiset union distinct is
Black White Red Yellow
...
BEGIN
comp1 := colours('Black','White','Red','Red');
comp2 := colours('Black','Red','Yellow');
result := comp1 MULTISET INTERSECT DISTINCT comp2;
dbms_output.put_line ('multiset intersect distinct is ');
show_table(result);
END;
/
multiset intersect distinct is
Black Red
...
BEGIN
comp1 := colours('Black','White','Red','Red');
comp2 := colours('Black','Red','Yellow');
result := comp1 MULTISET EXCEPT DISTINCT comp2;
dbms_output.put_line ('multiset except distinct is ');
show_table(result);
END;
/
multiset except distinct is
White
...
BEGIN
comp1 := colours('Black','White','Red','Red');
comp1 := comp1 MULTISET UNION DISTINCT comp1;
dbms_output.put_line (‘self multiset intersect distinct is ');
show_table(comp1);
END;
/
self multiset union distinct is
Black White Red
DECLARE
TYPE colours IS TABLE OF VARCHAR2(64);
t_colours colours := colours('Black','White','Red','Red');
PROCEDURE show_table (p_table IN colours)
...
BEGIN
DBMS_OUTPUT.PUT_LINE('Count:'||CARDINALITY(t_colours));
DBMS_OUTPUT.PUT_LINE('Distinct:'||CARDINALITY(SET(t_colours)));
IF t_colours IS NOT A SET THEN
t_colours := SET(t_colours);
show_table(t_colours);
END IF;
END;
/
Count:4
Distinct:3
Black White Red
but wait, there's still more...
Equality
DECLARE
TYPE colours IS TABLE OF VARCHAR2 (64);
group1 colours := colours ('Black', 'White');
group2 colours := colours ('White', 'Black');
group3 colours := colours ('White', 'Red');
BEGIN
IF group1 = group2 THEN
DBMS_OUTPUT.PUT_LINE ('Group 1 = Group 2');
ELSE
DBMS_OUTPUT.PUT_LINE ('Group 1 != Group 2');
END IF;
IF group2 != group3 THEN
DBMS_OUTPUT.PUT_LINE ('Group 2 != Group 3');
ELSE
DBMS_OUTPUT.PUT_LINE ('Group 2 = Group 3');
END IF;
END;
/
DECLARE
TYPE colours IS TABLE OF VARCHAR2(64);
t_colours colours := colours('Black','White','Red','Red');
v_colour VARCHAR2(64) := 'Black';
BEGIN
IF v_colour MEMBER OF t_colours THEN
DBMS_OUTPUT.PUT_LINE('Exists');
ELSE
DBMS_OUTPUT.PUT_LINE(‘Absent');
END IF;
END;
/
Exists
Membership
DECLARE
TYPE colours IS TABLE OF VARCHAR2(64);
t_colours colours := colours('Black','White','Red','Yellow');
t_colours2 colours := colours('Black','Red');
t_colours3 colours := colours('Black','Blue');
BEGIN
IF t_colours2 SUBMULTISET OF t_colours THEN
DBMS_OUTPUT.PUT_LINE('2 Subset');
ELSE
DBMS_OUTPUT.PUT_LINE('2 Separate');
END IF;
IF t_colours3 SUBMULTISET OF t_colours THEN
DBMS_OUTPUT.PUT_LINE('3 Subset');
ELSE
DBMS_OUTPUT.PUT_LINE('3 Separate');
END IF;
END;
/
2 Subset
3 Separate
Subset
DECLARE
TYPE t_c IS TABLE OF VARCHAR2(32767) INDEX BY
PLS_INTEGER;
l_c t_c;
BEGIN
SELECT LPAD('x',32767,'x') bb
BULK COLLECT
INTO l_c
FROM DUAL
CONNECT BY LEVEL <=1000000;
END;
/
declare
*
ERROR at line 1:
ORA-04030: out of process memory when trying to allocate
16396 bytes (koh-kghu call ,pl/sql vc2)
ORA-06512: at line 5
Elapsed: 00:00:02.70
Boom!
limiting data
prevent collections from expanding with no limit
SELECT sal BULK COLLECT
INTO t_emp
FROM emp
WHERE ROWNUM <= 10;
WHERE ROWNUM BETWEEN 11 AND 20 – Won’t work
FROM emp SAMPLE(10) -- “Random”
-- Performance hit:
SELECT * FROM (
SELECT ROW_NUMBER() OVER (ORDER BY empno)
AS from_to_rank
…)
WHERE from_to_rank BETWEEN 1 AND 10
LIMIT clause
DECLARE
v_rows PLS_INTEGER := 10;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp BULK COLLECT INTO t_emp LIMIT v_rows;
EXIT WHEN t_emp.COUNT = 0;
null; -- (Process information)
END LOOP;
CLOSE c_emp;
take care with the exit condition
OPEN c_emp;
LOOP
FETCH c_emp BULK COLLECT INTO t_emp LIMIT v_rows;
EXIT WHEN t_emp.COUNT = 0; -- Here?
null; -- (Process information)
EXIT WHEN c_emp%NOTFOUND; -- or here?
END LOOP;
CLOSE c_emp;
EXCEPTION WHEN NO_DATA_FOUND
-- Does this get raised?
t_emp.COUNT = 0
** Count:10
CLARK
JAMES
MARTIN
MILLER
WARD
KING
ALLEN
ADAMS
SMITH
JONES
** Count:4
TURNER
BLAKE
SCOTT
FORD
** Count:0
PL/SQL procedure successfully completed.
LOOP
FETCH c_emp BULK COLLECT INTO t_emp LIMIT 10;
dbms_output.put_line('** Count:'||t_emp.COUNT);
EXIT WHEN t_emp.COUNT = 0;
dbms_output.put_line(t_emp(i).ename);
-- EXIT WHEN c_emp%NOTFOUND;
WHEN c_emp%NOTFOUND
** Count:10
CLARK
JAMES
MARTIN
MILLER
WARD
KING
ALLEN
ADAMS
SMITH
JONES
** Count:4
TURNER
BLAKE
SCOTT
FORD
PL/SQL procedure successfully completed.
LOOP
FETCH c_emp BULK COLLECT INTO t_emp LIMIT 10;
dbms_output.put_line('** Count:'||t_emp.COUNT);
-- EXIT WHEN t_emp.COUNT = 0;
dbms_output.put_line(t_emp(i).ename);
EXIT WHEN c_emp%NOTFOUND;
implicit cursors don’t bulk up
DECLARE
TYPE emp_tab IS TABLE OF emp.empno%TYPE INDEX BY
PLS_INTEGER;
t_emp emp_tab;
BEGIN
SELECT empno
BULK COLLECT INTO t_emp
FROM emp
LIMIT 10;
END;
/
LIMIT 10
*
ERROR at line 8:
ORA-06550: line 8, column 9:
PL/SQL: ORA-00933: SQL command not properly ended
ORA-06550: line 5, column 3:
PL/SQL: SQL Statement ignored
and if I have no data?
NO_DATA_FOUND
DECLARE
v_sal emp.sal%TYPE;
BEGIN
SELECT sal
INTO v_sal
FROM emp
WHERE 1=0;
END;
/
DECLARE
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 4
DECLARE
TYPE emp_tab IS TABLE OF emp.sal%TYPE
INDEX BY PLS_INTEGER;
t_emp emp_tab;
BEGIN
SELECT sal BULK COLLECT
INTO t_emp
FROM emp
WHERE 1=0;
END;
/
PL/SQL procedure successfully completed.
bulk attributes
Bulk Cursor Attributes
DECLARE
TYPE dept_list IS TABLE OF NUMBER;
t_dept dept_list := dept_list(10, 20, 30);
BEGIN
FORALL i IN t_dept.FIRST..t_dept.LAST
DELETE FROM emp WHERE deptno = t_dept(i);
-- Each indice may update multiple rows
dbms_output.put_line('Total rows affected: '||SQL%ROWCOUNT);
-- How many rows were affected by each delete statement?
FOR j IN t_dept.FIRST..t_dept.LAST LOOP
dbms_output.put_line('Dept '||t_dept(j)||
'rows:'||SQL%BULK_ROWCOUNT(j));
END LOOP;
END;
/
Total rows affected: 14
Dept 10 rows:3
Dept 20 rows:5
Dept 30 rows:6
PL/SQL procedure successfully completed.
what if we have exceptions for a particular row?
CREATE TABLE emp2 AS SELECT * FROM emp;
ALTER TABLE emp2 ADD CONSTRAINT be_test CHECK (sal = ROUND(sal));DECLARE
TYPE emp_list IS TABLE OF NUMBER;
t_emp emp_list := emp_list(7934, 7782, 7839, 7788, 7900);
e_dml_errors EXCEPTION;
PRAGMA exception_init(e_dml_errors, -24381);
BEGIN
FORALL i IN t_emp.FIRST..t_emp.LAST SAVE EXCEPTIONS
-- Will raise exception for sal of 1250 but not 1300
UPDATE emp2
SET sal = sal/100
WHERE empno = t_emp(i);
dbms_output.put_line('Total rows affected: ‘
||SQL%ROWCOUNT);
EXCEPTION
WHEN e_dml_errors THEN -- Now we figure out what failed and why.
dbms_output.put_line('Total failed updates: '||SQL%BULK_EXCEPTIONS.COUNT);
FOR j IN 1..SQL%BULK_EXCEPTIONS.COUNT LOOP
dbms_output.put_line('Error '||j||' for indice ‘
||SQL%BULK_EXCEPTIONS(j).ERROR_INDEX);
dbms_output.put_line('Error message is ‘
||SQLERRM(-SQL%BULK_EXCEPTIONS(j).ERROR_CODE));
END LOOP;
END; Total failed updates: 2
Error 1 for indice 2
Error message is ORA-02290: check constraint (.) violated
Error 2 for indice 5
Error message is ORA-02290: check constraint (.) violated
PL/SQL procedure successfully completed.
Bulk Exceptions
select empno, ename, sal from emp2 where
empno in (7934, 7782, 7839, 7788, 7900);
EMPNO ENAME SAL
---------- ---------- ----------
7934 MILLER 13
7782 CLARK 2450
7839 KING 50
7788 SCOTT 30
7900 JAMES 950
5 rows selected.
41%
33%
10%
9%
7%
FOR
CURSOR
COLLECT
LIMIT100
IISS
0%
10%
20%
30%
40%
50%
60%
70%
80%
90%
100%
10g 11g
Indices1000
Indices100
Limit1000
Limit100
0
50
100
150
200
250
300
9i 10g 11g
Limit 100
Limit 1000
0%
20%
40%
60%
80%
100%
9i
10g
11g
IISS
Limit100
Collect
Cursor
For
FOR CURSOR COLLECT LIMIT100 IISS
Enterprise Manager
Limit 100 vs 1000 Separate runs of
For | Cursor | Collect | Limit | IISS
What’s new?
• 8i
– Bulk operations!
– Collections indexed by BINARY_INTEGER only
• 9i
– Bulk collect via dynamically opened ref cursor
• 9i Release 2
– Bulk collect into collection of records
– Index by VARCHAR2 & BINARY_INTEGER (or their subtypes)
• 10g
– PL/SQL engine may decide to peform array fetching for you
– INDICES OF/VALUES OF introduced
– MULTISET operations
• 11g
– table(bulk_index).field is now supported at run-time
– DBMS_SQL allows bulk binds using user-define collection types
CREATE TABLE emp2 AS SELECT empno,ename,sal, SYSTIMESTAMP ts
FROM emp WHERE 1=0;
DECLARE
CURSOR sw IS SELECT empno, ename, sal FROM emp;
TYPE t_sw IS TABLE OF sw%ROWTYPE;
lt_sw t_sw;
BEGIN
OPEN sw;
FETCH sw BULK COLLECT INTO lt_sw;
CLOSE sw;
FORALL i IN lt_sw.FIRST..lt_sw.LAST
INSERT INTO emp2
VALUES (lt_sw(i).empno
,lt_sw(i).ename
,lt_sw(i).sal
,SYSTIMESTAMP);
END;
/
values (lt_sw(i).empno
*
ERROR at line 11:
ORA-06550: line 11, column 9:
PLS-00436: implementation restriction: cannot reference fields of
BULK In-BIND table of records
some final words
Read
appropriate
documentation
READ THIS… TWICE!
• Tom Kyte
– In search of the truth - Or Correlation is not Causation
– http://asktom.oracle.com/pls/ask/download_file?p_file=3067171813508
– “If any pape r yo u re ad te lls yo u what but no t why, re g ardle ss o f
its tim e stam p, Isug g e st yo u take its advice with a big g rain o f
salt as it m ay be applicable onlyto onlyspecific cases andnot
applicabletoyouat all. In fact, it co uld be so m e thing that was
true in the past and no t true anym o re . If theygiveyouno wayto
findout, ignoreit. ”
things change
it only takes one case to show something is...
not universally true
Rules of thumb without evidence, without ways to test them before
implementing them, are dangerous, seriously dangerous
“Because a rule of thumb is a principle with
broad application not intended to be strictly
accurate or reliable for all situations”
SAGE Computing Services
Customised Oracle Training Workshops and Consulting
Questions and Answers?
Presentations are available from our website:
http: //www. sag e co m puting . co m . au
e nq uirie s@ sag e co m puting . co m . au
sco tt. we sle y@ sag e co m puting . co m . au
http: //triang le -circle -sq uare . blo g spo t. co m

Contenu connexe

Tendances

Oracle - Program with PL/SQL - Lession 03
Oracle - Program with PL/SQL - Lession 03Oracle - Program with PL/SQL - Lession 03
Oracle - Program with PL/SQL - Lession 03Thuan Nguyen
 
Oracle - Program with PL/SQL - Lession 07
Oracle - Program with PL/SQL - Lession 07Oracle - Program with PL/SQL - Lession 07
Oracle - Program with PL/SQL - Lession 07Thuan Nguyen
 
Procedure and Functions in pl/sql
Procedure and Functions in pl/sqlProcedure and Functions in pl/sql
Procedure and Functions in pl/sqlÑirmal Tatiwal
 
Oracle SQL, PL/SQL best practices
Oracle SQL, PL/SQL best practicesOracle SQL, PL/SQL best practices
Oracle SQL, PL/SQL best practicesSmitha Padmanabhan
 
Oracle - Program with PL/SQL - Lession 01
Oracle - Program with PL/SQL - Lession 01Oracle - Program with PL/SQL - Lession 01
Oracle - Program with PL/SQL - Lession 01Thuan Nguyen
 
A green solution to solve a race condition problem
A green solution to solve a race condition problemA green solution to solve a race condition problem
A green solution to solve a race condition problemKai Zhou
 
PL/SQL Introduction and Concepts
PL/SQL Introduction and Concepts PL/SQL Introduction and Concepts
PL/SQL Introduction and Concepts Bharat Kalia
 
Oracle - Program with PL/SQL - Lession 06
Oracle - Program with PL/SQL - Lession 06Oracle - Program with PL/SQL - Lession 06
Oracle - Program with PL/SQL - Lession 06Thuan Nguyen
 
Basic cursors in oracle
Basic cursors in oracleBasic cursors in oracle
Basic cursors in oracleSuhel Firdus
 
Oracle - Program with PL/SQL - Lession 11
Oracle - Program with PL/SQL - Lession 11Oracle - Program with PL/SQL - Lession 11
Oracle - Program with PL/SQL - Lession 11Thuan Nguyen
 
Oracle - Program with PL/SQL - Lession 14
Oracle - Program with PL/SQL - Lession 14Oracle - Program with PL/SQL - Lession 14
Oracle - Program with PL/SQL - Lession 14Thuan Nguyen
 
Oracle PL/SQL exception handling
Oracle PL/SQL exception handlingOracle PL/SQL exception handling
Oracle PL/SQL exception handlingSmitha Padmanabhan
 
Oracle - Program with PL/SQL - Lession 13
Oracle - Program with PL/SQL - Lession 13Oracle - Program with PL/SQL - Lession 13
Oracle - Program with PL/SQL - Lession 13Thuan Nguyen
 
Procedures/functions of rdbms
Procedures/functions of rdbmsProcedures/functions of rdbms
Procedures/functions of rdbmsjain.pralabh
 
Trigger and cursor program using sql
Trigger and cursor program using sqlTrigger and cursor program using sql
Trigger and cursor program using sqlSushil Mishra
 
Oracle - Program with PL/SQL - Lession 10
Oracle - Program with PL/SQL - Lession 10Oracle - Program with PL/SQL - Lession 10
Oracle - Program with PL/SQL - Lession 10Thuan Nguyen
 

Tendances (20)

Oracle - Program with PL/SQL - Lession 03
Oracle - Program with PL/SQL - Lession 03Oracle - Program with PL/SQL - Lession 03
Oracle - Program with PL/SQL - Lession 03
 
PL/SQL
PL/SQLPL/SQL
PL/SQL
 
Oracle - Program with PL/SQL - Lession 07
Oracle - Program with PL/SQL - Lession 07Oracle - Program with PL/SQL - Lession 07
Oracle - Program with PL/SQL - Lession 07
 
Procedure and Functions in pl/sql
Procedure and Functions in pl/sqlProcedure and Functions in pl/sql
Procedure and Functions in pl/sql
 
Oracle SQL, PL/SQL best practices
Oracle SQL, PL/SQL best practicesOracle SQL, PL/SQL best practices
Oracle SQL, PL/SQL best practices
 
Oracle - Program with PL/SQL - Lession 01
Oracle - Program with PL/SQL - Lession 01Oracle - Program with PL/SQL - Lession 01
Oracle - Program with PL/SQL - Lession 01
 
A green solution to solve a race condition problem
A green solution to solve a race condition problemA green solution to solve a race condition problem
A green solution to solve a race condition problem
 
Oracle: Procedures
Oracle: ProceduresOracle: Procedures
Oracle: Procedures
 
PLSQL Advanced
PLSQL AdvancedPLSQL Advanced
PLSQL Advanced
 
PL/SQL Introduction and Concepts
PL/SQL Introduction and Concepts PL/SQL Introduction and Concepts
PL/SQL Introduction and Concepts
 
Oracle - Program with PL/SQL - Lession 06
Oracle - Program with PL/SQL - Lession 06Oracle - Program with PL/SQL - Lession 06
Oracle - Program with PL/SQL - Lession 06
 
Basic cursors in oracle
Basic cursors in oracleBasic cursors in oracle
Basic cursors in oracle
 
Oracle - Program with PL/SQL - Lession 11
Oracle - Program with PL/SQL - Lession 11Oracle - Program with PL/SQL - Lession 11
Oracle - Program with PL/SQL - Lession 11
 
Oracle - Program with PL/SQL - Lession 14
Oracle - Program with PL/SQL - Lession 14Oracle - Program with PL/SQL - Lession 14
Oracle - Program with PL/SQL - Lession 14
 
Oracle PL/SQL exception handling
Oracle PL/SQL exception handlingOracle PL/SQL exception handling
Oracle PL/SQL exception handling
 
Oracle - Program with PL/SQL - Lession 13
Oracle - Program with PL/SQL - Lession 13Oracle - Program with PL/SQL - Lession 13
Oracle - Program with PL/SQL - Lession 13
 
Procedures/functions of rdbms
Procedures/functions of rdbmsProcedures/functions of rdbms
Procedures/functions of rdbms
 
Trigger and cursor program using sql
Trigger and cursor program using sqlTrigger and cursor program using sql
Trigger and cursor program using sql
 
Oracle - Program with PL/SQL - Lession 10
Oracle - Program with PL/SQL - Lession 10Oracle - Program with PL/SQL - Lession 10
Oracle - Program with PL/SQL - Lession 10
 
Stored procedure
Stored procedureStored procedure
Stored procedure
 

En vedette

Oracle 11g new features for developers
Oracle 11g new features for developersOracle 11g new features for developers
Oracle 11g new features for developersScott Wesley
 
Automated testing APEX Applications
Automated testing APEX ApplicationsAutomated testing APEX Applications
Automated testing APEX ApplicationsRoel Hartman
 
LOBS, BLOBS, CLOBS: Dealing with Attachments in APEX
LOBS, BLOBS, CLOBS: Dealing with Attachments in APEXLOBS, BLOBS, CLOBS: Dealing with Attachments in APEX
LOBS, BLOBS, CLOBS: Dealing with Attachments in APEXEnkitec
 
Generic collection types in PLSQL
Generic collection types in PLSQLGeneric collection types in PLSQL
Generic collection types in PLSQLArnold Reuser
 
Striving for Perfection: The Ultimate APEX Application Architecture
Striving for Perfection: The Ultimate APEX Application ArchitectureStriving for Perfection: The Ultimate APEX Application Architecture
Striving for Perfection: The Ultimate APEX Application ArchitectureRoel Hartman
 
utPLSQL: Unit Testing for Oracle PL/SQL
utPLSQL: Unit Testing for Oracle PL/SQLutPLSQL: Unit Testing for Oracle PL/SQL
utPLSQL: Unit Testing for Oracle PL/SQLSteven Feuerstein
 
Oracle Text in APEX
Oracle Text in APEXOracle Text in APEX
Oracle Text in APEXScott Wesley
 
Oracle APEX Performance
Oracle APEX PerformanceOracle APEX Performance
Oracle APEX PerformanceScott Wesley
 
Take Full Advantage of the Oracle PL/SQL Compiler
Take Full Advantage of the Oracle PL/SQL CompilerTake Full Advantage of the Oracle PL/SQL Compiler
Take Full Advantage of the Oracle PL/SQL CompilerSteven Feuerstein
 
PL/SQL Code for Sample Projects
PL/SQL Code for Sample ProjectsPL/SQL Code for Sample Projects
PL/SQL Code for Sample Projectsjwjablonski
 
PL/SQL Fundamentals I
PL/SQL Fundamentals IPL/SQL Fundamentals I
PL/SQL Fundamentals INick Buytaert
 
Mastering universal theme
Mastering universal themeMastering universal theme
Mastering universal themeRoel Hartman
 
Migrating to a New DBMS
Migrating to a New DBMSMigrating to a New DBMS
Migrating to a New DBMSStephen Conant
 
10g plsql slide
10g plsql slide10g plsql slide
10g plsql slideTanu_Manu
 
Take a load off! Load testing your Oracle APEX or JDeveloper web applications
Take a load off! Load testing your Oracle APEX or JDeveloper web applicationsTake a load off! Load testing your Oracle APEX or JDeveloper web applications
Take a load off! Load testing your Oracle APEX or JDeveloper web applicationsSage Computing Services
 
PL/SQL Complete Tutorial. All Topics Covered
PL/SQL Complete Tutorial. All Topics CoveredPL/SQL Complete Tutorial. All Topics Covered
PL/SQL Complete Tutorial. All Topics CoveredDanish Mehraj
 
Database Development Mistakes
Database Development MistakesDatabase Development Mistakes
Database Development MistakesMichael Findling
 
Why is the application running so slowly?
Why is the application running so slowly?Why is the application running so slowly?
Why is the application running so slowly?Michael Rosenblum
 

En vedette (20)

Oracle 11g new features for developers
Oracle 11g new features for developersOracle 11g new features for developers
Oracle 11g new features for developers
 
Automated testing APEX Applications
Automated testing APEX ApplicationsAutomated testing APEX Applications
Automated testing APEX Applications
 
LOBS, BLOBS, CLOBS: Dealing with Attachments in APEX
LOBS, BLOBS, CLOBS: Dealing with Attachments in APEXLOBS, BLOBS, CLOBS: Dealing with Attachments in APEX
LOBS, BLOBS, CLOBS: Dealing with Attachments in APEX
 
Generic collection types in PLSQL
Generic collection types in PLSQLGeneric collection types in PLSQL
Generic collection types in PLSQL
 
Striving for Perfection: The Ultimate APEX Application Architecture
Striving for Perfection: The Ultimate APEX Application ArchitectureStriving for Perfection: The Ultimate APEX Application Architecture
Striving for Perfection: The Ultimate APEX Application Architecture
 
utPLSQL: Unit Testing for Oracle PL/SQL
utPLSQL: Unit Testing for Oracle PL/SQLutPLSQL: Unit Testing for Oracle PL/SQL
utPLSQL: Unit Testing for Oracle PL/SQL
 
Oracle Text in APEX
Oracle Text in APEXOracle Text in APEX
Oracle Text in APEX
 
Oracle APEX Performance
Oracle APEX PerformanceOracle APEX Performance
Oracle APEX Performance
 
Take Full Advantage of the Oracle PL/SQL Compiler
Take Full Advantage of the Oracle PL/SQL CompilerTake Full Advantage of the Oracle PL/SQL Compiler
Take Full Advantage of the Oracle PL/SQL Compiler
 
PL/SQL Code for Sample Projects
PL/SQL Code for Sample ProjectsPL/SQL Code for Sample Projects
PL/SQL Code for Sample Projects
 
PL/SQL Fundamentals I
PL/SQL Fundamentals IPL/SQL Fundamentals I
PL/SQL Fundamentals I
 
Best sql plsql material
Best sql plsql materialBest sql plsql material
Best sql plsql material
 
Mastering universal theme
Mastering universal themeMastering universal theme
Mastering universal theme
 
Migrating to a New DBMS
Migrating to a New DBMSMigrating to a New DBMS
Migrating to a New DBMS
 
10g plsql slide
10g plsql slide10g plsql slide
10g plsql slide
 
Take a load off! Load testing your Oracle APEX or JDeveloper web applications
Take a load off! Load testing your Oracle APEX or JDeveloper web applicationsTake a load off! Load testing your Oracle APEX or JDeveloper web applications
Take a load off! Load testing your Oracle APEX or JDeveloper web applications
 
PL/SQL Complete Tutorial. All Topics Covered
PL/SQL Complete Tutorial. All Topics CoveredPL/SQL Complete Tutorial. All Topics Covered
PL/SQL Complete Tutorial. All Topics Covered
 
Views Oracle Database
Views Oracle DatabaseViews Oracle Database
Views Oracle Database
 
Database Development Mistakes
Database Development MistakesDatabase Development Mistakes
Database Development Mistakes
 
Why is the application running so slowly?
Why is the application running so slowly?Why is the application running so slowly?
Why is the application running so slowly?
 

Similaire à Oracle PL/SQL Bulk binds (20)

Oracle pl sql
Oracle pl sqlOracle pl sql
Oracle pl sql
 
Tutorial de forms 10g
Tutorial de forms 10gTutorial de forms 10g
Tutorial de forms 10g
 
Oracle tips and tricks
Oracle tips and tricksOracle tips and tricks
Oracle tips and tricks
 
Oracle - SQL-PL/SQL context switching
Oracle - SQL-PL/SQL context switchingOracle - SQL-PL/SQL context switching
Oracle - SQL-PL/SQL context switching
 
Pl sql guide
Pl sql guidePl sql guide
Pl sql guide
 
Mysqlppt
MysqlpptMysqlppt
Mysqlppt
 
Plsql coding conventions
Plsql coding conventionsPlsql coding conventions
Plsql coding conventions
 
MERGE SQL Statement: Lesser Known Facets
MERGE SQL Statement: Lesser Known FacetsMERGE SQL Statement: Lesser Known Facets
MERGE SQL Statement: Lesser Known Facets
 
High Performance PL/SQL
High Performance PL/SQLHigh Performance PL/SQL
High Performance PL/SQL
 
Trig
TrigTrig
Trig
 
SQL Notes
SQL NotesSQL Notes
SQL Notes
 
Sql Objects And PL/SQL
Sql Objects And PL/SQLSql Objects And PL/SQL
Sql Objects And PL/SQL
 
My SQL.pptx
My SQL.pptxMy SQL.pptx
My SQL.pptx
 
Les06 Subqueries
Les06 SubqueriesLes06 Subqueries
Les06 Subqueries
 
Eff Plsql
Eff PlsqlEff Plsql
Eff Plsql
 
Sql dml & tcl 2
Sql   dml & tcl 2Sql   dml & tcl 2
Sql dml & tcl 2
 
PLSQL (1).ppt
PLSQL (1).pptPLSQL (1).ppt
PLSQL (1).ppt
 
My sql.ppt
My sql.pptMy sql.ppt
My sql.ppt
 
A New View of Database Views
A New View of Database ViewsA New View of Database Views
A New View of Database Views
 
Pl sql programme
Pl sql programmePl sql programme
Pl sql programme
 

Dernier

Discover Why Less is More in B2B Research
Discover Why Less is More in B2B ResearchDiscover Why Less is More in B2B Research
Discover Why Less is More in B2B Researchmichael115558
 
Jual obat aborsi Bandung ( 085657271886 ) Cytote pil telat bulan penggugur ka...
Jual obat aborsi Bandung ( 085657271886 ) Cytote pil telat bulan penggugur ka...Jual obat aborsi Bandung ( 085657271886 ) Cytote pil telat bulan penggugur ka...
Jual obat aborsi Bandung ( 085657271886 ) Cytote pil telat bulan penggugur ka...Klinik kandungan
 
Top profile Call Girls In Hapur [ 7014168258 ] Call Me For Genuine Models We ...
Top profile Call Girls In Hapur [ 7014168258 ] Call Me For Genuine Models We ...Top profile Call Girls In Hapur [ 7014168258 ] Call Me For Genuine Models We ...
Top profile Call Girls In Hapur [ 7014168258 ] Call Me For Genuine Models We ...nirzagarg
 
SAC 25 Final National, Regional & Local Angel Group Investing Insights 2024 0...
SAC 25 Final National, Regional & Local Angel Group Investing Insights 2024 0...SAC 25 Final National, Regional & Local Angel Group Investing Insights 2024 0...
SAC 25 Final National, Regional & Local Angel Group Investing Insights 2024 0...Elaine Werffeli
 
Reconciling Conflicting Data Curation Actions: Transparency Through Argument...
Reconciling Conflicting Data Curation Actions:  Transparency Through Argument...Reconciling Conflicting Data Curation Actions:  Transparency Through Argument...
Reconciling Conflicting Data Curation Actions: Transparency Through Argument...Bertram Ludäscher
 
High Profile Call Girls Service in Jalore { 9332606886 } VVIP NISHA Call Girl...
High Profile Call Girls Service in Jalore { 9332606886 } VVIP NISHA Call Girl...High Profile Call Girls Service in Jalore { 9332606886 } VVIP NISHA Call Girl...
High Profile Call Girls Service in Jalore { 9332606886 } VVIP NISHA Call Girl...kumargunjan9515
 
Computer science Sql cheat sheet.pdf.pdf
Computer science Sql cheat sheet.pdf.pdfComputer science Sql cheat sheet.pdf.pdf
Computer science Sql cheat sheet.pdf.pdfSayantanBiswas37
 
Top profile Call Girls In Chandrapur [ 7014168258 ] Call Me For Genuine Model...
Top profile Call Girls In Chandrapur [ 7014168258 ] Call Me For Genuine Model...Top profile Call Girls In Chandrapur [ 7014168258 ] Call Me For Genuine Model...
Top profile Call Girls In Chandrapur [ 7014168258 ] Call Me For Genuine Model...gajnagarg
 
Top profile Call Girls In bhavnagar [ 7014168258 ] Call Me For Genuine Models...
Top profile Call Girls In bhavnagar [ 7014168258 ] Call Me For Genuine Models...Top profile Call Girls In bhavnagar [ 7014168258 ] Call Me For Genuine Models...
Top profile Call Girls In bhavnagar [ 7014168258 ] Call Me For Genuine Models...gajnagarg
 
Lecture_2_Deep_Learning_Overview-newone1
Lecture_2_Deep_Learning_Overview-newone1Lecture_2_Deep_Learning_Overview-newone1
Lecture_2_Deep_Learning_Overview-newone1ranjankumarbehera14
 
RESEARCH-FINAL-DEFENSE-PPT-TEMPLATE.pptx
RESEARCH-FINAL-DEFENSE-PPT-TEMPLATE.pptxRESEARCH-FINAL-DEFENSE-PPT-TEMPLATE.pptx
RESEARCH-FINAL-DEFENSE-PPT-TEMPLATE.pptxronsairoathenadugay
 
In Riyadh ((+919101817206)) Cytotec kit @ Abortion Pills Saudi Arabia
In Riyadh ((+919101817206)) Cytotec kit @ Abortion Pills Saudi ArabiaIn Riyadh ((+919101817206)) Cytotec kit @ Abortion Pills Saudi Arabia
In Riyadh ((+919101817206)) Cytotec kit @ Abortion Pills Saudi Arabiaahmedjiabur940
 
Top Call Girls in Balaghat 9332606886Call Girls Advance Cash On Delivery Ser...
Top Call Girls in Balaghat  9332606886Call Girls Advance Cash On Delivery Ser...Top Call Girls in Balaghat  9332606886Call Girls Advance Cash On Delivery Ser...
Top Call Girls in Balaghat 9332606886Call Girls Advance Cash On Delivery Ser...kumargunjan9515
 
7. Epi of Chronic respiratory diseases.ppt
7. Epi of Chronic respiratory diseases.ppt7. Epi of Chronic respiratory diseases.ppt
7. Epi of Chronic respiratory diseases.pptibrahimabdi22
 
Top profile Call Girls In Tumkur [ 7014168258 ] Call Me For Genuine Models We...
Top profile Call Girls In Tumkur [ 7014168258 ] Call Me For Genuine Models We...Top profile Call Girls In Tumkur [ 7014168258 ] Call Me For Genuine Models We...
Top profile Call Girls In Tumkur [ 7014168258 ] Call Me For Genuine Models We...nirzagarg
 
Top profile Call Girls In dimapur [ 7014168258 ] Call Me For Genuine Models W...
Top profile Call Girls In dimapur [ 7014168258 ] Call Me For Genuine Models W...Top profile Call Girls In dimapur [ 7014168258 ] Call Me For Genuine Models W...
Top profile Call Girls In dimapur [ 7014168258 ] Call Me For Genuine Models W...gajnagarg
 
Kings of Saudi Arabia, information about them
Kings of Saudi Arabia, information about themKings of Saudi Arabia, information about them
Kings of Saudi Arabia, information about themeitharjee
 
Top profile Call Girls In Bihar Sharif [ 7014168258 ] Call Me For Genuine Mod...
Top profile Call Girls In Bihar Sharif [ 7014168258 ] Call Me For Genuine Mod...Top profile Call Girls In Bihar Sharif [ 7014168258 ] Call Me For Genuine Mod...
Top profile Call Girls In Bihar Sharif [ 7014168258 ] Call Me For Genuine Mod...nirzagarg
 
Statistics notes ,it includes mean to index numbers
Statistics notes ,it includes mean to index numbersStatistics notes ,it includes mean to index numbers
Statistics notes ,it includes mean to index numberssuginr1
 
Top profile Call Girls In Begusarai [ 7014168258 ] Call Me For Genuine Models...
Top profile Call Girls In Begusarai [ 7014168258 ] Call Me For Genuine Models...Top profile Call Girls In Begusarai [ 7014168258 ] Call Me For Genuine Models...
Top profile Call Girls In Begusarai [ 7014168258 ] Call Me For Genuine Models...nirzagarg
 

Dernier (20)

Discover Why Less is More in B2B Research
Discover Why Less is More in B2B ResearchDiscover Why Less is More in B2B Research
Discover Why Less is More in B2B Research
 
Jual obat aborsi Bandung ( 085657271886 ) Cytote pil telat bulan penggugur ka...
Jual obat aborsi Bandung ( 085657271886 ) Cytote pil telat bulan penggugur ka...Jual obat aborsi Bandung ( 085657271886 ) Cytote pil telat bulan penggugur ka...
Jual obat aborsi Bandung ( 085657271886 ) Cytote pil telat bulan penggugur ka...
 
Top profile Call Girls In Hapur [ 7014168258 ] Call Me For Genuine Models We ...
Top profile Call Girls In Hapur [ 7014168258 ] Call Me For Genuine Models We ...Top profile Call Girls In Hapur [ 7014168258 ] Call Me For Genuine Models We ...
Top profile Call Girls In Hapur [ 7014168258 ] Call Me For Genuine Models We ...
 
SAC 25 Final National, Regional & Local Angel Group Investing Insights 2024 0...
SAC 25 Final National, Regional & Local Angel Group Investing Insights 2024 0...SAC 25 Final National, Regional & Local Angel Group Investing Insights 2024 0...
SAC 25 Final National, Regional & Local Angel Group Investing Insights 2024 0...
 
Reconciling Conflicting Data Curation Actions: Transparency Through Argument...
Reconciling Conflicting Data Curation Actions:  Transparency Through Argument...Reconciling Conflicting Data Curation Actions:  Transparency Through Argument...
Reconciling Conflicting Data Curation Actions: Transparency Through Argument...
 
High Profile Call Girls Service in Jalore { 9332606886 } VVIP NISHA Call Girl...
High Profile Call Girls Service in Jalore { 9332606886 } VVIP NISHA Call Girl...High Profile Call Girls Service in Jalore { 9332606886 } VVIP NISHA Call Girl...
High Profile Call Girls Service in Jalore { 9332606886 } VVIP NISHA Call Girl...
 
Computer science Sql cheat sheet.pdf.pdf
Computer science Sql cheat sheet.pdf.pdfComputer science Sql cheat sheet.pdf.pdf
Computer science Sql cheat sheet.pdf.pdf
 
Top profile Call Girls In Chandrapur [ 7014168258 ] Call Me For Genuine Model...
Top profile Call Girls In Chandrapur [ 7014168258 ] Call Me For Genuine Model...Top profile Call Girls In Chandrapur [ 7014168258 ] Call Me For Genuine Model...
Top profile Call Girls In Chandrapur [ 7014168258 ] Call Me For Genuine Model...
 
Top profile Call Girls In bhavnagar [ 7014168258 ] Call Me For Genuine Models...
Top profile Call Girls In bhavnagar [ 7014168258 ] Call Me For Genuine Models...Top profile Call Girls In bhavnagar [ 7014168258 ] Call Me For Genuine Models...
Top profile Call Girls In bhavnagar [ 7014168258 ] Call Me For Genuine Models...
 
Lecture_2_Deep_Learning_Overview-newone1
Lecture_2_Deep_Learning_Overview-newone1Lecture_2_Deep_Learning_Overview-newone1
Lecture_2_Deep_Learning_Overview-newone1
 
RESEARCH-FINAL-DEFENSE-PPT-TEMPLATE.pptx
RESEARCH-FINAL-DEFENSE-PPT-TEMPLATE.pptxRESEARCH-FINAL-DEFENSE-PPT-TEMPLATE.pptx
RESEARCH-FINAL-DEFENSE-PPT-TEMPLATE.pptx
 
In Riyadh ((+919101817206)) Cytotec kit @ Abortion Pills Saudi Arabia
In Riyadh ((+919101817206)) Cytotec kit @ Abortion Pills Saudi ArabiaIn Riyadh ((+919101817206)) Cytotec kit @ Abortion Pills Saudi Arabia
In Riyadh ((+919101817206)) Cytotec kit @ Abortion Pills Saudi Arabia
 
Top Call Girls in Balaghat 9332606886Call Girls Advance Cash On Delivery Ser...
Top Call Girls in Balaghat  9332606886Call Girls Advance Cash On Delivery Ser...Top Call Girls in Balaghat  9332606886Call Girls Advance Cash On Delivery Ser...
Top Call Girls in Balaghat 9332606886Call Girls Advance Cash On Delivery Ser...
 
7. Epi of Chronic respiratory diseases.ppt
7. Epi of Chronic respiratory diseases.ppt7. Epi of Chronic respiratory diseases.ppt
7. Epi of Chronic respiratory diseases.ppt
 
Top profile Call Girls In Tumkur [ 7014168258 ] Call Me For Genuine Models We...
Top profile Call Girls In Tumkur [ 7014168258 ] Call Me For Genuine Models We...Top profile Call Girls In Tumkur [ 7014168258 ] Call Me For Genuine Models We...
Top profile Call Girls In Tumkur [ 7014168258 ] Call Me For Genuine Models We...
 
Top profile Call Girls In dimapur [ 7014168258 ] Call Me For Genuine Models W...
Top profile Call Girls In dimapur [ 7014168258 ] Call Me For Genuine Models W...Top profile Call Girls In dimapur [ 7014168258 ] Call Me For Genuine Models W...
Top profile Call Girls In dimapur [ 7014168258 ] Call Me For Genuine Models W...
 
Kings of Saudi Arabia, information about them
Kings of Saudi Arabia, information about themKings of Saudi Arabia, information about them
Kings of Saudi Arabia, information about them
 
Top profile Call Girls In Bihar Sharif [ 7014168258 ] Call Me For Genuine Mod...
Top profile Call Girls In Bihar Sharif [ 7014168258 ] Call Me For Genuine Mod...Top profile Call Girls In Bihar Sharif [ 7014168258 ] Call Me For Genuine Mod...
Top profile Call Girls In Bihar Sharif [ 7014168258 ] Call Me For Genuine Mod...
 
Statistics notes ,it includes mean to index numbers
Statistics notes ,it includes mean to index numbersStatistics notes ,it includes mean to index numbers
Statistics notes ,it includes mean to index numbers
 
Top profile Call Girls In Begusarai [ 7014168258 ] Call Me For Genuine Models...
Top profile Call Girls In Begusarai [ 7014168258 ] Call Me For Genuine Models...Top profile Call Girls In Begusarai [ 7014168258 ] Call Me For Genuine Models...
Top profile Call Girls In Begusarai [ 7014168258 ] Call Me For Genuine Models...
 

Oracle PL/SQL Bulk binds

  • 1. SAGE Computing Services Customised Oracle Training Workshops and Consulting BulkBinds Be A Bulk Binding Baron Sco tt We sle y Syste m s Co nsultant & Traine r
  • 2.
  • 5.
  • 6.
  • 7.
  • 10. not used often enough
  • 11. binding is the assignment of values to placeholders in SQL statements my_column = :my_value
  • 12. Bulk Binding is binding an array of values my_column = my_array(i)
  • 17. A quick word on Collections
  • 18. lists or sets of information
  • 20.
  • 21. can be faster than SQL
  • 23.
  • 24. my_module (pt_array IN OUT NOCOPY t_array)
  • 26. • Associative Arrays (aka index-by tables) – Only PL/SQL – Sparse – Can have negative indexes – Similar to hash table concept – Different datatypes for indexes – TYPE type _ nam e IS TABLE OF e le m e nt_ type [NOT NULL] INDEX BY [PLS_INTEGER | BINARY_INTEGER | VARCHAR2(siz e _ lim it)]; TYPE emp_tab IS TABLE OF employees %ROWTYPE INDEX BY PLS_INTEGER;
  • 27. • Nested Tables – Can use in SQL – Unbounded – Good for set operations – TYPE type _ nam e IS TABLE OF e le m e nt_ type [NOT NULL]; TYPE top_emp IS TABLE OF employees.employee_id%TYPE; CREATE TYPE galaxy AS TABLE OF star_object;
  • 28. • VARRAY – Specify maximums – Dense – Can use in SQL – Most similar to 3GL array – TYPE type _ nam e IS {VARRAY | VARYING ARRAY} (siz e _ lim it) OF e le m e nt_ type [NOT NULL]; TYPE Calendar IS VARRAY(366) OF DATE; CREATE TYPE rainbow AS VARRAY(7) OF VARCHAR2(64); CREATE TYPE solar_system AS VARRAY(8) OF planet_object;
  • 29. back to the business of binds
  • 30. from the 8.1.7 documentation
  • 31.
  • 32. Conventional Bind Performance penalty for many context switches Oracle Server PL/SQL Runtime Engine PL/SQL block Procedural statement executor SQL Engine SQL statement executorFOR r_emp IN c_emp LOOP UPDATE emp SET sal = sal * 1.1 WHERE empno = r_emp.empno; END LOOP;
  • 33. Bulk Bind Much less overhead Oracle Server PL/SQL Runtime Engine PL/SQL block Procedural statement executor SQL Engine SQL statement executorFORALL i IN INDICES OF t_emp UPDATE emp SET sal = sal * 1.1 WHERE empno = t_emp(i);
  • 34. when would you use it?
  • 37. no bulk bind – do it in SQL
  • 38. “If the DML statement affects four or more database rows, the use of bulk SQL can improve performance considerably” - Oracle Documentation
  • 39. SELECT everyone BULK COLLECT INTO my_array FROM the_worlds_idiots;
  • 40. SELECT everyone BULK COLLECT INTO my_array LIMIT 100 FROM the_worlds_idiots;
  • 41. reoccurring SQL within PL/SQL loop
  • 42.
  • 43. multiple operations on dataset – BULK COLLECT
  • 45. 11g compound triggers – auditing
  • 46. finally some coding examples?
  • 47. DML Bind Example -- Slower method, running the UPDATE -- statements within a regular loop FOR i IN t_emp.FIRST..t_emp.LAST LOOP UPDATE emp_largish SET sal = sal * 1.1 WHERE empno = t_emp(i); END LOOP; 1.94 seconds -- Efficient method, using a bulk bind on a VARRAY FORALL i IN t_emp.FIRST..t_emp.LAST UPDATE emp_largish SET sal = sal * 1.1 WHERE empno = t_emp(i); 1.40 seconds
  • 48. Collect Example -- Slower method, assigning each -- collection element within a loop. v_index := 0; FOR r_emp IN c_emp LOOP v_index := v_index + 1; t_emp(v_index).empno := r_emp.empno; t_emp(v_index).ename := r_emp.ename; END LOOP; 0.19 seconds -- Efficient method, using a bulk bind OPEN c_emp; FETCH c_emp BULK COLLECT INTO t_emp; CLOSE c_emp; 0.09 seconds
  • 49. Example of Combination -- Slower method, running update -- statement within regular loop, -- returning individual elements FOR i IN t_emp.FIRST..t_emp.LAST LOOP UPDATE emp_largish SET sal = sal * 1.1 WHERE empno = t_emp(i) RETURNING sal INTO t_sal(i); END LOOP; 0.75 seconds -- Efficient method, using a bulk bind -- and bulk collect FORALL i IN t_emp.FIRST..t_emp.LAST UPDATE emp_largish SET sal = sal * 1.1 WHERE empno = t_emp(i) RETURNING sal BULK COLLECT INTO t_sal; 0.29 seconds
  • 52. can you just do it in SQL? when you only need one iteration just filter records with where/intersect/minus when you haven't tested it with & without >= 10g may silently do it for you too much data?
  • 53. what if I have a sparse collection?
  • 54. Uh oh… DECLARE TYPE emp_tab IS TABLE OF emp.empno%TYPE INDEX BY PLS_INTEGER; t_emp emp_tab; CURSOR c_emp IS SELECT empno FROM emp; BEGIN OPEN c_emp; FETCH c_emp BULK COLLECT INTO t_emp; CLOSE c_emp; -- ...do a bunch of processing, including -- something like: t_emp.DELETE(3); FORALL i IN t_emp.FIRST..t_emp.LAST UPDATE emp SET sal = sal * 1.1 WHERE empno = t_emp(i); END; / ORA-22160: element at index [3] does not exist ORA-06512: at line 15
  • 57. INDICES OF allows iteration of all index values, not just from lower to upper bound (tab.FIRST..tab.LAST)
  • 58. VALUES OF Create PL/SQL table effectively indexing your collection - process specific elements - process in particular order - process an element more than once
  • 59. simple FORALL i IN t_emp.FIRST..t_emp.LAST UPDATE emp SET sal = sal * 1.1 WHERE empno = t_emp(i); FIRST LAST Updated all rows In order of array listing
  • 60. simple FORALL i IN t_emp.FIRST..t_emp.LAST UPDATE emp SET sal = sal * 1.1 WHERE empno = t_emp(i); FIRST LAST ORA-22160: element at index [3] does not exist
  • 61. clever FORALL i IN INDICES OF t_emp UPDATE emp SET comm = comm * 1.5 WHERE empno = t_emp(i); 7890 7988 7752 7521 7900 Updated rows within array In order of array listing t_emp(3) := 7890 t_emp(5) := 7988 t_emp(6) := 7752 t_emp(8) := 7521 t_emp(9) := 7900
  • 62. advanced 7890 7988 7752 t_index(-2):= 6 t_index( 0):= 3 t_index( 3):= 5 t_index(10):= 6 t_emp(9) := 7900 t_emp(8) := 7521 t_emp(6) := 7752 t_emp(5) := 7988 t_emp(3) := 7890 FORALL i IN VALUES OF t_index UPDATE emp SET comm = comm * 1.5 WHERE empno = t_emp(i); DECLARE TYPE emp_tab IS TABLE OF emp.empno%TYPE INDEX BY PLS_INTEGER; TYPE numlist IS TABLE OF PLS_INTEGER INDEX BY BINARY_INTEGER; t_emp emp_tab; t_indexes numlist; BEGIN t_emp(3) := 7890; t_emp(5) := 7988; t_emp(6) := 7752; t_emp(8) := 7521; t_emp(9) := 7900; t_indexes(-2) := 6; t_indexes(0) := 3; t_indexes(3) := 5; t_indexes(10) := 6;
  • 63. what if I have 9i?
  • 64. CREATE OR REPLACE PACKAGE BODY sw_bulk_insert IS PROCEDURE sw_insert (sw_tab IN t_sw_tab) IS BEGIN $IF dbms_db_version.ver_le_9 $THEN DECLARE l_dense t_sw_tab; ln_index PLS_INTEGER := sw_tab.FIRST; BEGIN << dense_loop >> WHILE (l_index IS NOT NULL) LOOP l_dense(l_dense.COUNT + 1) := sw_tab(l_index); l_index := sw_tab.NEXT(l_index); END LOOP dense_loop; FORALL i IN 1..l_dense.COUNT INSERT INTO sw_table VALUES l_dense(i); END; $ELSE FORALL i IN INDICES OF sw_tab INSERT INTO sw_table VALUES sw_tab(i); $END END sw_insert; END sw_bulk_insert;
  • 65. DECLARE t_emp t_emp_obj; BEGIN SELECT emp_obj(empno, ename, job, mgr, hiredate, sal, comm, deptno) BULK COLLECT INTO t_emp FROM emp; -- Remove those with commission to create sparse collection FOR i IN 1..t_emp.COUNT LOOP IF t_emp(i).comm IS NOT NULL THEN t_emp.DELETE(i); END IF; END LOOP; -- No need for FORALL INSERT INTO emp2 SELECT * FROM TABLE(CAST(t_emp AS t_emp_obj)); END; / CREATE TABLE emp2 AS SELECT * FROM emp WHERE 1=0; CREATE OR REPLACE TYPE emp_obj AS OBJECT (empno NUMBER(4) ,ename VARCHAR2(10) ,job VARCHAR2(9) ,mgr NUMBER(4) ,hiredate DATE ,sal NUMBER(7,2) ,comm NUMBER(7,2) ,deptno NUMBER(2)) / CREATE OR REPLACE TYPE t_emp_obj AS TABLE OF emp_obj /
  • 66. can I do this "bunch of processing" in bulk, outside the db?
  • 67. DECLAREDECLARE TYPE emp_tab IS TABLE OF emp.empno%TYPE INDEX BY PLS_INTEGER;TYPE emp_tab IS TABLE OF emp.empno%TYPE INDEX BY PLS_INTEGER; t_emp emp_tab;t_emp emp_tab; CURSOR c_emp ISCURSOR c_emp IS SELECT empno FROM emp;SELECT empno FROM emp; BEGINBEGIN OPEN c_emp;OPEN c_emp; FETCH c_emp BULK COLLECT INTO t_emp;FETCH c_emp BULK COLLECT INTO t_emp; CLOSE c_emp;CLOSE c_emp; -- ...do a bunch of processing, including -- something like: t_emp.DELETE(3); FORALL i IN t_emp.FIRST..t_emp.LASTFORALL i IN t_emp.FIRST..t_emp.LAST UPDATE empUPDATE emp SET sal = sal * 1.1SET sal = sal * 1.1 WHERE empno = t_emp(i);WHERE empno = t_emp(i); END;END; // -- ... Or just those employees that exist in another collection -- t_emp intersect with t_emp_leaders;
  • 70.
  • 71. DECLARE TYPE colours IS TABLE OF VARCHAR2(64); comp1 colours; comp2 colours; result colours; PROCEDURE show_table (p_table IN colours) IS BEGIN FOR i IN p_table.FIRST..p_table.LAST LOOP DBMS_OUTPUT.PUT (p_table(i)||' '); END LOOP; DBMS_OUTPUT.NEW_LINE; END; BEGIN comp1 := colours('Black','White','Red','Red'); comp2 := colours('Black','Red','Yellow'); result := comp1 MULTISET UNION comp2; dbms_output.put_line ('multiset union is '); show_table(result); END; / multiset union is Black White Red Red Black Red Yellow
  • 72. ... BEGIN comp1 := colours('Black','White','Red','Red'); comp2 := colours('Black','Red','Yellow'); result := comp1 MULTISET UNION DISTINCT comp2; dbms_output.put_line ('multiset union distinct is '); show_table(result); END; / multiset union distinct is Black White Red Yellow
  • 73. ... BEGIN comp1 := colours('Black','White','Red','Red'); comp2 := colours('Black','Red','Yellow'); result := comp1 MULTISET INTERSECT DISTINCT comp2; dbms_output.put_line ('multiset intersect distinct is '); show_table(result); END; / multiset intersect distinct is Black Red
  • 74. ... BEGIN comp1 := colours('Black','White','Red','Red'); comp2 := colours('Black','Red','Yellow'); result := comp1 MULTISET EXCEPT DISTINCT comp2; dbms_output.put_line ('multiset except distinct is '); show_table(result); END; / multiset except distinct is White
  • 75. ... BEGIN comp1 := colours('Black','White','Red','Red'); comp1 := comp1 MULTISET UNION DISTINCT comp1; dbms_output.put_line (‘self multiset intersect distinct is '); show_table(comp1); END; / self multiset union distinct is Black White Red
  • 76. DECLARE TYPE colours IS TABLE OF VARCHAR2(64); t_colours colours := colours('Black','White','Red','Red'); PROCEDURE show_table (p_table IN colours) ... BEGIN DBMS_OUTPUT.PUT_LINE('Count:'||CARDINALITY(t_colours)); DBMS_OUTPUT.PUT_LINE('Distinct:'||CARDINALITY(SET(t_colours))); IF t_colours IS NOT A SET THEN t_colours := SET(t_colours); show_table(t_colours); END IF; END; / Count:4 Distinct:3 Black White Red
  • 77. but wait, there's still more...
  • 78. Equality DECLARE TYPE colours IS TABLE OF VARCHAR2 (64); group1 colours := colours ('Black', 'White'); group2 colours := colours ('White', 'Black'); group3 colours := colours ('White', 'Red'); BEGIN IF group1 = group2 THEN DBMS_OUTPUT.PUT_LINE ('Group 1 = Group 2'); ELSE DBMS_OUTPUT.PUT_LINE ('Group 1 != Group 2'); END IF; IF group2 != group3 THEN DBMS_OUTPUT.PUT_LINE ('Group 2 != Group 3'); ELSE DBMS_OUTPUT.PUT_LINE ('Group 2 = Group 3'); END IF; END; /
  • 79. DECLARE TYPE colours IS TABLE OF VARCHAR2(64); t_colours colours := colours('Black','White','Red','Red'); v_colour VARCHAR2(64) := 'Black'; BEGIN IF v_colour MEMBER OF t_colours THEN DBMS_OUTPUT.PUT_LINE('Exists'); ELSE DBMS_OUTPUT.PUT_LINE(‘Absent'); END IF; END; / Exists Membership
  • 80. DECLARE TYPE colours IS TABLE OF VARCHAR2(64); t_colours colours := colours('Black','White','Red','Yellow'); t_colours2 colours := colours('Black','Red'); t_colours3 colours := colours('Black','Blue'); BEGIN IF t_colours2 SUBMULTISET OF t_colours THEN DBMS_OUTPUT.PUT_LINE('2 Subset'); ELSE DBMS_OUTPUT.PUT_LINE('2 Separate'); END IF; IF t_colours3 SUBMULTISET OF t_colours THEN DBMS_OUTPUT.PUT_LINE('3 Subset'); ELSE DBMS_OUTPUT.PUT_LINE('3 Separate'); END IF; END; / 2 Subset 3 Separate Subset
  • 81.
  • 82. DECLARE TYPE t_c IS TABLE OF VARCHAR2(32767) INDEX BY PLS_INTEGER; l_c t_c; BEGIN SELECT LPAD('x',32767,'x') bb BULK COLLECT INTO l_c FROM DUAL CONNECT BY LEVEL <=1000000; END; / declare * ERROR at line 1: ORA-04030: out of process memory when trying to allocate 16396 bytes (koh-kghu call ,pl/sql vc2) ORA-06512: at line 5 Elapsed: 00:00:02.70 Boom!
  • 84. prevent collections from expanding with no limit
  • 85. SELECT sal BULK COLLECT INTO t_emp FROM emp WHERE ROWNUM <= 10; WHERE ROWNUM BETWEEN 11 AND 20 – Won’t work FROM emp SAMPLE(10) -- “Random” -- Performance hit: SELECT * FROM ( SELECT ROW_NUMBER() OVER (ORDER BY empno) AS from_to_rank …) WHERE from_to_rank BETWEEN 1 AND 10
  • 87. DECLARE v_rows PLS_INTEGER := 10; BEGIN OPEN c_emp; LOOP FETCH c_emp BULK COLLECT INTO t_emp LIMIT v_rows; EXIT WHEN t_emp.COUNT = 0; null; -- (Process information) END LOOP; CLOSE c_emp;
  • 88. take care with the exit condition
  • 89. OPEN c_emp; LOOP FETCH c_emp BULK COLLECT INTO t_emp LIMIT v_rows; EXIT WHEN t_emp.COUNT = 0; -- Here? null; -- (Process information) EXIT WHEN c_emp%NOTFOUND; -- or here? END LOOP; CLOSE c_emp; EXCEPTION WHEN NO_DATA_FOUND -- Does this get raised?
  • 90. t_emp.COUNT = 0 ** Count:10 CLARK JAMES MARTIN MILLER WARD KING ALLEN ADAMS SMITH JONES ** Count:4 TURNER BLAKE SCOTT FORD ** Count:0 PL/SQL procedure successfully completed. LOOP FETCH c_emp BULK COLLECT INTO t_emp LIMIT 10; dbms_output.put_line('** Count:'||t_emp.COUNT); EXIT WHEN t_emp.COUNT = 0; dbms_output.put_line(t_emp(i).ename); -- EXIT WHEN c_emp%NOTFOUND;
  • 91. WHEN c_emp%NOTFOUND ** Count:10 CLARK JAMES MARTIN MILLER WARD KING ALLEN ADAMS SMITH JONES ** Count:4 TURNER BLAKE SCOTT FORD PL/SQL procedure successfully completed. LOOP FETCH c_emp BULK COLLECT INTO t_emp LIMIT 10; dbms_output.put_line('** Count:'||t_emp.COUNT); -- EXIT WHEN t_emp.COUNT = 0; dbms_output.put_line(t_emp(i).ename); EXIT WHEN c_emp%NOTFOUND;
  • 93. DECLARE TYPE emp_tab IS TABLE OF emp.empno%TYPE INDEX BY PLS_INTEGER; t_emp emp_tab; BEGIN SELECT empno BULK COLLECT INTO t_emp FROM emp LIMIT 10; END; / LIMIT 10 * ERROR at line 8: ORA-06550: line 8, column 9: PL/SQL: ORA-00933: SQL command not properly ended ORA-06550: line 5, column 3: PL/SQL: SQL Statement ignored
  • 94. and if I have no data?
  • 95. NO_DATA_FOUND DECLARE v_sal emp.sal%TYPE; BEGIN SELECT sal INTO v_sal FROM emp WHERE 1=0; END; / DECLARE * ERROR at line 1: ORA-01403: no data found ORA-06512: at line 4 DECLARE TYPE emp_tab IS TABLE OF emp.sal%TYPE INDEX BY PLS_INTEGER; t_emp emp_tab; BEGIN SELECT sal BULK COLLECT INTO t_emp FROM emp WHERE 1=0; END; / PL/SQL procedure successfully completed.
  • 97. Bulk Cursor Attributes DECLARE TYPE dept_list IS TABLE OF NUMBER; t_dept dept_list := dept_list(10, 20, 30); BEGIN FORALL i IN t_dept.FIRST..t_dept.LAST DELETE FROM emp WHERE deptno = t_dept(i); -- Each indice may update multiple rows dbms_output.put_line('Total rows affected: '||SQL%ROWCOUNT); -- How many rows were affected by each delete statement? FOR j IN t_dept.FIRST..t_dept.LAST LOOP dbms_output.put_line('Dept '||t_dept(j)|| 'rows:'||SQL%BULK_ROWCOUNT(j)); END LOOP; END; / Total rows affected: 14 Dept 10 rows:3 Dept 20 rows:5 Dept 30 rows:6 PL/SQL procedure successfully completed.
  • 98. what if we have exceptions for a particular row?
  • 99. CREATE TABLE emp2 AS SELECT * FROM emp; ALTER TABLE emp2 ADD CONSTRAINT be_test CHECK (sal = ROUND(sal));DECLARE TYPE emp_list IS TABLE OF NUMBER; t_emp emp_list := emp_list(7934, 7782, 7839, 7788, 7900); e_dml_errors EXCEPTION; PRAGMA exception_init(e_dml_errors, -24381); BEGIN FORALL i IN t_emp.FIRST..t_emp.LAST SAVE EXCEPTIONS -- Will raise exception for sal of 1250 but not 1300 UPDATE emp2 SET sal = sal/100 WHERE empno = t_emp(i); dbms_output.put_line('Total rows affected: ‘ ||SQL%ROWCOUNT); EXCEPTION WHEN e_dml_errors THEN -- Now we figure out what failed and why. dbms_output.put_line('Total failed updates: '||SQL%BULK_EXCEPTIONS.COUNT); FOR j IN 1..SQL%BULK_EXCEPTIONS.COUNT LOOP dbms_output.put_line('Error '||j||' for indice ‘ ||SQL%BULK_EXCEPTIONS(j).ERROR_INDEX); dbms_output.put_line('Error message is ‘ ||SQLERRM(-SQL%BULK_EXCEPTIONS(j).ERROR_CODE)); END LOOP; END; Total failed updates: 2 Error 1 for indice 2 Error message is ORA-02290: check constraint (.) violated Error 2 for indice 5 Error message is ORA-02290: check constraint (.) violated PL/SQL procedure successfully completed.
  • 100. Bulk Exceptions select empno, ename, sal from emp2 where empno in (7934, 7782, 7839, 7788, 7900); EMPNO ENAME SAL ---------- ---------- ---------- 7934 MILLER 13 7782 CLARK 2450 7839 KING 50 7788 SCOTT 30 7900 JAMES 950 5 rows selected.
  • 102. FOR CURSOR COLLECT LIMIT100 IISS
  • 103. Enterprise Manager Limit 100 vs 1000 Separate runs of For | Cursor | Collect | Limit | IISS
  • 104. What’s new? • 8i – Bulk operations! – Collections indexed by BINARY_INTEGER only • 9i – Bulk collect via dynamically opened ref cursor • 9i Release 2 – Bulk collect into collection of records – Index by VARCHAR2 & BINARY_INTEGER (or their subtypes) • 10g – PL/SQL engine may decide to peform array fetching for you – INDICES OF/VALUES OF introduced – MULTISET operations • 11g – table(bulk_index).field is now supported at run-time – DBMS_SQL allows bulk binds using user-define collection types
  • 105. CREATE TABLE emp2 AS SELECT empno,ename,sal, SYSTIMESTAMP ts FROM emp WHERE 1=0; DECLARE CURSOR sw IS SELECT empno, ename, sal FROM emp; TYPE t_sw IS TABLE OF sw%ROWTYPE; lt_sw t_sw; BEGIN OPEN sw; FETCH sw BULK COLLECT INTO lt_sw; CLOSE sw; FORALL i IN lt_sw.FIRST..lt_sw.LAST INSERT INTO emp2 VALUES (lt_sw(i).empno ,lt_sw(i).ename ,lt_sw(i).sal ,SYSTIMESTAMP); END; / values (lt_sw(i).empno * ERROR at line 11: ORA-06550: line 11, column 9: PLS-00436: implementation restriction: cannot reference fields of BULK In-BIND table of records
  • 108. READ THIS… TWICE! • Tom Kyte – In search of the truth - Or Correlation is not Causation – http://asktom.oracle.com/pls/ask/download_file?p_file=3067171813508 – “If any pape r yo u re ad te lls yo u what but no t why, re g ardle ss o f its tim e stam p, Isug g e st yo u take its advice with a big g rain o f salt as it m ay be applicable onlyto onlyspecific cases andnot applicabletoyouat all. In fact, it co uld be so m e thing that was true in the past and no t true anym o re . If theygiveyouno wayto findout, ignoreit. ”
  • 110. it only takes one case to show something is...
  • 112. Rules of thumb without evidence, without ways to test them before implementing them, are dangerous, seriously dangerous “Because a rule of thumb is a principle with broad application not intended to be strictly accurate or reliable for all situations”
  • 113. SAGE Computing Services Customised Oracle Training Workshops and Consulting Questions and Answers? Presentations are available from our website: http: //www. sag e co m puting . co m . au e nq uirie s@ sag e co m puting . co m . au sco tt. we sle y@ sag e co m puting . co m . au http: //triang le -circle -sq uare . blo g spo t. co m

Notes de l'éditeur

  1. Good excuse for cheese
  2. Scott from Sage – Consultant &amp; Trainer
  3. Scott from Sage – Consultant &amp; Trainer
  4. Scott from Sage – Consultant &amp; Trainer
  5. Scott from Sage – Consultant &amp; Trainer
  6. Back to the business at hand
  7. But it can only be done in the right context
  8. We’ll also have a look at theses
  9. Can be like a 3GL array
  10. Get comfortable
  11. Get comfortable with them
  12. Depending on what you’re doing
  13. Process/program global area
  14. I’ll show you how to get oracle in a knot later
  15. Consider this, but be very careful
  16. Associative arrays – I’d imagine most are familiar with index-by tables – most flexible, used in my demos for bulk binds
  17. The other two are sometimes talked about the same, can be defined as a column in a table or an object. No index by clause
  18. VARRAYS are dense, must remove elements from end of array - FILO
  19. A little boring and makes you think…
  20. As Guy mentioned, you can use pl/sql tuning tools to see essentially how much time spent in each engine
  21. Well if you saw Guy’s presentation, you’d think that one day you could do this and the database will just code itself.
  22. Doesn’t need to be from a massive table
  23. You will need this keyword to avoid memory issues
  24. How able a real world example?
  25. There are great examples out there showing how to improve auditing functionality with compound triggers
  26. Very minor change in the code.
  27. Come on, I think we’ve ALL done this in the past, I’m pretty sure I have. Especially in my Pascal days.
  28. And we can easily combine the two
  29. I’m considering in &amp; out binding...
  30. Remember the golden rule
  31. On the line of “when wouldn’t you”, perhaps you’re thinking, well, if I gather info in bulk, do a heap of operations in the meantime, all of a sudden I have a sparse collection – how do I use FORALL with FIRST..LAST? It ain’t gonna cut it.
  32. Introduced in 10g, probably the best advancement in bulk binds since it was introduced in 8i
  33. For all elements in the array, update using the relevant empno (value) found
  34. For all VALUES of t_index, update USING t_emp T_index index defines - order - frequency
  35. You’re out of support…apparently
  36. You can prepare for future versions using conditional compilation In the meantime slide the array to fill the gaps
  37. … but that may not always be feasible. Alternatively, we could use object types and skip forall:
  38. Theoretically no “order” to their elements Makes set operations critical!
  39. I noticed those with synesthesia may have trouble with the next few slides
  40. Yes, you can operate these functions on itself, but there’s and easier way to get a distinct set.
  41. But this doesn’t really modify our data – but it was a LOT harder to do in earlier versions.
  42. I promised to talk about memory issues
  43. Yep, my sister is the graphic designer... I’m the computer guy in the family
  44. If we want to process chunks of data from a large set, we can’t really use any of these. As awesome as sample is….
  45. When I first saw this I thought “what’s the point, how do we process the rest? Do we have to flag rows processed” No! It’s to consider memory ramifications. Process a chunk of data each iteration, and then look at the next, automatically overriding previous collection. Test on your system what the “magic number” is regarding chunk size. Just don’t forget the exit condition like I did when I was setting up my performance comparisons.
  46. There are a couple of variations. Where do I put that exit condition, for example.
  47. And be totally sure where you would like your exit condition.
  48. Note it doesn’t go into the third iteration
  49. Steve Feuerstein described it as an “oddity” – along with something fixed in 10g release (fetching into collection of records using limit). It makes sense to me. How do you process a chunk at a time using an implicit cursor?!
  50. What should be considered an oddity
  51. Note the output after the FORALL UPDATE – it doesn’t get executed, yet the DML has been applied! Note is saves the error code, not the actual error text – hence the missing constraint
  52. See! The data has been updated, even though exception was raised.
  53. You don’t need to convert data timings into pretty graphs, enterprise manager can also graphically let you know some differences.
  54. Yep, still improvements in 11g. So it’s not an old topic that everyone knows and uses. Other features of 11g also conducive to bulk operations, such as the compound audit trigger in Connor’s 11g presentation.
  55. No longer an issue in 11g. This may have also have improved some of the timings in the graphs I showed, but I wanted to compares apples to apples.
  56. Because a rule of thumb is a principle with broad application not intended to be strictly accurate or reliable for all situations