brave new world two days for 2005
TRANSCRIPT
-
8/14/2019 Brave New World TWO DAYS for 2005
1/280
Copyright 2000-2005 Steven Feuerstein - Page 1
The Brave New Worldof Oracle PL/SQL
"Gotta Know, Gotta Use"New Features of
Oracle8i, Oracle9i and Oracle10g PL/SQL
Steven [email protected]
m
All non-technical views expressed are those of Steven Feuerstein and donot necessarily (and not likely!) reflect those of Quest or the TCOUG.
-
8/14/2019 Brave New World TWO DAYS for 2005
2/280
Copyright 2000-2005 Steven Feuerstein - Page 2
The New Topography of a PowerfulLanguage
New/enhanced data structures and data types Collections, object types, TIMESTAMP,
INTERVAL, XMLType
Enhancements to the SQL-PL/SQL interface Native Dynamic SQL, bulk processing, record-
based DML
Miscellaneous - but not leftovers
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE, Javafrom PL/SQL, UTL_FILE enhancements, CASE,row level security
-
8/14/2019 Brave New World TWO DAYS for 2005
3/280
Copyright 2000-2005 Steven Feuerstein - Page 3
"All" about Steven Feuerstein
Bachelor's degree in mathematics (1980), with threecomputer 101 classes to my name (a self-taughtprogrammer).
Five years with Oracle Corporation (1987 - 1992), withtoo much time spent helping salespeople sell. Life istoo short...
Author/co-author of nine texts on PL/SQL, most
notably Oracle PL/SQL Programming. I live in Chicago with one wife (Veva), two sons (Chris
and Eli), and three cats (Sister, Moshe and Mica).
www.stevenfeuerstein.co
-
8/14/2019 Brave New World TWO DAYS for 2005
4/280
Copyright 2000-2005 Steven Feuerstein - Page 4
Ten Years of Writing onthe Oracle PL/SQL Language
-
8/14/2019 Brave New World TWO DAYS for 2005
5/280
Copyright 2000-2005 Steven Feuerstein - Page 5
Software Used in Training
You can download all my training materials anddemonstration scripts from:
http://oracleplsqlprogramming.com/resources.html
Toad and/or SQL Navigator: make sure you've got a top-notch IDE, otherwise you are wasting lots of time.
Ounit and utPLSQL, software for unit testing of PL/SQL codeat www.ounit.com.
Mastoid Mind and Set: have fun while keepingyour brain tuned up.
Qnxo, active mentoring software: a repository ofreusable and templated code, www.qnxo.com.plsql_ides.txt
-
8/14/2019 Brave New World TWO DAYS for 2005
6/280
Copyright 2000-2005 Steven Feuerstein - Page 6
About Qnxo
Qnxo is a searchable, customizable repository forreusable code and templates.
Starter set: "PL/SQL by Feuerstein"
You can create our own toolboxes and libraries.
Qnxo is a flexible code generator that helps youavoid writing tedious, repetitive code.
Qnxo is an error manager for PL/SQL-basedapplications.
-
8/14/2019 Brave New World TWO DAYS for 2005
7/280
Copyright 2000-2005 Steven Feuerstein - Page 7
Qnxo is....
NOT an integrated development environment,aka IDE, aka editor, for PL/SQL programming. It complements Toad, SQL Navigator, PL/SQL
Developer, etc.
NOT free. Qnxo is sold on a subscription basis (youare paying for content).There is a trial version and there will be a free
version in the future (design platform minus
content). NOT neededin order to benefit from this class.
Qnxo contains a repository of examples.
The Qnxo backend reflects my latest (and, I
But we will raffle off a one year sub in class!
-
8/14/2019 Brave New World TWO DAYS for 2005
8/280
Copyright 2000-2005 Steven Feuerstein - Page 8
Some PL/SQL Fundamentals
The STANDARD package and how to be aPL/SQL sleuth
The PL/SQL run-time memory architecture
Quick reminders about packages Overloading: use it to improve the usability
of your code.
Packaged data
The initialization section
Packages or stand-alone programs?
-
8/14/2019 Brave New World TWO DAYS for 2005
9/280
Copyright 2000-2005 Steven Feuerstein - Page 9
The STANDARD Package and theRdbms/Admin Directory
Much of what we consider to be the basePL/SQL language is defined in the STANDARDpackage.
One of two "default" packages; the other isDBMS_STANDARD.
You can view the contents of the STANDARDpackage (and other "supplied" packages by
visiting the appropriate variation of:$ORACLE_HOME/Rdbms/Admin
-
8/14/2019 Brave New World TWO DAYS for 2005
10/280
Copyright 2000-2005 Steven Feuerstein - Page 10
System Global Area (SGA) of RDBMS
Instance
PL/SQL in Shared Memory
Shared Pool
Large Pool
Reserved Pool
show_empscalc_totals upd_salaries
Select *from emp
Shared SQL
Pre-parsedUpdate empSet sal=...
Library cache
Session 1 memory(PGA/UGA)
emp_rec emp%rowtype;tot_tab tottabtype;
Session 2 memory(PGA/UGA)
emp_rec emp%rowtype;tot_tab tottabtype;Session 1
Session 2
mysess.pkgSess2.sql
-
8/14/2019 Brave New World TWO DAYS for 2005
11/280
Copyright 2000-2005 Steven Feuerstein - Page 11
Code and Data in Shared Memory
PL/SQL is an interpretative language. The sourcecode is partially compiled into an intermediate form(p-code). The p-code is loaded into the shared pool when any
element of that code (package or stand-alone
program) is referenced. The partially-compiled code is shared among all
users who have EXECUTE authority on theprogram/package.
Each user (Oracle session) has its own copy of anydata structures defined within the program/package. Distinct sets of in-memory data (not shared among
different users) are stored in the PGA.
-
8/14/2019 Brave New World TWO DAYS for 2005
12/280
Copyright 2000-2005 Steven Feuerstein - Page 12
Overloading in packages:key usability technique
Overloading: two or more programs with thesame name, but different signature.You can overload in the declaration section
of any PL/SQL block, including the package
body (most common). Overloading is a critical feature when building
comprehensive programmatic interfaces(APIs) or components using packages.
If you want others to use your code, youneed to make that code as smart and aseasy to use as possible.
Overloading transfers the "need to know"from the user to the overloaded ro ram.
myproc
myfunc
myproc
Compare: DBMS_OUTPUT and p
-
8/14/2019 Brave New World TWO DAYS for 2005
13/280
Copyright 2000-2005 Steven Feuerstein - Page 13
How Overloading Works
For two or more modules to be overloaded,the compiler must be able to distinguishbetween the two calls at compile-time. Another name for overloading is "static
polymorphism."
There are two different "compile times":
1. When you compile the package or block
containing the overloaded code. 2. When you compile programs that use
the overloaded code.
-
8/14/2019 Brave New World TWO DAYS for 2005
14/280
Copyright 2000-2005 Steven Feuerstein - Page 14
How Overloading Works, continued
Distinguishing characteristics:The formal parameters of overloaded modules
must differ in number, order or datatype family(CHAR vs. VARCHAR2 is not different enough).
The programs are of different types: procedureand function.
Undistinguishing characteristics: Functions differ only in their RETURN datatype.
Arguments differ only in their mode (IN, OUT, INOUT).
Their formal parameters differ only in datatypeand the datatypes are in the same family.
-
8/14/2019 Brave New World TWO DAYS for 2005
15/280
Copyright 2000-2005 Steven Feuerstein - Page 15
Examples of Invalid Overloadings
PACKAGE too_similar
IS PROCEDURE calc (reg_in IN CHAR);PROCEDURE calc (reg_in IN VARCHAR2);
END too_many_cals;
PACKAGE only_returns
IS FUNCTION func1 (val IN VARCHAR2) RETURN DATE;FUNCTION func1 (val IN VARCHAR2) RETURN VARCHAR2;
END only_returns;
PACKAGE param_modes
ISPROCEDURE proc1 (val IN VARCHAR2);PROCEDURE proc1 (val IN OUT VARCHAR2);
END param_modes;
Parameter
data typescause conflict.
Only differenceis function
RETURN type.
Only differenceis parameter
mode.
too_similar.calc ('123');which one?
DBMS_OUTPUT.PUT_LINE (only_returns.func1 (v_value));which one?
param_modes.proc1 (v_value);which one?
-
8/14/2019 Brave New World TWO DAYS for 2005
16/280
Copyright 2000-2005 Steven Feuerstein - Page 16
Quiz! Nuances of Overloading
Is this a valid overloading? Will it compile? Howcan I use it?
CREATE OR REPLACE PACKAGE salesIS
PROCEDURE calc_total (zone_in IN VARCHAR2);
PROCEDURE calc_total (reg_in IN VARCHAR2);END sales;
BEGINsales.calc_total ('NORTHWEST');
sales.calc_total ('ZONE2');END;
sales.pkg
?
-
8/14/2019 Brave New World TWO DAYS for 2005
17/280
Copyright 2000-2005 Steven Feuerstein - Page 17
Package Data: Useful and Sticky
The scope of a package is your session, and anydata defined at the "package level" also hassession scope. If defined in the package specification, any
program can directly read/write the data.
Ideal for program-specific caching. General best practice: hide your package data in
the body so that you can control access to it. Use the SERIALLY_REUSABLE pragma to move
data to SGA and have memory released after eachusage.
thisuser.pkgthisuser.tstserial.sql
-
8/14/2019 Brave New World TWO DAYS for 2005
18/280
Copyright 2000-2005 Steven Feuerstein - Page 18
Package Initialization Structure
The initialization section:
Is defined after and outsideof any programs in thepackage.
Is not required. In fact, mostpackages you build won't
have one. Can have its own exception
handling section.
Useful for:
Performing complex settingof default or initial values.
Setting up package datawhich does not change forthe duration of a session.
PACKAGE BODY pkgIS
PROCEDURE proc ISBEGINEND;
FUNCTION func RETURNBEGINEND;
BEGIN...initialize...
END pkg;
BEGIN after/outsideof any program
defined in the pkg.init.pkginit.tst
datemgr.pkg
-
8/14/2019 Brave New World TWO DAYS for 2005
19/280
Copyright 2000-2005 Steven Feuerstein - Page 19
Packages vs. Stand-alone programs
General recommendation: use packagesinstead of stand-alone programs.
Better way to organize code.
Can hide implementation and reduce needto recompile programs using the package.
Other considerations....
Entire package loaded when any single
program is called. Central packages can become a
"bottleneck" when changes are needed.recompile.sql
-
8/14/2019 Brave New World TWO DAYS for 2005
20/280
-
8/14/2019 Brave New World TWO DAYS for 2005
21/280
Copyright 2000-2005 Steven Feuerstein - Page 21
PL/SQL Collections
Collections are single-dimensionedlistsof information, similar to 3GL arrays.
They are an invaluable data structure; allPL/SQL developers should be familiarwith them -- and use them a lot.
They take some getting used to,especially when you want to leverage the
latest features, such as multi-levelcollections.
array (15) array (15, 77)
-
8/14/2019 Brave New World TWO DAYS for 2005
22/280
Copyright 2000-2005 Steven Feuerstein - Page 22
Why Use Collections?
Maintain any kind of list of related information for usein your programs.
Emulate bi-directional cursors, which are not yet
supported in PL/SQL Cache data in program memory for faster access. Avoid mutating table errors in database triggers. Mirror complex data structures from database
directly in program data structures. Emulate multi-dimensional arrays in PL/SQL.
-
8/14/2019 Brave New World TWO DAYS for 2005
23/280
Copyright 2000-2005 Steven Feuerstein - Page 23
Three Types of Collections
Associative arrays - previously known as "index-bytables" (V8) and "PL/SQL tables" (V7) Available in PL/SQL only; preferred structures for
developers as they are the easiest to use.
Nested tables
Can be defined in PL/SQL and SQL. Use to store largeamounts of persistent data in the column of a table, usewith table functions.
Required for some features, such as table functions
Variable arrays Can be defined in PL/SQL and SQL; useful for definingsmall lists in columns of relational tables.
assoc_array_example.sqnested_table_example.sq
varray_example.sql
-
8/14/2019 Brave New World TWO DAYS for 2005
24/280
Copyright 2000-2005 Steven Feuerstein - Page 24
Getting to Know Collections
Defining collection types and collections Navigating collection contents
Manipulating collections inside SQL
New features in Oracle9i Multi-level collections
Indexing by strings
New features in Oracle10g Nested table operators
-
8/14/2019 Brave New World TWO DAYS for 2005
25/280
Copyright 2000-2005 Steven Feuerstein - Page 25
Defining Collections
First, you define the TYPE of the collection. For associative arrays, this can only occur in a PL/SQL
declaration section. Best option: package specification.
For nested tables and VARRAYs, you can define the TYPEin the database with a CREATE statement, or in a PL/SQLdeclaration section.
Then you declare one or more instances, actualcollections, from the TYPE..
CREATE OR REPLACE PACKAGE coll_typesIS
TYPE integer_aat IS TABLE OF INTEGER INDEX BY PLS_INTEGER;TYPE integer_nt IS TABLE OF INTEGER;TYPE integer_vat IS VARRAY(10) OF INTEGER;...
END coll_types;
-
8/14/2019 Brave New World TWO DAYS for 2005
26/280
Copyright 2000-2005 Steven Feuerstein - Page 26
Initializing Collections
Before you can use a collection, it must be initialized. Nested tables and VARRAYs are atomically null. You must
initialize them explicitly with a constructor. Associative arraysare initialized automatically.
DECLARETYPE numbers_t IS VARRAY (10) OF NUMBER;
salaries numbers_t := numbers_t (100, 200, 300);BEGIN
CREATE TYPE numbers_t IS VARRAY (10) OF NUMBER;/DECLARE -- Initialize the collection.
salaries numbers_t := numbers_t (100, 200, 300);
BEGIN
TYPE defined inthe database
TYPE defined in
PL/SQL
CREATE TABLE employee_denorm (employee_id INTEGER,salary_history numbers_t);
Collection usedin a table
b i i
-
8/14/2019 Brave New World TWO DAYS for 2005
27/280
Copyright 2000-2005 Steven Feuerstein - Page 27
More about Associative Arrays
They are unbounded, practically speaking. Valid row numbers range: -2,147,483,647 to2,147,483,647. You will not actually create tables thislarge; they will use up all available memory.
Instead, this range allows you to employ the row number
as an intelligent key, such as the primary key or uniqueindex value, because AAs are:
Sparse Data does not have to be stored in consecutive rows, as
is required in traditional 3GL arrays. Try to read a row that doesn't exist and Oracle
raises NO_DATA_FOUND. emplu.*
-
8/14/2019 Brave New World TWO DAYS for 2005
28/280
Copyright 2000-2005 Steven Feuerstein - Page 28
Wide Variety of Collection Methods
Obtain information about the collection
COUNT returns number of rows currently defined incollection.
EXISTS returns TRUE if the specified row is defined.
FIRST/LAST return lowest/highest numbers of defined rows.
NEXT/PRIOR return the closest defined row after/before thespecified row.
LIMIT tells you the max. number of elements allowed in aVARRAY.
Modify the contents of the collection
DELETE deletes one or more rows from the index-by table. EXTEND adds rows to a nested table or VARRAY.
TRIM removes rows from a VARRAY.
Th DELETE M th d
-
8/14/2019 Brave New World TWO DAYS for 2005
29/280
Copyright 2000-2005 Steven Feuerstein - Page 29
The DELETE Method
You can delete one or more rows from a collectionusing DELETE:
BEGIN-- Delete all rows
myCollection.DELETE;
-- Delete one (the last) rowmyCollection.DELETE (myCollection.LAST);
-- Delete a range of rows
myCollection.DELETE (1400, 17255);END;
DELETE releases memory, but you may also want to callDBMS_SESSION.FREE_UNUSED_USER_MEMORY.
h h C ll
-
8/14/2019 Brave New World TWO DAYS for 2005
30/280
Copyright 2000-2005 Steven Feuerstein - Page 30
Navigating Through Collections
Use FIRST and NEXT to move from beginning to end. Use LAST and PRIOR to move from end to beginning.
rowind PLS_INTEGER := birthdays.FIRST;-- REVERSE: birthdays.LAST
BEGINWHILE (rowind IS NOT NULL)LOOP
DBMS_OUTPUT.PUT_LINE (birthdays(rowind).best_present);
rowind := birthdays.NEXT (rowind);-- REVERSE: birthdays.PRIOR
END LOOP;END;
plsqlloops.spnotworking.sql
notworking_NT.sqlnotworking_VA.sql
U i C ll ti I id SQL
-
8/14/2019 Brave New World TWO DAYS for 2005
31/280
Copyright 2000-2005 Steven Feuerstein - Page 31
Using Collections Inside SQL
You can apply SQL operations to the contents ofnested tables and VARRAYs with these operators: CAST - Maps a collection of one type to a collection
of another type
MULTISET - Maps a database table to a collection
TABLE - Maps a collection to a database table
Index-by tables are programmatic constructs only. You cannot make a direct reference to an index-by
table in SQL.
Instead, do so indirectly with a PL/SQL function.
Using Collections inside SQL
-
8/14/2019 Brave New World TWO DAYS for 2005
32/280
Copyright 2000-2005 Steven Feuerstein - Page 32
Using Collections inside SQL
Lisa MarieGary Richard
BOND
BOLZ
Barbara Annedb_family
surname children
Max RichardEric Thomas
Lisa MarieGary RichardBarbara Annecolumn_value
SELECT column_valueFROM TABLE (SELECT children FROM db_family
WHERE surname = 'BOLZ');
UPDATE TABLE(SELECT children FROM db_family
WHERE SURNAME = 'BOLZ)SET column_value = 'Lisa Nadezhka' WHERE column_value = 'Lisa Marie');
Lisa NadezhkaGary RichardBarbara Anne
. . .
BOLZ
db_family
surname children
Using the TABLE and CAST Operators
-
8/14/2019 Brave New World TWO DAYS for 2005
33/280
Copyright 2000-2005 Steven Feuerstein - Page 33
Using the TABLE and CAST Operators
Use CAST to convert a collection from one type to another,
TABLE to convert a TYPE into a database table. Useful when you would like to apply SQL operations against
a PL/SQL collection (ie, one not stored in a database table).
DECLAREnyc_devolution cutbacks_for_taxcuts :=
cutbacks_for_taxcuts ('Stop rat extermination programs','Fire building inspectors','Close public hospitals');
BEGINDBMS_OUTPUT.PUT_LINE (
'How to Make the NYC Rich Much, Much Richer:');FOR rec IN (SELECT COLUMN_VALUE ohmy
FROMTABLE (CAST (nyc_devolutionAS cutbacks_for_taxcuts)))LOOP
DBMS_OUTPUT.PUT_LINE (rec.ohmy);END LOOP;
END;cast.sql
Using the MULTISET Operator
-
8/14/2019 Brave New World TWO DAYS for 2005
34/280
Copyright 2000-2005 Steven Feuerstein - Page 34
Using the MULTISET Operator
MULTISET is the inverse of TABLE, converting a set oftable, view, query) into a VARRAY or nested table. Use MULTISET to emulate or transform relational joins into
collections, with potential client-server performance impact.
DECLARECURSOR bird_curs IS
SELECT b.genus, b.species,CAST(MULTISET(SELECT bh.country FROM bird_habitats bh
WHERE bh.genus = b.genusAND bh.species = b.species)
AS country_tab_t)FROM birds b;
bird_row bird_curs%ROWTYPE;BEGIN
OPEN bird_curs;FETCH bird_curs into bird_row;
END;multiset.sql
Retrieves all detail
information for themaster in one trip.
Referencing Associative Arrays inside SQL
-
8/14/2019 Brave New World TWO DAYS for 2005
35/280
Copyright 2000-2005 Steven Feuerstein - Page 35
CREATE OR REPLACE PACKAGE ibtab ISFUNCTION rowval (indx IN PLS_INTEGER) RETURN DATE;PRAGMA RESTRICT_REFERENCES (rowval, WNPS, WNDS);
END;
CREATE OR REPLACE PACKAGE BODY ibtab ISTYPE date_tab IS TABLE OF DATE INDEX BY BINARY_INTEGER;hiredates date_tab;
FUNCTION rowval (indx IN PLS_INTEGER) RETURN DATEIS BEGIN
RETURN hiredates (indx);END;
END;
Referencing Associative Arrays inside SQL
You can't directly reference an index-by table'scontents inside SQL. Call functions that retrieve data from hidden array.
ibtab_in_sql.sql
Make accessiblein SQL forOracle8 and
below.
Putting Collections to Work
-
8/14/2019 Brave New World TWO DAYS for 2005
36/280
Copyright 2000-2005 Steven Feuerstein - Page 36
Putting Collections to Work
Let's take a closer look at some of the waysyou can use collections in PL/SQL programs.
Enhancing date-string conversion Bi-directional cursor emulation
Data caching
Mutating table error resolution
datemgr*.pkgdates.sql
bidir.*emplu.*
The Mutating Table Problem
-
8/14/2019 Brave New World TWO DAYS for 2005
37/280
Copyright 2000-2005 Steven Feuerstein - Page 37
The Mutating Table Problem
Row level triggers cannot query from orchange the contents of the table to which itis attached; it is "mutating".
So what are you supposed to do when arow-level operation needs to "touch" thattable?
UPDATE row 1
UPDATE row N
UPDATE emp SET sal = 1000
Database triggers can be associated with both the
DML statement as a whole and individual rowsaffected by that statement.
Note: in Oracle8i, youcan use autonomoustransactions to relax
restrictionsassociated with
queries.
mutating.sql
Statement level
Row level
A Solution Based on
-
8/14/2019 Brave New World TWO DAYS for 2005
38/280
Copyright 2000-2005 Steven Feuerstein - Page 38
Associative Arrays Tables
Since you cannot perform the processing desiredin the row-level trigger, you need to defertheaction until you get to the statement level.
If you are going to defer the work, you have toremember what you needed to do. an index-by table is an ideal repository for this
reminder list.
1st row trigger fires
Nth row trigger fires
Work List(PL/SQL Table)
Statement Trigger
Writes to list
Writes to list
Process datain the list.
An Example:R ki S l l
-
8/14/2019 Brave New World TWO DAYS for 2005
39/280
Copyright 2000-2005 Steven Feuerstein - Page 39
Ranking Salespeople
A table holds the rankings based on the amount of annual sales
of salespeople within a department. As the sales amount is updated in this table, the rankingsmust also change to show the new standings for thatdepartmentonly.
Salesperson ID Sales Amount RankDepartment ID
1055 64333 74055.88 3
1055 65709 144533.91
1055 65706 109000.25
1047 70904 65011.25
1
2
6
"Deferred work" is not only necessary, but preferable.
By storing the salespersons department ids as theychange, we then know which departments to re-rank.
We might update more than one department within astatement so we must be able to retain multipledepartment numbers.
T i L i R i d
-
8/14/2019 Brave New World TWO DAYS for 2005
40/280
Copyright 2000-2005 Steven Feuerstein - Page 40
Trigger Logic Required
CREATE OR REPLACE TRIGGER Rank_Sales_StrgAFTER INSERT OR UPDATE OR DELETEON rank_sales
BEGIN rank.rank_depts;END;
Statement Level Trigger
All details of theranking are hidden
in the package body.
CREATE OR REPLACE TRIGGER Rank_Sales_RtrgAFTER insert OR update OF sales_amtON rank_sales FOR EACH ROW
WHEN (OLD.sales_amt != NEW.sales_amt)BEGIN rank.add_dept (:new.dept_id);
END;
Row Level Trigger
Doesn't fire unlessthe sales_amtis actually changed.
ranking.pkg
The Ranking Package
-
8/14/2019 Brave New World TWO DAYS for 2005
41/280
Copyright 2000-2005 Steven Feuerstein - Page 41
The Ranking Package
PACKAGE rankIS
PROCEDURE add_dept (dept_id_in IN INTEGER);
PROCEDURE rank_depts;END rank;
PACKAGE BODY rankISin_process BOOLEAN := FALSE;
TYPE dept_tabtype IS TABLE OF BOOLEAN INDEX BY BINARY_INTEGER;dept_tab dept_tabtype;
PROCEDURE add_dept (dept_id_in IN INTEGER) ISBEGINIF NOT in_process
THENdept_tab (dept_id_in) := TRUE;
END IF;END add_dept
Table holds indicatorthat department
needs re-ranking.
Create row to indicatedepartment to be ranked.
The Ranking Package Continued
-
8/14/2019 Brave New World TWO DAYS for 2005
42/280
Copyright 2000-2005 Steven Feuerstein - Page 42
The Ranking Package, Continued
PROCEDURE rank_depts
ISv_deptid PLS_INTEGER := dept_tab.FIRST;BEGIN
IF NOT in_processTHENin_process := TRUE;LOOPEXIT WHEN v_deptid IS NULL;
perform_ranking (v_deptid);v_deptid := dept_tab.NEXT (v_deptid);
END LOOP;END IF;
in_process := FALSE;
dept_tab.DELETE;END rank_dept;
END rank;
Avoid recursiveexecution of logic
Row number isdepartment number.
Clean up fornext time.
Multi-level CollectionsOracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
43/280
Copyright 2000-2005 Steven Feuerstein - Page 43
Multi level Collections
Oracle9i allows you to create collections ofcollections, or collections of records thatcontain collections, or...
Applies to all three types of collections.
Two scenarios to be aware of:
Named collection columns
Anonymous collection columns
Collections with Named,M lti l l C ll ti
Oracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
44/280
Copyright 2000-2005 Steven Feuerstein - Page 44
Multi-level Collections
When a collection is based on a record orobject that in turn contains a collection, thatcollection has a name.
CREATE TYPE vet_visit_t IS OBJECT (visit_date DATE,reason VARCHAR2 (100));
/CREATE TYPE vet_visits_t IS TABLE OF vet_visit_t/CREATE TYPE pet_t IS OBJECT (
tag_no INTEGER,NAME VARCHAR2 (60),
petcare vet_visits_t,MEMBER FUNCTION set_tag_no (new_tag_no IN INTEGER)
RETURN pet_t);/
Continued...multilevel_collections.sql
Collection nested insideobject type
Collections with Named,M lti l l C ll ti ti d
Oracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
45/280
Copyright 2000-2005 Steven Feuerstein - Page 45
Multi-level Collections, continued
DECLARETYPE bunch_of_pets_t IS TABLE OF pet_t INDEX BY BINARY_INTEGER;my_pets bunch_of_pets_t;
BEGINmy_pets (1) :=
pet_t (
100, 'Mercury',vet_visits_t (
vet_visit_t ('01-Jan-2001', 'Clip wings'),
vet_visit_t ('01-Apr-2002', 'Check cholesterol')
)
);DBMS_OUTPUT.put_line (my_pets (1).petcare (2).reason);END;
Outer collection
Inner collection
Anonymous Collection ColumnsOracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
46/280
Copyright 2000-2005 Steven Feuerstein - Page 46
y
If your nested collections do not rely on "intermediate"
records or objects, you simply string together indexsubscripts. To demonstrate this syntax, let's take a look at how to
emulate a three-dimensional array using nestedcollections.
First, we cannot directly reference or populate anindividual cell, as one would do in a 3GL. Instead we have to build an interface between the
underlying arrays and the user of the "three
dimensional array."BEGINgps_info (1, 45, 605) :=
l_value;
BEGINgps_info (605) (45) (1) :=
l_value;
Can't do this... Have to do something like this instead...
Multi-dimensional array emulation
Oracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
47/280
Copyright 2000-2005 Steven Feuerstein - Page 47
y
CREATEORREPLACEPACKAGE multdimIS TYPE dim1_t ISTABLEOFVARCHAR2(32767)
INDEXBYBINARY_INTEGER;
TYPE dim2_t ISTABLEOF dim1_t INDEXBYBINARY_INTEGER;
TYPE dim3_t ISTABLEOF dim2_t INDEXBYBINARY_INTEGER;
PROCEDURE setcell (array_in INOUT dim3_t,dim1_in PLS_INTEGER,dim2_in PLS_INTEGER,dim3_in PLS_INTEGER,value_in IN VARCHAR2
);
FUNCTION getcell (
array_in IN dim3_t,dim1_in PLS_INTEGER,dim2_in PLS_INTEGER,dim3_in PLS_INTEGER
) RETURN VARCHAR2;END multdim;
multdim.*multdim2.*
gen_multcoll.sp
Three levels ofcollections
Set a cell value
Get a cell value
Multi-dimensional array emulation
Oracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
48/280
Copyright 2000-2005 Steven Feuerstein - Page 48
y
CREATEORREPLACEPACKAGEBODYmultdimIS PROCEDURE setcell (
array_in INOUT dim3_t,dim1_in PLS_INTEGER,dim2_in PLS_INTEGER,dim3_in PLS_INTEGER,value_in IN VARCHAR2
)IS BEGIN
array_in(dim3_in )(dim2_in )(dim1_in):= value_in; END;
FUNCTION getcell (array_in IN dim3_t,dim1_in PLS_INTEGER,dim2_in PLS_INTEGER,dim3_in PLS_INTEGER)
RETURNVARCHAR2 IS BEGIN RETURN array_in(dim3_in )(dim2_in )(dim1_in);
END;
multdim.*multdim2.*
gen_multcoll.sp
As close as youcan get...
-
8/14/2019 Brave New World TWO DAYS for 2005
49/280
Examples of NewTYPE Variants
Oracle9iRelease 2
-
8/14/2019 Brave New World TWO DAYS for 2005
50/280
Copyright 2000-2005 Steven Feuerstein - Page 50
TYPE Variants
All of the following are now valid TYPE declarations inOracle9i Release 2 You cannot use %TYPE against an INTEGER column,
because INTEGER is nota subtype of BINARY_INTEGER.
DECLARETYPE array_t1 IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;TYPE array_t2 IS TABLE OF NUMBER INDEX BY PLS_INTEGER;TYPE array_t3 IS TABLE OF NUMBER INDEX BY POSITIVE;TYPE array_t4 IS TABLE OF NUMBER INDEX BY NATURAL;TYPE array_t5 IS TABLE OF NUMBER INDEX BY VARCHAR2(64);TYPE array_t6 IS TABLE OF NUMBER INDEX BY VARCHAR2(32767);
TYPE array_t7 IS TABLE OF NUMBER INDEX BYemployee.last_name%TYPE;TYPE array_t8 IS TABLE OF NUMBER INDEX BY
types_pkg.subtype_t;
Working with VARCHAR2-IndexedCollections
Oracle9iRelease 2
-
8/14/2019 Brave New World TWO DAYS for 2005
51/280
Copyright 2000-2005 Steven Feuerstein - Page 51
Collections
Specifying a row via a string takes some gettingused to, but if offers some very powerful advantages.
DECLARE
TYPE population_type IS TABLE OF NUMBER INDEX BY VARCHAR2(64);
country_population population_type;continent_population population_type;
howmany NUMBER;BEGIN
country_population('Greenland') := 100000;country_population('Iceland') := 750000;
howmany := country_population('Greenland');
continent_population('Australia') := 30000000;END;
assoc_array*.sqlassoc_array_perf.tst
Rapid Access to DataVia String Keys
Oracle9iRelease 2
-
8/14/2019 Brave New World TWO DAYS for 2005
52/280
Copyright 2000-2005 Steven Feuerstein - Page 52
Via String Keys
One of the most powerful applications of this
features is to construct very fast pathways to staticdata from within PL/SQL programs. If you are repeatedly querying the same data from the
database, why not cache it in your PGA inside
collections? Emulate the various indexing mechanisms (primary
key, unique indexes) with collections.
Demonstration package:assoc_array5.sql
Comparison of performanceof different approaches:
vocab*.*
Generate a caching package:genaa.sql
The power of multi-level and string-based indexes
-
8/14/2019 Brave New World TWO DAYS for 2005
53/280
Copyright 2000-2005 Steven Feuerstein - Page 53
based indexes
Careful -- and creative! -- application of thisfunctionality can greatly simplify the code you need towrite to handle complex requirements.
Let's step through a demonstration of this capabilityusing Codecheck as an example.
overloadings
naming_conventionsbad_datatypes
CodecheckpackageCodecheck:
A QA package
for PL/SQL
The problem ofambiguous package overloadings
-
8/14/2019 Brave New World TWO DAYS for 2005
54/280
Copyright 2000-2005 Steven Feuerstein - Page 54
ambiguous package overloadings
Oddly and sadly, it is possible to compileoverloadings which are not usable.You see an obvious example below, but there are
many more subtle circumstances, usuallyinvolving defaulted parameters.
So I will build a program to identify such ambiguousoverloadings. But how can I do this?
BEGINsalespkg.calc_total ('ABC');
END;/
PACKAGE salespkgIS
PROCEDURE calc_total (dept_in IN VARCHAR2);
PROCEDURE calc_total (dept_in IN CHAR);
END salespkg; ?
ALL_ARGUMENTS to the rescue!
-
8/14/2019 Brave New World TWO DAYS for 2005
55/280
Copyright 2000-2005 Steven Feuerstein - Page 55
Parsing is too complicated for me, but theALL_ARGUMENTS data dictionary viewcontains information about all the argumentsof all the procedures and functions to which Ihave access. That sounds pretty good!
As usual, Oracle offers us a whole lot ofpleasure, mixed with a little bit of pain.The organization of data in
ALL_ARGUMENTS is a bit bizarre, plus it isincomplete, necessitating the use also ofDBMS_DESCRIBE.DESCRIBE_COLUMNS.
First Inclination:Same Old, Same Old
-
8/14/2019 Brave New World TWO DAYS for 2005
56/280
Copyright 2000-2005 Steven Feuerstein - Page 56
Same Old, Same Old
All right then, I will grab all the information from
ALL_ARGUMENTS and dump it into a collectionbased on that view! Very easy...
CREATE OR REPLACE PROCEDURE get_all_arguments (package_in IN VARCHAR2)
ISTYPE all_arguments_tt IS TABLE OF all_arguments%ROWTYPE
INDEX BY BINARY_INTEGER;l_arguments all_arguments_tt;
BEGINFOR rec IN (SELECT * FROM all_argumentsWHERE owner = USER AND package_name = package_in)
LOOPl_arguments (SQL%ROWCOUNT) := rec;
END LOOP;END;
Load it up!
Emulate theview.
Then what? Write lots of code tointerpret the contents...
-
8/14/2019 Brave New World TWO DAYS for 2005
57/280
Copyright 2000-2005 Steven Feuerstein - Page 57
interpret the contents...
Which programs are overloaded? Wheredoes one overloading end and another start?
l_last_program all_arguments.object_name%TYPE;l_is_new_program BOOLEAN :=FALSE;l_last_overload PLS_INTEGER :=-1;
BEGIN
FORindx IN l_arguments.FIRST ..l_arguments.LAST
LOOP IF l_arguments (indx).object_name !=
l_last_program ORl_last_programISNULL THEN
l_last_program:=
l_arguments (indx).object_name;l_is_new_program:=TRUE;do_new_program_stuff;
ENDIF;...
IF l_arguments (indx).overload!= l_last_overload
ORl_last_overload=-1 THEN IF l_is_new_program THEN
do_first_overloading_stuff; ELSE
do_new_overloading_stuff; ENDIF;
ENDIF; ENDLOOP;END;
Discovery: there is a natural hierarchyto ALL ARGUMENTS data!
-
8/14/2019 Brave New World TWO DAYS for 2005
58/280
Copyright 2000-2005 Steven Feuerstein - Page 58
to ALL_ARGUMENTS data!
Each program has zero ormore overloadings, eachoverloading has Narguments, and eachargument can havemultiple "breakouts" (my
term - applies to non-scalar parameters, such asrecords or object types).
RUN_TEST
SHOW_RESULTS
RESET_FLAGS
Program name
Overloading 1
Overloading 2
Overloading
Argument 1
Argument 2
Argument 3
Argument 4
Argument 5
ArgumentBreakout 1
Breakout 1
Breakout 2
Breakout 3
Breakout
What if I reflect this hierarchy ina collection of collections?
-
8/14/2019 Brave New World TWO DAYS for 2005
59/280
Copyright 2000-2005 Steven Feuerstein - Page 59
Have to build from the bottom up:TYPE breakouts_t IS TABLE OF all_arguments%ROWTYPE
INDEX BY BINARY_INTEGER;
TYPE arguments_t IS TABLE OF breakouts_t
INDEX BY BINARY_INTEGER;
TYPE overloadings_t IS TABLE OF arguments_tINDEX BY BINARY_INTEGER;
TYPE programs_t IS TABLE OF overloadings_tINDEX BY all_arguments.object_name%type;
1. Set of rows fromALL_ARGUMENTS
String-based index
2. All the "breakout" info
for a single argument
3. All the argument infofor a single overloading
4. All the overloadings fora distinct program name
Then I can populate it very easily
-
8/14/2019 Brave New World TWO DAYS for 2005
60/280
Copyright 2000-2005 Steven Feuerstein - Page 60
Assigning a single record to the "lowest" level alsodefines each of the upper levels. Notice the automatic "SELECT DISTINCT" on program
name that results!
FOR rec IN (SELECT * FROM all_arguments)LOOPl_arguments (NVL (l_arguments.LAST,0)+1)
:= rec;
l_programs (rec.object_name) (NVL (rec.overload,0)) (rec.position) (rec.data_level):= rec;ENDLOOP;
I can still do thetypical sequential
load.
But I will now also
add the multi-levelload in singleassignment
A closer look at the multi-levelassignment
-
8/14/2019 Brave New World TWO DAYS for 2005
61/280
Copyright 2000-2005 Steven Feuerstein - Page 61
g
g_programs(c_program)
(c_overload).PARAMETERS
(c_position).toplevel
all programs in packagedistinct program name in package
Nth overloading for program (record)
field containing all parameters for overloading
:= g_all_arguments (argindx_in);
Nth parameter in the program's parameter list
field containing a single row fromALL_ARGUMENTS (more or less) with the
top-level parameter information
the record that isassigned as the top-
level parameter
And then I can "query" the contentswith a minimum of code
-
8/14/2019 Brave New World TWO DAYS for 2005
62/280
Copyright 2000-2005 Steven Feuerstein - Page 62
l_programs ('TOP_SALES') (2).EXISTS (0)
Is the TOP_SALES
program overloaded?
l_programs ('TOP_SALES') (2)(0)(0).datatype
l_programs ('TOP_SALES').COUNT > 1
Is the 2nd overloadingof TOP_SALES a
function?
What is the datatypeof the RETURN clauseof the 2nd overloading
of TOP_SALES?
And, of course, I know the beginning and end points ofeach program, overloading, and argument. I just use the
FIRST and LAST methods on those collections!
Some best practices for these complexstructures
-
8/14/2019 Brave New World TWO DAYS for 2005
63/280
Copyright 2000-2005 Steven Feuerstein - Page 63
As you can see, you can easily and rapidlyarrive at completely unreadable and un-maintainable code.
What' s a developer to do?
Hide complexity -- and all data structures --behind small modules.
Functions to retrieve contents andprocedures to set contents.
cc_smartargs.pkb:cc_smartargs.next_overloading
cc_smartargs.add_new_parameter
Nested Tables unveil theirMULTISET-edness
Oracle10g
-
8/14/2019 Brave New World TWO DAYS for 2005
64/280
Copyright 2000-2005 Steven Feuerstein - Page 64
Oracle10g introduces high-level setoperations on nested tables (only).
Nested tables are multisets, meaningthat theoretically there is no order to their
elements. This makes set operations ofcritical importance for manipulatingnested tables. .
You can now
Check for equality and inequality
Obtain UNION, INTERSECT and MINUS oftwo NTs
Check for equality and inequalityOracle10g
-
8/14/2019 Brave New World TWO DAYS for 2005
65/280
Copyright 2000-2005 Steven Feuerstein - Page 65
Just use the basic operators.DECLARE
TYPE clientele IS TABLE OF VARCHAR2 (64);group1 clientele := clientele ('Customer 1', 'Customer 2');group2 clientele := clientele ('Customer 1', 'Customer 3');group3 clientele := clientele ('Customer 3', 'Customer 1');
BEGINIF 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 THENDBMS_OUTPUT.put_line ('Group 2 != Group 3');
ELSEDBMS_OUTPUT.put_line ('Group 2 = Group 3');
END IF;END; 10g_compare.sql
10g_compare_old.sql
UNION, INTERSECT, MINUSOracle10g
-
8/14/2019 Brave New World TWO DAYS for 2005
66/280
Copyright 2000-2005 Steven Feuerstein - Page 66
Straightforward, with the MULTISET keyword.BEGIN
our_favorites := my_favorites MULTISET UNION dad_favorites;show_favorites ('MINE then DAD', our_favorites);
our_favorites := dad_favorites MULTISET UNION my_favorites;show_favorites ('DAD then MINE', our_favorites);
our_favorites := my_favorites MULTISET UNION DISTINCT dad_favorites;show_favorites ('MINE then DAD with DISTINCT', our_favorites);
our_favorites := my_favorites MULTISET INTERSECT dad_favorites;show_favorites ('IN COMMON', our_favorites);
our_favorites := dad_favorites MULTISET EXCEPT my_favorites;show_favorites ('ONLY DAD''S', our_favorites);
END;10g_setops.sql
10g_string_nt.sql10g_favorites.sql10g*union*.sql
Distinct sets of valuesOracle10g
-
8/14/2019 Brave New World TWO DAYS for 2005
67/280
Copyright 2000-2005 Steven Feuerstein - Page 67
Use the SET operator to work with distinct values, and
determine ifyou have a set of distinct values.DECLARE
keep_it_simple strings_nt := strings_nt ();BEGIN
keep_it_simple := SET (favorites_pkg.my_favorites);
favorites_pkg.show_favorites ('FULL SET', favorites_pkg.my_favorites);
p.l (favorites_pkg.my_favorites IS A SET, 'My favorites distinct?');p.l (favorites_pkg.my_favorites IS NOT A SET, 'My favorites NOT distinct?');
favorites_pkg.show_favorites ('DISTINCT SET', keep_it_simple);
p.l (keep_it_simple IS A SET, 'Keep_it_simple distinct?');
p.l (keep_it_simple IS NOT A SET, 'Keep_it_simple NOT distinct?');
END;
10g_set.sql10g_favorites.pkg
Determining subsets of dataOracle10g
-
8/14/2019 Brave New World TWO DAYS for 2005
68/280
Copyright 2000-2005 Steven Feuerstein - Page 68
Use the SUBMULTISET operator to determine if a
nested table contains only elements that are inanother nested table.
BEGINp.l (favorites_pkg.my_favorites
SUBMULTISET OF favorites_pkg.eli_favorites, 'Father follows son?');
p.l (favorites_pkg.eli_favoritesSUBMULTISET OF favorites_pkg.my_favorites
, 'Son follows father?');
p.l (favorites_pkg.my_favoritesNOT SUBMULTISET OF favorites_pkg.eli_favorites
, 'Father doesn''t follow son?');
p.l (favorites_pkg.eli_favoritesNOT SUBMULTISET OF favorites_pkg.my_favorites
, 'Son doesn''t follow father?');END; 10g_submultiset.sql
10g_favorites.pkg
The Wonderful World ofOracle Object Types
-
8/14/2019 Brave New World TWO DAYS for 2005
69/280
Copyright 2000-2005 Steven Feuerstein - Page 69
A New Frontier:
Object Types andObject-oriented Development
in PL/SQL
Which best describes yourrelationship with Object Types?
-
8/14/2019 Brave New World TWO DAYS for 2005
70/280
Copyright 2000-2005 Steven Feuerstein - Page 70
I love 'em and use 'em all the time.
They scare me. I'll stick with good, old-fashioned relational tables.
I am comfortable with defining and using
object types, but not in production.
We use object types and haveincorporated them into our production
applications.
Object Types in Oracle
-
8/14/2019 Brave New World TWO DAYS for 2005
71/280
Copyright 2000-2005 Steven Feuerstein - Page 71
Object types were first introduced into the
Oracle8 RDBMS (the "object-relational" model). Oracle uses object types in many of its new features
(e.g., Oracle AQ, the XML datatype).
Few development shops work with object types.
The implementation is weak. Not really object oriented.
Advantages are not persuasive to developers andDBAs with relational and procedural backgrounds.
Oracle9i support for inheritance may well change thissituation..
Some Terminology
-
8/14/2019 Brave New World TWO DAYS for 2005
72/280
Copyright 2000-2005 Steven Feuerstein - Page 72
Object type - Oracle's version of a class; a structure that
combines data with programs (a blend of a table and apackage).
Object type instance - Oracle's version of an object
Attribute - a characteristic or "column" of the object type.
Method - a program that manipulate an object type instance. Supertype - a type that is closer in the hierarchy to the root
Subtype - a type that has a supertype.
Inheritance - the ability of a subtype to inherit attributes and
methods from a supertype. Overriding - replacing functionality of a supertype with new
functionality in a subtype.
A Very Simple Object Type Example
-
8/14/2019 Brave New World TWO DAYS for 2005
73/280
Copyright 2000-2005 Steven Feuerstein - Page 73
The food type contains three attributes and nomethods or programs.
It is very similar to a CREATE TABLE statement,but it does not create a "container" for data. Rather
it is a "template" for data or instances.
CREATE TYPE food_tAS OBJECT (
nameVARCHAR2(100),food_group VARCHAR2(100),grown_in VARCHAR2(100)
);
Attributes
Working with Simple Objects
-
8/14/2019 Brave New World TWO DAYS for 2005
74/280
Copyright 2000-2005 Steven Feuerstein - Page 74
DECLARE
my_favorite_vegetable food_t := food_t ('Brussel Sprouts',
'VEGETABLE','Farm,Greenhouse,Backyard');
BEGINDBMS_OUTPUT.put_line (
my_favorite_vegetable.name);
my_favorite_vegetable.food_group :='SATISFACTION';
IF INSTR (my_favorite_vegetable.grown_in,'yard')>0
THENorder_seeds (my_favorite_vegetable);
ENDIF;END;
Create a newobject with aconstructor.
Read an attributevalue
Modify anattribute value
Pass an objectas a parameter
objtype.sql
Another Object Type Example
-
8/14/2019 Brave New World TWO DAYS for 2005
75/280
Copyright 2000-2005 Steven Feuerstein - Page 75
The timer objectcalculateselapsed time.
It consists of four
attributes andfive methods.
CREATETYPE tmr_tAS OBJECT (
startTime INTEGER,endTime INTEGER,repetitions INTEGER,nameVARCHAR2(2000),
MEMBERPROCEDUREgo,
MEMBERPROCEDUREstop( show_timing INBOOLEAN:=TRUE),MEMBERFUNCTION timing RETURNINTEGER,MEMBERPROCEDURE reset (
name INVARCHAR2:=NULL),STATIC FUNCTION make (
name INVARCHAR2,
repetitions ININTEGER:=1) RETURN tmr_t);
Attributes
Methods
tmr.ot
About Constructor Functions
-
8/14/2019 Brave New World TWO DAYS for 2005
76/280
Copyright 2000-2005 Steven Feuerstein - Page 76
Each object type
comes with its ownconstructor function.You must supply a
value for eachattribute.
Oracle9i Release 2allows you designuser-definedconstructors, so you
can hide attributesand performadditional init. tasks.
CREATETYPE tmr_tASOBJECT(...
CONSTRUCTORFUNCTION tmr_t (SELF INOUT tmr_t,name INVARCHAR2,
repetitions ININTEGER ) RETURN SELFAS RESULT);CREATEORREPLACETYPEBODY tmr_t
ASCONSTRUCTORFUNCTION tmr_t (
SELF INOUT tmr_t,name INVARCHAR2,
repetitions ININTEGER ) RETURN SELFAS RESULT IS BEGIN
SELf.repetitions := repetitions;SELF.name := name;
RETURN; END;END;
Oracle9iRelease 2
Using the Timer Object
-
8/14/2019 Brave New World TWO DAYS for 2005
77/280
Copyright 2000-2005 Steven Feuerstein - Page 77
DECLAREonce_tmr tmr_t :=NEWtmr_t (
NULL,NULL, 10000, 'Packaged Function');
myonce_tmr tmr_t := tmr_t.make ( 'Packaged Constant',10000);
every_tmr tmr_t :=NEWtmr_t ( 'USER Function', 10000);
BEGINonce_tmr.go ();
FORindx IN1.. count_in LOOP
v:=thisuser.name;
ENDLOOP;once_tmr.stop ();
Declare timer with
default constructor
Invoke object typemethods using dot
notation.
thisuser.tst
Declare timer with"pseudo-constructor"
Declare timer with user-defined constructor
Support for inheritance in object typesOracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
78/280
Copyright 2000-2005 Steven Feuerstein - Page 78
You can now define a hierarchy of subtypes ofobject types.
A subtype contains all the attributes andmethods of the parent type (or supertype).
The subtypes can also contain additionalattributes and additional methods, and canoverride methods from the supertype.
You decide if an object type is INSTANTIABLE
or is FINAL (cannot be extended to a subtype).
Type Hierarchy ExampleOracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
79/280
Copyright 2000-2005 Steven Feuerstein - Page 79
An employee is one sort of person. An hourlyworker is one sort of employee. An employee isalways a person, but a person may not be anemployee.
Person
Citizen
Corporation
Employee
supertype/"wider" subtype/"narrower"
Hourly Worker
SalariedWorker
Management
Non-Management
"root" type
person.ot
Why Bother with Hierarchy?
-
8/14/2019 Brave New World TWO DAYS for 2005
80/280
Copyright 2000-2005 Steven Feuerstein - Page 80
Define shared functionality once at the"widest" level and it is automatically availableat all narrower points in the hierarchy.
A very powerful approach to code reuse.
Easily customize or override functionality forspecific subtypes.
You get the best of both worlds: rely on the
supertype-standard, and selectively over-ride thatfunctionality as needed.
Let's Build a Type HierarchyOracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
81/280
Copyright 2000-2005 Steven Feuerstein - Page 81
We have a three levelhierarchy: food is the root type.
desserts are a type of food
cakes are a type of dessert. We will make cake the most
specialized type of foodallowed in the hierarchy.
food
dessert
cake
"root",supertypeof dessert
subtype offood,supertypeof cake
subtypeof dessert
food.ot
Creating a SimpleObject Type Hierarchy
-
8/14/2019 Brave New World TWO DAYS for 2005
82/280
Copyright 2000-2005 Steven Feuerstein - Page 82
CREATE TYPE food_t AS OBJECT (name VARCHAR2(100),food_group VARCHAR2 (100),grown_in VARCHAR2 (100))
NOT FINAL;
CREATE TYPE dessert_t UNDERfood_t (contains_chocolate CHAR(1),year_created NUMBER(4))
NOT FINAL;
CREATE TYPE cake_t UNDERdessert_t (diameter NUMBER,inscription VARCHAR2(200));
NOT FINAL
indicates that thistype can be asupertype.
UNDER denotesthat this type is asubtype.
An object instantiated from food_t has three attributes. A dessertobject has five attributes. A cake has seven.
food.ot
Substitutability ofObject Types
-
8/14/2019 Brave New World TWO DAYS for 2005
83/280
Copyright 2000-2005 Steven Feuerstein - Page 83
A supertype is substitutable if one of itssubtypes can substitute or stand in for it ina slot (a variable, column, etc.) whosedeclared type is the supertype.
Oracle supports object type substitution in
columns of relational tables, attributes ofobject types and elements in collections.
"Any object of type cake is also a dessert,
is also a food."
Populate an Object Table
-
8/14/2019 Brave New World TWO DAYS for 2005
84/280
Copyright 2000-2005 Steven Feuerstein - Page 84
Create a table of objects of type food (root type).
Populate it with objects at different levels in hierarchy.DECLARE
my_favorite_vegetables food_t :=food_t ('Brussel Sprouts','VEGETABLE','farm');
BEGIN INSERTINTOsustenanceVALUES(my_favorite_vegetables);
INSERTINTOsustenanceVALUES(dessert_t ('Jello','PROTEIN','bowl','N',1887));
INSERTINTOsustenance
VALUES(cake_t ( 'Marzepan Delight','CARBOHYDRATE','bakery', 'N',1634,8,'Happy Birthday!'));END;
CREATETABLEsustenanceOF food_t;
Substitution of subtypes
Use of constructor toinitialize a variable
food.ot
Objects in a Collection
-
8/14/2019 Brave New World TWO DAYS for 2005
85/280
Copyright 2000-2005 Steven Feuerstein - Page 85
Create a table of objects of type food (root type).
DECLARETYPE foodstuffs_nt ISTABLEOF food_t;
fridge_contents foodstuffs_nt := foodstuffs_nt (
food_t ('Eggs benedict','PROTEIN','Farm'),dessert_t ('Strawberries and cream','FRUIT','Backyard','N',2001),
cake_t ( 'Chocolate Supreme', 'CARBOHYDATE', 'Kitchen', 'Y',2001,8, 'Happy Birthday, Veva' )
);BEGIN...
Insert three different
objects in the collection,each of a different type.
Declare a nestedtable
Accessing Attributes in SubstitutedTypes
-
8/14/2019 Brave New World TWO DAYS for 2005
86/280
Copyright 2000-2005 Steven Feuerstein - Page 86
You can substitute a subtype in a supertype
column or attribute, but subtype-specific attributesand methods are by default not visible.
SQL> DECLARE4 mmm_good food_t :=
5 dessert_t ('Super Brownie', 'CARBOHYDRATE',6 'my oven', 'Y', 1994);7 BEGIN8 DBMS_OUTPUT.PUT_LINE (mmm_good.contains_chocolate);9 END;10 /DBMS_OUTPUT.PUT_LINE (mmm_good.contains_chocolate);
*ERROR at line 8:PLS-00302: component 'CONTAINS_CHOCOLATE' must be declared
Converting Between Types
-
8/14/2019 Brave New World TWO DAYS for 2005
87/280
Copyright 2000-2005 Steven Feuerstein - Page 87
Use the TREAT operator to "treat" or convert
a wider type into a narrower subtype:
CREATE TABLE books (title VARCHAR2(30),author Person_ot /* substitutable */);
BEGININSERT INTO books
VALUES ('Oracle PL/SQL Programming',citizen_ot ('HUMAN','Steven Feuerstein',
180, '23-SEP-1958', 'USA', 'Independent'
));
END;/SELECT author.nation FROM Books; -- WILL NOT WORK!
SELECT TREAT(author AS citizen_ot).nation FROM Books; - WORKS!
treat2.sql
Use TREAT to Identify ConstrainedTypes
-
8/14/2019 Brave New World TWO DAYS for 2005
88/280
Copyright 2000-2005 Steven Feuerstein - Page 88
/* Show all the meals in which a main course is a dessert */SELECT*
FROMmealWHERE TREAT (main_courseAS dessert_t)ISNOTNULL;
/* Will fail, since main_course is of food_t type */SELECT main_course.contains_chocolate
FROMmealWHERE TREAT (main_courseAS dessert_t)ISNOTNULL;
/* Now works, since I am treating main_course as a dessert */SELECT TREAT (main_courseAS dessert_t).contains_chocolate FROMmealWHERE TREAT (main_courseAS dessert_t)ISNOTNULL;
/* Set to NULL any desserts that are not cakes... */UPDATE meal SET dessert = TREAT (dessertAS cake_t);
treat.sql
Example: NOT SUBSTITUTABLE
-
8/14/2019 Brave New World TWO DAYS for 2005
89/280
Copyright 2000-2005 Steven Feuerstein - Page 89
The appetizer must be of type food_t;
desserts are not acceptable.SQL> BEGIN2 INSERT INTO meal VALUES (3 SYSDATE + 1,4 dessert_t ('Strawberries and cream',
5 'FRUIT', 'Backyard', 'N', 2001),6 food_t ('Eggs benedict', 'PROTEIN', 'Farm'),7 cake_t ('Apple Pie', 'FRUIT',8 'Baker''s Square', 'N', 2001, 8, NULL));9 END;10 /
BEGIN*ERROR at line 1:ORA-00932: inconsistent datatypes
notsubst.sql
Constraining Substitutability toa Specific Type
-
8/14/2019 Brave New World TWO DAYS for 2005
90/280
Copyright 2000-2005 Steven Feuerstein - Page 90
Suppose I want a column of desserts tocontain only cakes?
CREATE TABLE meal (
served_on DATE,
appetizer food_t,
main_course food_t,
dessert dessert_t
)
COLUMN appetizer NOT SUBSTITUTABLE AT ALL LEVELS,
COLUMN dessert IS OF (ONLY cake_t)
;
Unconstrainednon-substitutability
Constrain to asingle subtype
notsubst.sqlYou can only constrain to asingle type, not a list of types.
Turning Off Substitutability
-
8/14/2019 Brave New World TWO DAYS for 2005
91/280
Copyright 2000-2005 Steven Feuerstein - Page 91
Oracle provides syntax to turn off substitutability on
either an entire type or specific attributes of a type.
CREATE TABLE brunches OF food_tNOT SUBSTITUTABLE AT ALL LEVELS;
CREATE TABLE meal (served_on DATE,appetizer food_t,main_course food_t,dessert dessert_t)
COLUMN appetizer NOT SUBSTITUTABLE AT ALL LEVELS;
At the table level
For a single column
Creating "Template" Types
-
8/14/2019 Brave New World TWO DAYS for 2005
92/280
Copyright 2000-2005 Steven Feuerstein - Page 92
Some object types should only be used assupertypes for other types; they are so general, youwould not actually create and manipulate instancesfrom those types.
Oracle allows you to define object types as NOTINSTANTIABLE, as shown above.
CREATE TYPE Address_t ASOBJECT (
street VARCHAR2(1000),city VARCHAR2(30),...
)NOT INSTANTIABLENOT FINAL;
Creating and Overriding Methods
-
8/14/2019 Brave New World TWO DAYS for 2005
93/280
Copyright 2000-2005 Steven Feuerstein - Page 93
Most real-world object types will have bothattributes and methods, programs thatperform operations on attributes.
With inheritance, you can:
inherit supertype methods override or replace supertype methods with
subtype implementations
add completely new methods
Overriding to Provide Specificity forSubtypes
CREATE OR REPLACE TYPE BODY dessert t
-
8/14/2019 Brave New World TWO DAYS for 2005
94/280
Copyright 2000-2005 Steven Feuerstein - Page 94
Different
calculations fordesserts andcakes.
CREATE OR REPLACE TYPE BODY cake_tIS
OVERRIDING MEMBERFUNCTION price RETURN NUMBERISBEGIN
RETURN (5.00
+ 0.25 * (LENGTH (SELF.inscription))+ 0.50 * diameter);END;
END;
Generic dessert prices aredetermined by chocolate
content and age. Cake prices
are driven by inscriptionlength and size..
food2.ot
CREATE OR REPLACE TYPE BODY dessert_tIS
OVERRIDING MEMBERFUNCTION price RETURN NUMBER ISmult NUMBER := 1;
BEGINIF SELF.contains_chocolate = 'Y'
THEN mult := 2; END IF;IF SELF.year_created < 1900
THEN mult := mult + 0.5; END IF;RETURN (10.00 * mult );
END;END;
Disallowing Overrides
-
8/14/2019 Brave New World TWO DAYS for 2005
95/280
Copyright 2000-2005 Steven Feuerstein - Page 95
If you do not want a subtype to modify thebehavior of a supertype method, declare it tobe FINAL. You can do this even in object types that are
NOT FINAL.
CREATE TYPE Person_t ASOBJECT (
ssn NUMBER,name VARCHAR2(30),address VARCHAR2(100),
FINAL MEMBER PROCEDURE showInfo)NOT FINAL;
Requiring Overrides to Methods
CREATE TYPE food t AS OBJECT ( food2.ot
-
8/14/2019 Brave New World TWO DAYS for 2005
96/280
Copyright 2000-2005 Steven Feuerstein - Page 96
Suppose the implementation of a method changes witheach subtype in the hierarchy andthe supertype'simplementation really is irrelevant.
Declare the method to be NOT INSTANTIABLE and then
(a) you do not have to provide an implementation of themethod and (b) all subtypes mustprovide animplementation.
_ (name VARCHAR2(100),
food_group VARCHAR2 (100),grown_in VARCHAR2 (100),NOT INSTANTIABLE MEMBER
FUNCTION price RETURN NUMBER)NOT FINAL
NOT INSTANTIABLE;
If any member is NOTINSTANTIABLE, then the
entire type must bedeclared the same way.
food2.ot
Quiz: What is "Dynamic Polymorphism"?
A new kind of diet regimen
-
8/14/2019 Brave New World TWO DAYS for 2005
97/280
Copyright 2000-2005 Steven Feuerstein - Page 97
A new kind of diet regimen.
A form of sex therapy practiced inLuxembourg.
A computer language's ability to anticipatethe requirements of a system and generatematching code.
A computer language's ability to choose atrun-time among different forms of the same
program.
About Polymorphism
-
8/14/2019 Brave New World TWO DAYS for 2005
98/280
Copyright 2000-2005 Steven Feuerstein - Page 98
The ability to choose from multiple methods of thesame name and execute the appropriate method. Static polymorphism: the decision about which method to
execute is made at the time the code is compiled. Staticpolymorphism is also known as overloading, and is
supported in declaration sections of PL/SQL blocks. Dynamic polymorphism: the decision about which method to
execute is made at the time the code is executed, at run-time. This is also known as "dynamic method dispatch", andis available for the first time in PL/SQL with support forobject type inheritance.
Exploring Dynamic Polymorphism
-
8/14/2019 Brave New World TWO DAYS for 2005
99/280
Copyright 2000-2005 Steven Feuerstein - Page 99
CREATETYPE food_tAS OBJECT(
...attributes...MEMBERFUNCTION price RETURNNUMBER)NOT FINAL;
CREATETYPE dessert_t UNDERfood_t ( ...attributes...
OVERRIDING MEMBERFUNCTION priceRETURNNUMBER
)NOT FINAL) ;CREATETYPE cake_t UNDERdessert_t ( ...attributes... -- No price method of its own.
);
The food anddessert typeseach have a pricemethod, but cake
does not. It simply inherits
the dessertmethod.
A Visual Representation
The root price
-
8/14/2019 Brave New World TWO DAYS for 2005
100/280
Copyright 2000-2005 Steven Feuerstein - Page 100
The root price
function is over-ridden in thedessert subtype.
The cake
subtype nowsimply inheritsits pricecalculation from
its dessertsupertype.
food
dessert
cake
Price
Price
the "original"
An override
Inherited
calculation
Dynamically Choosingthe Right Method
DECLARE
-
8/14/2019 Brave New World TWO DAYS for 2005
101/280
Copyright 2000-2005 Steven Feuerstein - Page 101
DECLARETYPE foodstuffs_nt IS TABLE OF food_t;
fridge foodstuffs_nt:= foodstuffs_nt (
food_t ('Eggs benedict', ...), dessert_t ('Strawberries and cream', ...), cake_t ('Chocolate Supreme', ...));BEGIN
FOR indx INfridge.FIRST ..fridge.LAST
LOOPDBMS_OUTPUT.put_line (
'Price of ' || fridge (indx).NAME ||' = ' ||
fridge (indx).price);END LOOP;
END;
A collection of foods ispopulated with threedifferent object types.
The price invocation isresolved at run-time, andnot necessarily as thefood_t.price method.
food3.ot
food4.otdynpoly_overhead.tst
Object Types Summary
They are finally becoming robust enough to
-
8/14/2019 Brave New World TWO DAYS for 2005
102/280
Copyright 2000-2005 Steven Feuerstein - Page 102
They are finally becoming robust enough to
be useful Object types are being used extensively by
Oracle itself.
This fact makes more confident of the future,performance and capabilities of object types.
Get familiar with the syntax so that you canwork with object types with confidence.
New and Enhanced Datatypes inOracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
103/280
Copyright 2000-2005 Steven Feuerstein - Page 103
TIMESTAMP and INTERVAL XMLType
The ANY* "generic" types
Timestamps & Intervals
TIMESTAMP
-
8/14/2019 Brave New World TWO DAYS for 2005
104/280
Copyright 2000-2005 Steven Feuerstein - Page 104
TIMESTAMP
Extends the DATE datatype, offering a muchhigher (and variable) precision of seconds.
INTERVAL Store and manipulate intervals of years and
months. DAY TO SECOND: represent the precise
difference between two datetime values.
YEAR TO MONTH: calculate the difference
between two datetime values, where the onlysignificant portions are the year and month.
Timestamp Precision
DECLARE
-
8/14/2019 Brave New World TWO DAYS for 2005
105/280
Copyright 2000-2005 Steven Feuerstein - Page 105
When you declare a TIMESTAMP, you
provide a precision (from 0 to 9) for theseconds component of the value.
Use TIMESTAMP WITH TIME ZONE to
handle time zone displacement.
checkout TIMESTAMP(3);
BEGINcheckout := '1999-06-22 07:48:53.275';
...
END;
Working with Time Zones
DECLARE
logoff TIMESTAMP(3) WITH TIME ZONE;
logon TIMESTAMP(3) WITH LOCAL TIME ZONE;
-
8/14/2019 Brave New World TWO DAYS for 2005
106/280
Copyright 2000-2005 Steven Feuerstein - Page 106
Automatically work with the local time zone or specify aspecific displacement.
Useful when gathering data that crosses time zones.
The TIMEZONE_REGION and TIMEZONE_ABBRcolumns of the V$TIMEZONE_NAMES data dictionaryview provide the names of available time zones.
logon TIMESTAMP(3) WITH LOCAL TIME ZONE;
BEGIN
logoff := '1999-10-31 09:42:37.114 +02:00';
...
END;
tzset_show.sqltzmisc.sql
tzglobal_events_local.sql
Interval Computations
In the example below declare a variable of type
-
8/14/2019 Brave New World TWO DAYS for 2005
107/280
Copyright 2000-2005 Steven Feuerstein - Page 107
In the example below, declare a variable of type
INTERVAL YEAR TO MONTH, then assign a valueof 101 years and 3 months to it in three differentways. These are notpoints in time, but amounts of elapsed time.
DECLARE
lifetime INTERVAL YEAR(3) TO MONTH;
BEGIN
lifetime := INTERVAL '101-3' YEAR TO MONTH; -- interval literal
lifetime := '101-3'; -- implicit conversion from character type
lifetime := INTERVAL '101' YEAR; -- Can specify just the years
lifetime := INTERVAL '3' MONTH; -- Can specify just the months
...END;
Function with Interval
MEMBER FUNCTION RETURN INTERVAL YEAR TO MONTH
-
8/14/2019 Brave New World TWO DAYS for 2005
108/280
Copyright 2000-2005 Steven Feuerstein - Page 108
Notice the explicit conversion of the agecalculation formula to an INTERVAL.
MEMBER FUNCTION age RETURN INTERVALYEAR TO MONTH
ISretval INTERVAL YEAR TO MONTH;
BEGINretval := (SYSDATE - SELF.dob)YEAR TO MONTH;
RETURN retval;END;
person.ot
Lots of New Functions
New conversion and "right now" capabilities:
-
8/14/2019 Brave New World TWO DAYS for 2005
109/280
Copyright 2000-2005 Steven Feuerstein - Page 109
New conversion and right now capabilities:
EXTRACT
NUMTODSINTERVAL
NUMTOYMINTERVAL
TO_DSINTERVAL
TO_YMINTERVALTO_TIMESTAMP
TO_TIMESTAMP_TZ
FROM_TZ
SESSIONTIMEZONE
CURRENT_DATE
CURRENT_TIMESTAMP
DBTIMEZONELOCALTIMESTAMP
SYSTIMESTAMP
TZ_OFFSET
extract.sql
Working with XML in PL/SQL
-
8/14/2019 Brave New World TWO DAYS for 2005
110/280
Copyright 2000-2005 Steven Feuerstein - Page 110
Brief introduction to XML
The XMLtype datatype
What is XML?
Stands for Extensible Markup Language and
-
8/14/2019 Brave New World TWO DAYS for 2005
111/280
Copyright 2000-2005 Steven Feuerstein - Page 111
p g g
defines a universal standard for electronic dataexchange...."EDI for the 21st century"
Offers a rigorous set of rules to give structure todata and make it easy to send and receive
information. Nothing but "text with tags"... a vendor-neutral,
platform-neutral, standards-based informationpathway.
Simple XML Example
70689
h k l /
-
8/14/2019 Brave New World TWO DAYS for 2005
112/280
Copyright 2000-2005 Steven Feuerstein - Page 112
ThickPlating, Inc.
Waste dumped in river
Chimney filters disabled
Press conference to call for fines and penalties.
File suit in state and federal counts.
Why Use XML?
XML can serve as application integration "glue"
-
8/14/2019 Brave New World TWO DAYS for 2005
113/280
Copyright 2000-2005 Steven Feuerstein - Page 113
XML can serve as application integration glue .
XML over the HTTP protocol may provide the technology torelatively seamlessly and inexpensively connectheterogeneous databases, applications and networks.
XML makes it easier to publish and reuse information.
Complete separation of data from presentation layer. Standard utilities to transform data to specific output styles.
XML is extensible. "Roll your own" markup language.
Extensions to XML
XML is tabula rosa.
-
8/14/2019 Brave New World TWO DAYS for 2005
114/280
Copyright 2000-2005 Steven Feuerstein - Page 114
You get to define the tags (you can think of HTML as asubset of XML with pre-defined formatting tags).
Different industries are now defining standardizedmarkup languages that know about those
industries' requirements. Some examples: ebXML electronic business infrastucture
WML wireless markup language
docBook documentation standards
www.xml.org
Send/Receive XML over Internet
You can easily send XML documents over the Web
-
8/14/2019 Brave New World TWO DAYS for 2005
115/280
Copyright 2000-2005 Steven Feuerstein - Page 115
using: FTP - File Transfer Protocol (transfer files)
SMTP - Simple Mail Transfer Protocol (transfer email)
HTTP - HyperText Transfer Protocol (transfer documents)
XML will likely figure prominently in the explosion ofwireless Internet devices. "Small footprint" of information-rich data.
Oracle 8iWeb
XML
-
8/14/2019 Brave New World TWO DAYS for 2005
116/280
Copyright 2000-2005 Steven Feuerstein - Page 116
XML and HTTP can connect heterogeneous applications
SQLServer
XSLTStylesheet
OracleAppsSAP
Apps MessageHub
XML
XML
XMLWeb
Oracle Support for XML
Oracle has moved very aggressively to
-
8/14/2019 Brave New World TWO DAYS for 2005
117/280
Copyright 2000-2005 Steven Feuerstein - Page 117
Oracle has moved very aggressively to
support XML from both Java and PL/SQL. Started in Oracle8i and accelerated tremendously
in Oracle9i: the XDB
JDeveloper allows you create, syntax-checkand debug XML, XSLT and XSQL.
interMedia lets you index and search an XMLdocument.
Many utilities available through PL/SQL (nextpage).
Some Oracle XML Components
Download the Oracle XDK from the Oracle TechnologyNetwork; the 9i XDK works for 8i as well.
-
8/14/2019 Brave New World TWO DAYS for 2005
118/280
Copyright 2000-2005 Steven Feuerstein - Page 118
XML Parser Use it to parse, construct and validate XMLdocuments.
XPath Engine A utility that searches in-memory XML documentsusing the declarative syntax of XPath, anotherelement of the XML standard
XSLTProcessor
Supports XSLT in Oracle, allowing you totransform XML documents into different formats
XML SQLUtility
Utility to facilitate the production of XMLdocuments from SQL and to easily insert XML-based data into Oracle tables.
XSQL Pages Technology allowing you to assemble XML datadeclaratively and then publish that data with XSLT.
Some XML Concepts and Capabilities
The XML Document
-
8/14/2019 Brave New World TWO DAYS for 2005
119/280
Copyright 2000-2005 Steven Feuerstein - Page 119
Document Type Definitions andSchemas
Similar to DDL for tables, DTDs and schemasdefine valid syntax for an XML document
The XML Infoset Tree representation of XML document
XPath
Search contents of XML documents
From Document to Infoset
/
Text DocumentInformation Set/
-
8/14/2019 Brave New World TWO DAYS for 2005
120/280
Copyright 2000-2005 Steven Feuerstein - Page 120
89-344
WEBMINTC
XMLParser
89-344
Shares = 100
WEBM
Shares = 30
INTC
XPath: The XML Search Syntax
W3C offers a declarative language called
-
8/14/2019 Brave New World TWO DAYS for 2005
121/280
Copyright 2000-2005 Steven Feuerstein - Page 121
XPath to query the contents of an XMLdocument.
Operators on an information set
Leverages our familiarity with the hierarchicalstructure and path notation of directories andURLs.
The Oracle xslProcessor package
implements the XPath functionality.
Some XPath Examples
What are the names of the newspaper in thedocument?
-
8/14/2019 Brave New World TWO DAYS for 2005
122/280
Copyright 2000-2005 Steven Feuerstein - Page 122
/Newspaper/Name
Does this company's CEO have any bonuspayments over $100,000 while hiring of new
employees was frozen?
//CEO/Bonus[. > 100000 and @HiringFreeze="ON"]
When did Sheri S. Tepper publish "Grass" ?
/Publication/Novel[Title="Grass"]/@PublicationDate
The New XML Datatype
A system-defined object type that has
Oracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
123/280
Copyright 2000-2005 Steven Feuerstein - Page 123
predefined member functions available toextract XML nodes and fragments.
Brings the XML and SQL worlds together
SQL operations on XML content XML operations on SQL content
Apply standard XML functionality, such as XPath,directly against data without need to convert.
Set of XMLtype Methods
createXML: creates an XMLtype instance from a stringor CLOB
Oracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
124/280
Copyright 2000-2005 Steven Feuerstein - Page 124
or CLOB. existsNode: returns 1 if the given XPath expression
returns any result nodes. extract: applies an XPath expression over the XML data
to return a XMLType instance containing the resultantfragment.
isFragment: returns 1 if the XMLtype contains afragment.
getCLOBval, getStringval, getNumberval: returns anXML document or fragment as CLOB, string or number.
Transfer XML Docs to Tables
Create a table with an XMLtype column and
Oracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
125/280
Copyright 2000-2005 Steven Feuerstein - Page 125
insert values with the CreateXML procedure.CREATE TABLE xml_tab (xmlval SYS.XMLTYPE);
INSERT INTO xml_tab VALUES (SYS.XMLTYPE.CREATEXML('
221 John '));
INSERT INTO xml_tab VALUES (XMLTYPE ('
331 PO_1 '));
xmltype.sql
Oracle9iRelease 1 Syntax
Oracle9iRelease 2 Syntax
Retrieve XML Data
SQL> select x.xmlval.getstringval() from xml_tab x;
Oracle9i
-
8/14/2019 Brave New World TWO DAYS for 2005
126/280
Copyright 2000-2005 Steven Feuerstein - Page 126
Note: you must use an alias on the table name.
X.XMLVAL.GETSTRINGVAL()---------------------------------------------------------
221John
331PO_1
-
8/14/2019 Brave New World TWO DAYS for 2005
127/280
Updating XML Documents in Tables
Use updateXML to change the contents of an
-
8/14/2019 Brave New World TWO DAYS for 2005
128/280
Copyright 2000-2005 Steven Feuerstein - Page 128
XML document in a table.The following statement updates all rowsthat have an employee element with the newvalues.
UPDATE emp_tab e SET e.emp_col = UPDATEXML (e.emp_col, '/EMPLOYEES/EMP[EMPNAME="Joe"]/SALARY/text()',100000, '//EMP[EMPNAME="Jack"]/EMPNAME/text()','Jackson',
'//EMP[EMPNO=217]', XMLTYPE.CREATEXML( '217
Jane'))WHERE EXISTSNODE(e.emp_col,'//EMP')=1;
-
8/14/2019 Brave New World TWO DAYS for 2005
129/280
-
8/14/2019 Brave New World TWO DAYS for 2005
130/280
Data Types - Summary
A broader, deeper choice for data types and
-
8/14/2019 Brave New World TWO DAYS for 2005
131/280
Copyright 2000-2005 Steven Feuerstein - Page 131
data structures offers great potential forimproving the quality and reducing thequantity of your code base.
Potentially dramatic impact on the quality ofyour code.
Get comfortable with the structures and putthem to work for you.
SQL-Related Enhancements in PL/SQL
Native Dynamic SQL
-
8/14/2019 Brave New World TWO DAYS for 2005
132/280
Copyright 2000-2005 Steven Feuerstein - Page 132
Bulk processing of DML and queries
Record-based DML
Autonomous transactions
Table functions and CURSOR expressions
-
8/14/2019 Brave New World TWO DAYS for 2005
133/280
Copyright 2000-2005 Steven Feuerstein - Page 133
The Beauty and Eleganceof
Native Dynamic SQL
What is Dynamic SQL?
Dynamic SQL actually refers, in the world of
-
8/14/2019 Brave New World TWO DAYS for 2005
134/280
Copyright 2000-2005 Steven Feuerstein - Page 134
PL/SQL, to two things: SQL statements, such as a DELETE or CREATE
TABLE, that are constructed and executed at run-time.
Anonymous PL/SQL blocks that are constructed,compiled and executed at run-time.
'DROP ' ||l_type || ' ' || l_name
'BEGIN ' ||l_proc_name || ' (' ||l_parameters || '); END;'
The Possibilities of Dynamic SQL
Build ad-hoc query and update applications.
-
8/14/2019 Brave New World TWO DAYS for 2005
135/280
Copyright 2000-2005 Steven Feuerstein - Page 135
When the user gets to decide what to do and see...acommon requirements for Internet applications.
Execute DDL statements from within PL/SQL. They are not otherwise available in a PL/SQL block.
Construct very generic and highly useful utilitiesthat work on "any" table or data structure.
Optimize SQL statements at run-time through soft-coding of hints.
Two Methods Available
DBMS_SQL
-
8/14/2019 Brave New World TWO DAYS for 2005
136/280
Copyright 2000-2005 Steven Feuerstein - Page 136
A large and complex built-in package that madedynamic SQL possible in Oracle7 and Oracle8.
Native Dynamic SQL
A new (with Oracle8i), native implementation ofdynamic SQL that does almostall of whatDBMS_SQL can do, but much more easily andusually more efficiently.
Let's focus on Native Dynamic SQL or NDS.
Native Dynamic SQL
The new "native dynamic SQL" or NDS of
-
8/14/2019 Brave New World TWO DAYS for 2005
137/280
Copyright 2000-2005 Steven Feuerstein - Page 137
Oracle8i is implemented with just twostatements (which are part of the language andnot available via a built-in package): EXECUTE IMMEDIATE , used for DDL,
DML and single row fetches. OPEN FOR , used for multi-row queries.
And in Oracle9i Release 2, you can
even use EXECUTE IMMEDIATEfor multi-row queries!
EXECUTE IMMEDIATE
EXECUTE IMMEDIATE sql-string
[INTO {define_variable[, define_variables]... | record }]
-
8/14/2019 Brave New World TWO DAYS for 2005
138/280
Copyright 2000-2005 Steven Feuerstein - Page 138
Use this statement to execute any dynamic SQLstatement (including a PL/SQL block) exceptfor multi-row
queries. The INTO clause allows you to pass values from the
select list of a single row query into local variables,including objects, collections and records.
The USING clause allows you to specify bind arguments
or variables to be passed into the SQL string beforeexecution.
[USING {IN | OUT | IN OUT] bind argument
[, {IN | OUT | IN OUT] bind argument]...];
DDL within PL/SQL
Very easy, very dangerous with NDS.
H ' d th t "d h t "
-
8/14/2019 Brave New World TWO DAYS for 2005
139/280
Copyright 2000-2005 Steven Feuerstein - Page 139
Here's a procedure that "drops whatever".CREATE OR REPLACE PROCEDURE drop_whatever (nm IN VARCHAR2)
AUTHID CURRENT_USERIS
CURSOR type_cur IS
SELECT object_type FROM USER_OBJECTSWHERE object_name LIKE UPPER (nm);type_rec type_cur%ROWTYPE;
BEGINOPEN type_cur; FETCH type_cur INTO type_rec;IF type_cur%FOUND THEN
EXECUTE IMMEDIATE'DROP ' || type_rec.object_type || ' ' || nm;
END IF;END;
dropwhatever.spcreind81.sphealth$.pkgsettrig.sp
COUNT(*) For Any Table
Here's a handy and simple utility based onNDS:
CREATE OR REPLACE FUNCTION tabCount (tab IN VARCHAR2, whr IN VARCHAR2 := NULL, sch IN VARCHAR2 := NULL)RETURN INTEGER
IS
-
8/14/2019 Brave New World TWO DAYS for 2005
140/280
Copyright 2000-2005 Steven Feuerstein - Page 140
IF tabCount ('citizens', 'insured = ''NO''') > 40,000,000THEN
DBMS_OUTPUT.PUT_LINE ('Not the best health care system in the world....');
END IF;tabcount81.sftabcount.sf
ISretval INTEGER;
BEGINEXECUTE IMMEDIATE
'SELECT COUNT(*) FROM ' || NVL (sch, USER) ||'.' || tab || ' WHERE ' || NVL (whr, '1=1') INTO retval;
RETURN retval;
END;
Specify schema, table andWHERE clause...
DML with NDS
CREATE OR REPLACE PROCEDURE salary_raise ( raise_percent NUMBER, job VARCHAR2)IS
TYPE loc arra t pe IS TABLE OF offices location@TYPE
-
8/14/2019 Brave New World TWO DAYS for 2005
141/280
Copyright 2000-2005 Steven Feuerstein - Page 141
TYPE loc_array_type IS TABLE OF offices.location@TYPEINDEX BY BINARY_INTEGER;
dml_str VARCHAR2 (200);loc_array loc_array_type;
BEGINSELECT location BULK COLLECT INTO loc_array
FROM offices;
FOR i IN loc_array.FIRST .. loc_array.LAST LOOPdml_str := 'UPDATE emp_' || loc_array (i)
|| ' SET sal = sal * (1+(:raise_percent/100))'|| ' WHERE job = :job_title';
EXECUTE IMMEDIATE dml_str USING raise_percent, job;
END LOOP;END;
Differenttable for
each location
Works w/User-defined types
In the following example, the USING clause allows
t bj t d t d t bl t
-
8/14/2019 Brave New World TWO DAYS for 2005
142/280
Copyright 2000-2005 Steven Feuerstein - Page 142
PROCEDURE add_profit_source (
hosp_name IN VARCHAR2,pers IN Person,cond IN preexisting_conditions)
ISBEGIN
EXECUTE IMMEDIATE'INSERT INTO ' || tabname (hosp_name) ||
' VALUES (:revenue_generator, :revenue_inhibitors)'USING pers, cond;END;
me to pass an object and nested table to anINSERT statement with a variable table name. Completely transparent support.
health$.pkg
Multiple Row Queries and NDS
Familiar syntax, tiny learning curve: OPEN FOR Here is a simple utility that displays the values of any date,
number or string column in any table
-
8/14/2019 Brave New World TWO DAYS for 2005
143/280
Copyright 2000-2005 Steven Feuerstein - Page 143
number or string column in any table.
CREATE OR REPLACE PROCEDURE showcol (tab IN VARCHAR2, col IN VARCHAR2, whr IN VARCHAR2 := NULL)
IScv SYS_REFCURSOR; -- Available in Oracle9i
val VARCHAR2(32767);
BEGIN OPEN cv FOR 'SELECT ' || col || ' FROM ' || tab ||
' WHERE ' || NVL (whr, '1 = 1');LOOP
FETCH cv INTO val;EXIT WHEN cv%NOTFOUND;DBMS_OUTPUT.PUT_LINE (val);
END LOOP;CLOSE cv;
END;
showcol81.spndsutil.pkg
Fetch Into Records!
In DBMS_SQL, you had to write many tediouslines of code to fetch into individual variables.
-
8/14/2019 Brave New World TWO DAYS for 2005
144/280
Copyright 2000-2005 Steven Feuerstein - Page 144
CREATE OR REPLACE PROCEDURE showemps (where_in IN VARCHAR2 := NULL)IS
cv SYS_REFCURSOR;rec employee%ROWTYPE;
BEGIN OPEN cv FOR
'SELECT * FROM employeeWHERE ' || NVL (where_in, '1=1');
LOOPFETCH cv INTO rec;EXIT WHEN cv%NOTFOUND;DBMS_OUTPUT.PUT_LINE (
TO_CHAR(rec.employee_id) || '=' || rec.last_name);
END LOOP;CLOSE cv;
END;
New (Oracle9i) pre-defined weak REF
CURSOR type
Quiz!
PROCEDURE process_lineitem( line_in ININTEGER)IS
BEGINIF li i 1
What's wrong with
this code?
-
8/14/2019 Brave New World TWO DAYS for 2005
145/280
Copyright 2000-2005 Steven Feuerstein - Page 145
BEGIN IF line_in =1 THEN
process_line1; ENDIF;
IF line_in =2
THENprocess_line2; ENDIF;
... IF line_in =22045 THEN
process_line22045; ENDIF;END;
dynplsql.txt
this code? How would you fix
it?
From 22,000 lines of code to 1!PROCEDURE process_lineitem( line_in ININTEGER)ISBEGIN IF line_in =1
THEN
PROCEDURE process_lineitem (
line in IN INTEGER)IS
-
8/14/2019 Brave New World TWO DAYS for 2005
146/280
Copyright 2000-2005 Steven Feuerstein - Page 146
Identify the pattern andresolve it either withreusable modules or
dynamic abstractions.
THENprocess_line1;
ENDIF;
IF line_in =2 THEN
process_line2;
ENDIF;...
IF line_in =22045 THEN
process_line22045; ENDIF;END;
line_in ININTEGER)ISBEGIN EXECUTEIMMEDIATE
'BEGIN process_line'||line_in ||'; END;';
END;
dynplsql.txt
Dynamic PL/SQL with NDS
Dynamically construct, compile and run ananonymous block with EXEC. IMMEDIATE.
-
8/14/2019 Brave New World TWO DAYS for 2005
147/280
Copyright 2000-2005 Steven Feuerstein - Page 147
DBMS_JOB uses dynamic PL/SQL to runstored procedures at scheduled times.
DECLAREv_jobno INTEGER;
BEGINDBMS_JOB.submit (job => v_jobno,what => 'DBMS_DDL.ANALYZE_OBJECT ' ||
'(''TABLE'',''LOAD1'',''TENK''' ||',''ESTIMATE'',null,estimate_percent=>50);',
next_date => TRUNC (SYSDATE + 1),
interval => 'TRUNC(SYSDATE+1)');END;
Rules for Dynamic PL/SQL
You must construct and execute a validanonymous block.
B i ith BEGIN DECLARE
-
8/14/2019 Brave New World TWO DAYS for 2005
148/280
Copyright 2000-2005 Steven Feuerstein - Page 148
Begins with BEGIN or DECLARE.
Ends with END;. The trailing semi-colon isrequired; otherwise it is parsed as