Oracle PL/SQL Language Pocket Reference, Second Edition [2 ed.] 9780596004729, 0596004729

The 'Oracle PL/SQL Language Pocket Reference' is a good pocket reference for Oracle 11g but I feel that this s

312 84 518KB

English Pages 115 Year 2003

Report DMCA / Copyright

DOWNLOAD PDF FILE

Recommend Papers

Oracle PL/SQL Language Pocket Reference, Second Edition [2 ed.]
 9780596004729, 0596004729

  • 0 0 0
  • Like this paper and download? You can publish your own PDF file online for free in a few minutes! Sign Up
File loading please wait...
Citation preview

[ Team LiB ]



Table of Cont ent s



I ndex



Reviews



Reader Reviews



Errat a

Oracle PL/SQL Language Pocket Reference, 2nd Edition By Chip Dawes, St even Feuerst ein, Bill Pribyl Publisher

: O'Reilly

Pub Dat e

: February 2003

I SBN

: 0- 596- 00472- 9

Pages

: 127

The new edit ion of t his m ust - have pocket guide boils down t he m ost vit al inform at ion from Oracle PL/ SQL Program m ing, t he best seller t hat m any consider " t he Bible" for PL/ SQL developm ent . This concise booklet sum m arizes feat ures available in Oracle's powerful new product - - Oracle9i- - and provides essent ial inform at ion on PL/ SQL block st ruct ure, fundam ent al language elem ent s, cont rol st at em ent s, and use of procedures, funct ions, packages, t riggers, Oracle obj ect s, ext ernal procedures, and m et hods of calling Java classes from PL/ SQL.

[ Team LiB ]

[ Team LiB ]



Table of Cont ent s



I ndex



Reviews



Reader Reviews



Errat a

Oracle PL/SQL Language Pocket Reference, 2nd Edition By Chip Dawes, St even Feuerst ein, Bill Pribyl Publisher

: O'Reilly

Pub Dat e

: February 2003

I SBN

: 0- 596- 00472- 9

Pages

: 127

Copyright Chapt er 1. Oracle PL/ SQL Language Pocket Reference Sect ion 1.1. I nt roduct ion Sect ion 1.2. Acknowledgm ent s Sect ion 1.3. Convent ions Sect ion 1.4. PL/ SQL Language Fundam ent als Sect ion 1.5. Variables and Program Dat a Sect ion 1.6. Condit ional and Sequent ial Cont rol Sect ion 1.7. Loops Sect ion 1.8. Dat abase I nt eract ion Sect ion 1.9. Cursors in PL/ SQL Sect ion 1.10. Except ion Handling Sect ion 1.11. Records in PL/ SQL Sect ion 1.12. Nam ed Program Unit s Sect ion 1.13. Triggers Sect ion 1.14. Packages Sect ion 1.15. Calling PL/ SQL Funct ions in SQL Sect ion 1.16. Oracle's Obj ect - Orient ed Feat ures Sect ion 1.17. Collect ions Sect ion 1.18. Ext ernal Procedures Sect ion 1.19. Java Language I nt egrat ion

Sect ion 1.20. Reserved Words I ndex

[ Team LiB ]

[ Team LiB ]

Copyright Copyright © 2003 O'Reilly & Associat es, I nc. Print ed in t he Unit ed St at es of Am erica. Published by O'Reilly & Associat es, I nc., 1005 Gravenst ein Highway Nort h, Sebast opol, CA 95472. O'Reilly & Associat es books m ay be purchased for educat ional, business, or sales prom ot ional use. Online edit ions are also available for m ost t it les ( ht t p: / / safari.oreilly.com ) . For m ore inform at ion, cont act our corporat e/ inst it ut ional sales depart m ent : ( 800) 998- 9938 or corporat [email protected] . Nut shell Handbook, t he Nut shell Handbook logo, and t he O'Reilly logo are regist ered t radem arks of O'Reilly & Associat es, I nc. Many of t he designat ions used by m anufact urers and sellers t o dist inguish t heir product s are claim ed as t radem arks. Where t hose designat ions appear in t his book, and O'Reilly & Associat es, I nc. was aware of a t radem ark claim , t he designat ions have been print ed in caps or init ial caps. The associat ion bet ween t he im age of ant s and t he t opic of Oracle PL/ SQL is a t radem ark of O'Reilly & Associat es, I nc. While every precaut ion has been t aken in t he preparat ion of t his book, t he publisher and aut hors assum e no responsibilit y for errors or om issions, or for dam ages result ing from t he use of t he inform at ion cont ained herein.

[ Team LiB ]

[ Team LiB ]

Chapter 1. Oracle PL/SQL Language Pocket Reference Sect ion 1.1. I nt roduct ion Sect ion 1.2. Acknowledgm ent s Sect ion 1.3. Convent ions Sect ion 1.4. PL/ SQL Language Fundam ent als Sect ion 1.5. Variables and Program Dat a Sect ion 1.6. Condit ional and Sequent ial Cont rol Sect ion 1.7. Loops Sect ion 1.8. Dat abase I nt eract ion Sect ion 1.9. Cursors in PL/ SQL Sect ion 1.10. Except ion Handling Sect ion 1.11. Records in PL/ SQL Sect ion 1.12. Nam ed Program Unit s Sect ion 1.13. Triggers Sect ion 1.14. Packages Sect ion 1.15. Calling PL/ SQL Funct ions in SQL Sect ion 1.16. Oracle's Obj ect - Orient ed Feat ures Sect ion 1.17. Collect ions Sect ion 1.18. Ext ernal Procedures Sect ion 1.19. Java Language I nt egrat ion Sect ion 1.20. Reserved Words

[ Team LiB ]

[ Team LiB ]

1.1 Introduction The Oracle PL/ SQL Language Pocket Reference is a quick reference guide t o t he PL/ SQL program m ing language, which provides procedural ext ensions t o t he SQL relat ional dat abase language and a range of Oracle developm ent t ools. Where a package, program , or funct ion is support ed only for a part icular version of Oracle ( e.g., Oracle9i) , we indicat e t his in t he t ext . The purpose of t his pocket reference is t o help PL/ SQL users find t he synt ax of specific language elem ent s. I t is not a self- cont ained user guide; basic knowledge of t he PL/ SQL program m ing language is required. For m ore inform at ion, see t he following O'Reilly books: Oracle PL/ SQL Program m ing, Third Edit ion , by St even Feuerst ein wit h Bill Pribyl Learning Oracle PL/ SQL, by Bill Pribyl wit h St even Feuerst ein Oracle Built - in Packages, by St even Feuerst ein, Charles Dye, and John Beresniewicz Oracle PL/ SQL Built - ins Pocket Reference, by St even Feuerst ein, John Beresniewicz, and Chip Dawes

[ Team LiB ]

[ Team LiB ]

1.2 Acknowledgments Many t hanks t o all t hose who helped in t he preparat ion of t his book. I n part icular, t hanks t o first edit ion reviewers Eric J. Givler and St ephen Nelson and second edit ion reviewer Jonat han Gennick. I n addit ion, we appreciat e all t he good work by t he O'Reilly crew in edit ing and producing t his book.

[ Team LiB ]

[ Team LiB ]

1.3 Conventions UPPERCASE indicat es PL/ SQL keywords. lowercase indicat es user- defined it em s such as param et ers. I t alic indicat es filenam es and param et ers wit hin t ext .

Constant width is used for code exam ples and out put . [] enclose opt ional it em s in synt ax descript ions. { } enclose a list of it em s in synt ax descript ions; you m ust choose one it em from t he list . | separat es bracket ed list it em s in synt ax descript ions.

[ Team LiB ]

[ Team LiB ]

1.4 PL/SQL Language Fundamentals This sect ion sum m arizes t he fundam ent al com ponent s of t he PL/ SQL language: charact ers, ident ifiers, lit erals, delim it ers, use of com m ent s and pragm as, and const ruct ion of st at em ent s and blocks.

1.4.1 PL/SQL Character Set The PL/ SQL language is const ruct ed from let t ers, digit s, sym bols, and whit espace, as defined in t he following t able:

Type

Cha ra ct ers

Let t ers

A-Z, a-z

Digit s

0-9

Sym bols

~!@#$%^&*(

Whit espace

space, tab, newline, carriage return

)_-+=|[ ]{ }:;"'< >,.?/ ^

Charact ers are grouped t oget her int o four lexical unit s: ident ifiers, lit erals, delim it ers, and com m ent s.

1.4.2 Identifiers I dent ifier s are nam es for PL/ SQL obj ect s such as const ant s, variables, except ions, procedures, cursors, and reserved words. I dent ifiers have t he following charact erist ics:

Can be up t o 30 charact ers in lengt h Cannot include whit espace ( space, t ab, carriage ret urn) Must st art wit h a let t er Can include a dollar sign ( $) , an underscore ( _ ) , and a pound sign ( # ) Are not case- sensit ive I n addit ion, you m ust not use PL/ SQL's reserved words as ident ifiers. For a list of t hose words, see t he t able in t he final sect ion in t his book, Sect ion 1.20. I f you enclose an ident ifier wit hin double quot es, t hen all but t he first of t hese rules are ignored. For exam ple, t he following declarat ion is valid:

DECLARE "1 ^abc" VARCHAR2(100); BEGIN IF "1 ^abc" IS NULL THEN ... END; 1.4.3 Boolean, Numeric, and String Literals

Lit erals are specific values not represent ed by ident ifiers. For exam ple, TRUE, 3.14159, 6.63E- 34, ` Moby Dick', and NULL are all lit erals of t ype Boolean, num ber, or st ring. There are no com plex dat at ype lit erals as t hey are int ernal represent at ions. Unlike t he rest of PL/ SQL, lit erals are case- sensit ive. To em bed single quot es wit hin a st ring lit eral, place t wo single quot es next t o each ot her. See t he following t able for exam ples:

Lit e r a l

Act u a l va lu e

'That''s Entertainment!'

That 's Ent ert ainm ent !

'"The Raven"'

" The Raven"

'TZ=''CDT6CST'''

TZ= 'CDT6CST'

''''

'

'''hello world'''

'hello world'

''''''

''

1.4.4 Datetime Interval Literals (Oracle9i) The dat et im e int erval dat at ypes are new wit h Oracle9i. These dat at ypes represent a chronological int erval expressed in t erm s of eit her years and m ont hs or days, hours, m inut es, seconds, and fract ional seconds. Lit erals of t hese dat at ypes require t he keyword I NTERVAL followed by t he lit eral and form at st ring( s) . The int erval m ust go from a larger field t o a sm aller one, so YEAR TO MONTH is valid, but MONTH TO YEAR is not . See t he following t able for exam ples:

Lit e r a l

Act u a l va lu e

I NTERVAL ` 1- 3' YEAR TO MONTH

1 year and 3 m ont hs lat er

I NTERVAL ` 125- 11' YEAR( 3) TO MONTH

125 years and 11 m ont hs lat er

I NTERVAL ` - 18' MONTH

18 m ont hs earlier

I NTERVAL ` - 48' HOUR

48 hours earlier

I NTERVAL ` 7 23: 15' DAY TO MI NUTE

7 days, 23 hours, 15 m inut es lat er

I NTERVAL ` 1 12: 30: 10.2' DAY TO SECOND

1 day, 12 hours, 30 m inut es, 10.2 seconds lat er

I NTERVAL ` 12: 30: 10.2' HOUR TO SECOND

12 hours, 30 m inut es,10.2 seconds lat er

1.4.5 Delimiters Delim it ers are sym bols wit h special m eaning, such as : = ( assignm ent operat or) , | | ( concat enat ion operat or) , and ; ( st at em ent delim it er) . The following t able list s t he PL/ SQL delim it ers:

D e lim it e r

D e scr ipt ion

;

Term inat or ( for st at em ent s and declarat ions)

+

Addit ion operat or

-

Subt ract ion operat or

*

Mult iplicat ion operat or

/

Division operat or

**

Exponent iat ion operat or

||

Concat enat ion operat or

:=

Assignm ent operat or

=

Equalit y operat or

and !=

I nequalit y operat ors

^= and ~=

I nequalit y operat ors


=

" Great er t han or equal t o" operat or

( and )

Expression or list delim it ers

>

Label delim it ers

,

( Com m a) I t em separat or

'

( Single quot e) Lit eral delim it er

"

( Double quot e) Quot ed lit eral delim it er

:

Host variable indicat or

%

At t ribut e indicat or

.

( Period) Com ponent indicat or ( as in record.field or package.elem ent )

@

Rem ot e dat abase indicat or ( dat abase link)

=>

Associat ion operat or ( nam ed not at ion)

..

( Two periods) Range operat or ( used in t he FOR loop)

--

Single- line com m ent indicat or

/* and */ Mult iline com m ent delim it ers 1.4.6 Comments Com m ent s are sect ions of t he code t hat exist t o aid readabilit y. The com piler ignores t hem . A single- line com m ent begins wit h a double hyphen ( —) and ends wit h a new line. The com piler ignores all charact ers bet ween t he — and t he new line. A m ult iline com m ent begins wit h slash ast erisk ( / * ) and ends wit h ast erisk slash ( * / ) . The / * * / com m ent delim it ers can also be used for a single- line com m ent . The following block dem onst rat es bot h kinds of com m ent s:

DECLARE -- Two dashes comment out only the physical line. /* Everything is a comment until the compiler encounters the following symbol */ You cannot em bed m ult iline com m ent s wit hin a m ult iline com m ent , so be careful during developm ent if you

com m ent out port ions of code t hat include com m ent s. The following code dem onst rat es t his issue:

DECLARE /* Everything is a comment until the compiler /* This comment inside another WON'T work!*/ encounters the following symbol. */ /* Everything is a comment until the compiler -- This comment inside another WILL work! encounters the following symbol. */ 1.4.7 Pragmas The PRAGMA keyword is used t o give inst ruct ions t o t he com piler. There are four t ypes of pragm as in PL/ SQL: EXCEPTI ON_I NI T Tells t he com piler t o associat e t he specified error num ber wit h an ident ifier t hat has been declared an EXCEPTI ON in your current program or an accessible package. See Sect ion 1.10 for m ore inform at ion on t his pragm a. RESTRI CT_REFERENCES Tells t he com piler t he purit y level of a packaged program . The purit y level is t he degree t o which a program does not read/ writ e dat abase t ables and/ or package variables. See Sect ion 1.15 for m ore inform at ion on t his pragm a. SERI ALLY_REUSABLE Tells t he runt im e engine t hat package dat a should not persist bet ween references. This is used t o reduce per- user m em ory requirem ent s when t he package dat a is only needed for t he durat ion of t he call and not for t he durat ion of t he session. See Sect ion 1.14 for m ore inform at ion on t his pragm a. AUTONOMOUS_TRANSACTI ON St art ing in Oracle8i, t ells t he com piler t hat t he funct ion, procedure, t op- level anonym ous PL/ SQL block, obj ect m et hod, or dat abase t rigger execut es in it s own t ransact ion space. See Sect ion 1.8 for m ore inform at ion on t his pragm a.

1.4.8 Statements A PL/ SQL program is com posed of one or m ore logical st at em ent s. A st at em ent is t erm inat ed by a sem icolon delim it er. The physical end- of- line m arker in a PL/ SQL program is ignored by t he com piler, except t o t erm inat e a single- line com m ent ( init iat ed by t he — sym bol) .

1.4.9 Block Structure Each PL/ SQL program is a block consist ing of a st andard set of elem ent s, ident ified by keywords ( see Figure 1- 1 ) . The block det erm ines t he scope of declared elem ent s, and how except ions are handled and propagat ed. A block can be anonym ous or nam ed. Nam ed blocks include funct ions, procedures, packages, and t riggers. Figu r e 1 - 1 . Th e PL/ SQL block st r u ct u r e

Here is an exam ple of an anonym ous block:

DECLARE today DATE DEFAULT SYSDATE; BEGIN -- Display the date. DBMS_OUTPUT.PUT_LINE ('Today is ' || today); END; Here is a nam ed block t hat perform s t he sam e act ion:

CREATE OR REPLACE PROCEDURE show_the_date IS today DATE DEFAULT SYSDATE; BEGIN -- Display the date. DBMS_OUTPUT.PUT_LINE ('Today is ' || today); END show_the_date; The following t able sum m arizes t he sect ions of a PL/ SQL block:

Se ct ion

D e scr ipt ion

Header

Required for nam ed blocks. Specifies t he way t he program is called by ot her PL/ SQL blocks. Anonym ous blocks do not have a header. They st art wit h t he DECLARE keyword if t here is a declarat ion sect ion, or wit h t he BEGI N keyword if t here are no declarat ions.

Declar at ion

Opt ional; declares variables, cursors, TYPEs, and local program s t hat are used in t he block's execut ion and except ion sect ions.

Execut ion

Opt ional in package and TYPE specificat ions; cont ains st at em ent s t hat are execut ed when t he block is run.

Ex cept ion

Opt ional; describes error- handling behavior for except ions raised in t he execut able sect ion.

[ Team LiB ]

[ Team LiB ]

1.5 Variables and Program Data PL/ SQL program s are norm ally used t o m anipulat e dat abase inform at ion. You com m only do t his by declaring variables and dat a st ruct ures in your program s, and t hen working wit h t hat PL/ SQL- specific dat a. A variable is a nam ed inst ant iat ion of a dat a st ruct ure declared in a PL/ SQL block ( eit her locally or in a package) . Unless you declare a variable as a CONSTANT, it s value can be changed at any t im e in your program . The following t able sum m arizes t he different t ypes of program dat a:

Type Scalar

D e scr ipt ion Variables m ade up of a single value, such as a num ber, dat e, or Boolean

Com posit e Variables m ade up of m ult iple values, such as a record or a collect ion Reference Point ers t o values LOB

Variables cont aining large obj ect ( LOB) locat ors

1.5.1 Scalar Datatypes Scalar dat at ypes divide int o four fam ilies: num ber, charact er, dat et im e, and Boolean.

1.5.1.1 Numeric datatypes Num eric dat at ypes are furt her divided int o decim al, binary int eger, and PLS_I NTEGER st orage t ypes. Decim al num eric dat at ypes st ore fixed and float ing- point num bers of j ust about any size. They include NUMBER, DEC, DECI MAL, NUMERI C, FLOAT, REAL, and DOUBLE PRECI SI ON. The m axim um precision of a variable wit h t ype NUMBER is 38 digit s, which yields a range of values from 1.0E- 129 t hrough 9.999E125. ( This range of num bers would include t he m ass of an elect ron over t he m ass of t he universe or t he size of t he universe in angst rom s.) Variables of t ype NUMBER can be declared wit h precision and scale, as follows:

NUMBER(precision, scale) where precision is t he num ber of digit s, and scale is t he num ber of digit s t o t he right ( posit ive scale) or left ( negat ive scale) of t he decim al point at which rounding occurs. Legal values for scale range from - 84 t o 127. The following t able shows exam ples of precision and scale:

D e cla r a t ion

Assign e d va lu e

St or e d va lu e

NUMBER

6.02

6.02

NUMBER( 4)

8675

8675

NUMBER( 4)

8675309

Error

NUMBER( 12,5)

3.14159265

3.14159

NUMBER( 12,- 5)

8675309

8700000

Binary int eger num eric dat at ypes st ore whole num bers. They include BI NARY_I NTEGER, I NTEGER, I NT,

SMALLI NT, NATURAL, NATURALN, POSI TI VE, POSI TI VEN, and SI GNTYPE. Binary int eger dat at ypes st ore signed int egers in t he range of - 2 3 1 + 1 t o 2 3 1 - 1. The subt ypes include NATURAL ( 0 t hrough 2 3 1) and POSI TI VE ( 1 t hrough 2 3 1) t oget her wit h t he NOT NULL variat ions NATURALN and POSI TI VEN. SI GNTYPE is rest rict ed t o t hree values ( - 1, 0, 1) . PLS_I NTEGER dat at ypes have t he sam e range as t he BI NARY_I NTEGER dat at ype, but use m achine arit hm et ic inst ead of library arit hm et ic, so are slight ly fast er for com put at ion- heavy processing. The following t able list s t he PL/ SQL num eric dat at ypes wit h ANSI and I BM com pat ibilit y. I n t his t able:

prec is t he precision for t he subt ype. scale is t he scale of t he subt ype. binary is t he binary precision of t he subt ype.

PL/ SQL da t a t ype

Com pa t ibilit y

Or a cle RD BM S da t a t ype

DEC( prec,scale)

ANSI

NUMBER(prec,scale)

DECI MAL( prec,scale)

I BM

NUMBER(prec,scale)

DOUBLE PRECI SI ON

ANSI

NUMBER

FLOAT( binary )

ANSI , I BM

NUMBER

I NT

ANSI

NUMBER( 38)

I NTEGER

ANSI , I BM

NUMBER( 38)

NUMERI C( prec,scale)

ANSI

NUMBER(prec,scale)

REAL

ANSI

NUMBER

SMALLI NT

ANSI , I BM

NUMBER( 38)

1.5.1.2 Character datatypes Charact er dat at ypes st ore alphanum eric t ext and are m anipulat ed by charact er funct ions. As wit h t he num eric fam ily, t here are several subt ypes in t he charact er fam ily, shown in t he following t able:

Fa m ily

D e scr ipt ion

CHAR

Fixed- lengt h alphanum eric st rings. Valid sizes are 1 t o 32767 byt es ( which is larger t han t he Oracle dat abase lim it of 4000) .

VARCHAR2

Variable- lengt h alphanum eric st rings. Valid sizes are 1 t o 32767 byt es ( which is larger t han t he Oracle dat abase lim it of 4000) .

LONG

Variable- lengt h alphanum eric st rings. Valid sizes are 1 t o 32760 byt es. LONG is included prim arily for backward com pat ibilit y. CLOB is t he preferred dat at ype for large charact er st rings.

RAW

Variable- lengt h binary st rings. Valid sizes are 1 t o 32767 byt es ( which is larger t han t he Oracle dat abase lim it of 2000) . RAW dat a do not undergo charact er set conversion when select ed from a rem ot e dat abase.

LONG RAW

Variable- lengt h binary st rings. Valid sizes are 1 t o 32760 byt es. LONG RAW is included prim arily for backward com pat ibilit y. BLOB and BFI LE are t he preferred dat at ypes for large binary dat a. Fixed- lengt h binary dat a. Every row in a dat abase has a physical address or ROWI D. A ROWI D has four part s in base 64: OOOOOOFFFBBBBBBRRR where:

ROWI D

OOOOOO is t he obj ect num ber. FFFF is t he absolut e or relat ive file num ber. BBBBBBBB is t he block num ber wit hin t he file. RRRR is t he row num ber wit hin t he block.

UROWI D

Universal ROWI D. Variable- lengt h hexadecim al st ring depict ing a logical, physical, or non- Oracle row ident ifier. Valid sizes are up t o 4000 byt es.

1.5.1.3 Datetime datatypes Oracle expanded support for dat et im e dat a in Oracle9i by int roducing an assort m ent of new dat at ypes. The dat et im e dat at ypes are DATE ( t he only dat et im e dat at ype pre- Oracle9i) , TI MESTAMP, TI MESTAMP WI TH TI ME ZONE, and TI MESTAMP WI TH LOCAL TI ME ZONE. The t wo int erval dat at ypes, also new t o Oracle9 i, are I NTERVAL YEAR TO MONTH and I NTERVAL DAY TO SECOND. DATE values are fixed- lengt h, dat e- plus- t im e values. The DATE dat at ype can st ore dat es from January 1, 4712 B.C. t o Decem ber 31, 9999 A.D. Each DATE includes t he cent ury, year, m ont h, day, hour, m inut e, and second. Sub- second granularit y is not support ed via t he DATE dat at ype; use one of t he TI MESTAMP dat at ypes inst ead. The t im e port ion of a DATE default s t o m idnight ( 12: 00: 00 AM) if it is not included explicit ly. TI MESTAMP values st ore dat e and t im e t o sub- second granularit y. The sub- second precision ( t he num ber of digit s t o t he right of t he decim al) eit her default s or is set t o 0 t hrough 9 digit s by declarat ion, as in:

DECLARE mytime_declared TIMESTAMP(9); mytime_default TIMESTAMP; The default precision is 6 digit s of precision t o t he right of t he decim al. TI MESTAMP WI TH TI ME ZONE values st ore dat e and t im e values like a TI MESTAMP but also st ore t he hourly offset from UTC ( Coordinat ed Universal Tim e, which is essent ially equivalent t o Greenwich Mean Tim e) . As wit h TI MESTAMP, t he sub- second precision is 0 t o 9 digit s, eit her declared or inherit ed from t he default 6 digit s of precision.

DECLARE mytime_declared TIMESTAMP(9) WITH TIME ZONE; mytime_default TIMESTAMP WITH TIME ZONE; TI MESTAMP WI TH LOCAL TI ME ZONE values st ore dat e and t im e values t oget her wit h t he UTC offset , like a TI MESTAMP WI TH TI ME ZONE. The principal difference bet ween t hese t im est am p dat at ypes occurs when values are saved t o or ret rieved from a dat abase t able. TI MESTAMP WI TH LOCAL TI ME ZONE values are convert ed t o t he dat abase t im e zone and saved wit hout an offset . The values ret rieved from t he dat abase t able are convert ed from t he dat abase t im e zone t o t he session's t im e zone. The offset from UTC for bot h TI MESTAMP WI TH TI ME ZONE and TI MESTAMP WI TH LOCAL TI ME ZONE can be hours and m inut es or a t im e zone region ( found in t he V$TI MEZONE_NAMES dat a dict ionary view) wit h t he opt ional daylight savings t im e nam e ( also found in V$TI MEZONE_NAMES) . For exam ple:

ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT= 'DD-Mon-YYYY HH24:MI:SS.FF TZR'; DECLARE my_tswtz TIMESTAMP(4) WITH TIME ZONE; BEGIN my_tswtz := '31-JUL-02 07:32:45.1234 US/Pacific';

I NTERVAL YEAR TO MONTH values st ore a period of t im e in years and m ont hs:

DECLARE myy2m INTERVAL YEAR TO MONTH; BEGIN myy2m := INTERVAL '1-6' YEAR TO MONTH; I NTERVAL DAY TO SECOND values st ore a period of t im e in days, hours, m inut es, seconds, and fract ional seconds:

DECLARE myd2s INTERVAL DAY TO SECOND; BEGIN myd2s := INTERVAL '2 10:32:15.678' DAY TO SECOND; 1.5.1.4 Boolean datatype The BOOLEAN dat at ype can st ore one of only t hree values: TRUE, FALSE, or NULL. BOOLEAN variables are usually used in logical cont rol st ruct ures such as I F...THEN or LOOP st at em ent s. The following t rut h t ables show t he result s of logical AND, OR, and NOT operat ions wit h PL/ SQL's t hree- value Boolean m odel:

AN D

TRUE

FALSE

N ULL

TRUE

TRUE

FALSE

NULL

FALSE

FALSE

FALSE

FALSE

NULL

NULL

FALSE

NULL

OR

TRUE

FALSE

N ULL

TRUE

TRUE

TRUE

TRUE

FALSE

TRUE

FALSE

NULL

NULL

TRUE

NULL

NULL

N OT ( TRUE) FALSE

N OT ( FALSE) TRUE

N OT ( N ULL) NULL

1.5.2 NLS Character Datatypes The st andard WE8MSWI N1252 or WE8I SO8859P2 charact er set does not support som e languages, such as Chinese and Greek. To support a secondary charact er set , Oracle allows t wo charact er set s in a dat abase—t he dat abase charact er set and t he nat ional charact er set ( NLS) . The t wo NLS dat at ypes, NCHAR and NVARCHAR2, are used t o represent dat a in t he nat ional charact er set . NCHAR values are fixed- lengt h charact er dat a; t he m axim um lengt h is 32767 byt es. NVARCHAR2 values are variable- lengt h charact er dat a; t he m axim um lengt h is also 32767 byt es.

1.5.3 LOB Datatypes PL/ SQL support s a num ber of large obj ect ( LOB) dat at ypes, which can st ore obj ect s of up t o four gigabyt es of dat a. Unlike t he scalar dat at ypes, variables declared for LOBs use locat ors, or point ers t o t he act ual dat a. LOBs are m anipulat ed in PL/ SQL using t he built - in package DBMS_LOB. The LOB dat at ypes are:

BFI LE File locat ors point ing t o read- only large binary obj ect s in operat ing syst em files. Wit h BFI LEs, t he large obj ect s are out side t he dat abase. BLOB LOB locat ors t hat point t o large binary obj ect s inside t he dat abase. CLOB LOB locat ors t hat point t o large charact er ( alphanum eric) obj ect s inside t he dat abase. NCLOB LOB locat ors t hat point t o large nat ional charact er set obj ect s inside t he dat abase.

1.5.4 Implicit Datatype Conversions Whenever PL/ SQL det ect s t hat a dat at ype conversion is necessary, it at t em pt s t o change t he values as required t o perform t he operat ion. Figure 2 shows what t ypes of im plicit conversions PL/ SQL can perform . Figu r e 1 - 2 . I m plicit con ve r sion s pe r for m e d by PL/ SQL

1.5.5 NULLs in PL/SQL PL/ SQL represent s unknown or inapplicable values as NULL values. Because a NULL is unknown, a NULL is never equal or not equal t o anyt hing ( including anot her NULL value) . I n addit ion, m ost funct ions ret urn a NULL when passed a NULL argum ent —t he not able except ions are NVL, NVL2, CONCAT, and REPLACE. You cannot check for equalit y or inequalit y t o NULL; t herefore, you m ust use t he I S NULL or I S NOT NULL synt ax t o check for NULL values. Here is an exam ple of t he I S NULL synt ax used t o check t he value of a variable:

BEGIN IF myvar IS NULL

THEN ... 1.5.6 Declaring Variables Before you can use a variable, you m ust first declare it in t he declarat ion sect ion of your PL/ SQL block or in a package as a global. When you declare a variable, PL/ SQL allocat es m em ory for t he variable's value and nam es t he st orage locat ion so t hat t he value can be ret rieved and changed. The synt ax for a variable declarat ion is:

variable_name datatype [CONSTANT] [NOT NULL] [{ := | DEFAULT } initial_value] 1.5.6.1 Constrained declarations The dat at ype in a declarat ion can be const rained or unconst rained. Const rained dat at ypes have a size, scale, or precision lim it t hat is less t han t he unconst rained dat at ype. For exam ple:

total_sales emp_id company_number book_title

NUMBER(15,2); VARCHAR2(9); NUMBER; VARCHAR2;

-----

Constrained. Constrained. Unconstrained. Not valid.

Const rained declarat ions require less m em ory t han unconst rained declarat ions. Not all dat at ypes can be specified as unconst rained. You cannot , for exam ple, declare a variable t o be of t ype VARCHAR2. You m ust always specify t he m axim um size of a variable- lengt h st ring.

1.5.6.2 Constants The CONSTANT keyword in a declarat ion requires an init ial value and does not allow t hat value t o be changed. For exam ple:

min_order_qty

NUMBER(1) CONSTANT := 5;

1.5.6.3 Default values Whenever you declare a variable, it is assigned a default value of NULL. I nit ializing all variables is dist inct ive t o PL/ SQL; in t his way, PL/ SQL differs from languages such as C and Ada. I f you want t o init ialize a variable t o a value ot her t han NULL, you do so in t he declarat ion wit h eit her t he assignm ent operat or ( : = ) or t he DEFAULT keyword:

counter priority

BINARY_INTEGER := 0; VARCHAR2(8) DEFAULT 'LOW';

A NOT NULL const raint can be appended t o t he variable's dat at ype declarat ion t o indicat e t hat NULL is not a valid value. I f you add t he NOT NULL const raint , you m ust explicit ly assign an init ial value for t hat variable.

1.5.7 Anchored Declarations Use t he % TYPE at t ribut e t o anchor t he dat at ype of a scalar variable t o eit her anot her variable or t o a colum n in a dat abase t able or view. Use % ROWTYPE t o anchor a record's declarat ion t o a cursor or t able ( see Sect ion 1.11 for m ore det ail on t he % ROWTYPE at t ribut e) .

The following block shows several variat ions of anchored declarat ions:

DECLARE tot_sales NUMBER(20,2); -- Anchor to a PL/SQL variable. monthly_sales tot_sales%TYPE; -- Anchor to a database column. v_ename employee.last_name%TYPE; CURSOR mycur IS SELECT * FROM employee; -- Anchor to a cursor. myrec mycur%ROWTYPE; The NOT NULL clause on a variable declarat ion ( but not on a dat abase colum n definit ion) follows t he % TYPE anchoring and requires anchored declarat ions t o have a default in t heir declarat ion. The default value for an anchored declarat ion can be different from t hat for t he base declarat ion:

tot_sales monthly_sales

NUMBER(20,2) NOT NULL DEFAULT 0; tot_sales%TYPE DEFAULT 10;

1.5.8 Programmer-Defined Subtypes PL/ SQL allows you t o define unconst rained scalar subt ypes. An unconst rained subt ype provides an alias t o t he original underlying dat at ype; for exam ple:

CREATE OR REPLACE PACKAGE std_types IS -- Declare standard types as globals. SUBTYPE dollar_amt_t IS NUMBER; END std_types; CREATE OR REPLACE PROCEDURE process_money IS -- Use the global type declared above. credit std_types.dollar_amt_t; ... A const rained subt ype lim it s or const rains t he new dat at ype t o a subset of t he original dat at ype. For exam ple, POSI TI VE is a const rained subt ype of BI NARY_I NTEGER. The declarat ion for POSI TI VE in t he STANDARD package is:

SUBTYPE POSITIVE IS BINARY_INTEGER RANGE 1..2147483647; You can define your own const rained subt ypes in your program s:

PACKAGE std_types IS SUBTYPE currency_t IS NUMBER (15, 2); END; [ Team LiB ]

[ Team LiB ]

1.6 Conditional and Sequential Control PL/ SQL includes condit ional ( I F, CASE) st ruct ures as well as sequent ial cont rol ( GOTO, NULL) const ruct s.

1.6.1 Conditional Control Statements There are several variet ies of I F- THEN- ELSE and CASE st ruct ures.

1.6.1.1 IF-THEN combination

IF condition THEN executable statement(s) END IF; For exam ple:

IF caller_type = 'VIP' THEN generate_response('GOLD'); END IF; 1.6.1.2 IF-THEN-ELSE combination

IF condition THEN TRUE sequence_of_executable_statement(s) ELSE FALSE/NULL sequence_of_executable_statement(s) END IF; For exam ple:

IF caller_type = 'VIP' THEN generate_response('GOLD'); ELSE generate_response('BRONZE'); END IF; 1.6.1.3 IF-THEN-ELSIF combination

IF condition-1 THEN statements-1 ELSIF condition-N THEN statements-N [ELSE ELSE statements] END IF; For exam ple:

IF caller_type = 'VIP' THEN

generate_response('GOLD'); ELSIF priority_client THEN generate_response('SILVER'); ELSE generate_response('BRONZE'); END IF; 1.6.1.4 CASE statement (Oracle9i) There are t wo t ypes of CASE st at em ent s: sim ple and searched. A sim ple CASE st at em ent is sim ilar t o an I F- THEN- ELSI F st ruct ure. The st at em ent has a swit ch expression im m ediat ely aft er t he keyword CASE. The expression is evaluat ed and com pared t o t he value in each WHEN clause. The first WHEN clause wit h a m at ching value is execut ed and t hen cont rol passes t o t he next st at em ent following t he END CASE. For exam ple:

CASE region_id WHEN 'NE' THEN mgr_name := 'MINER'; WHEN 'SE' THEN mgr_name := 'KOOI'; ELSE mgr_name := 'LANE'; END CASE; I f a swit ch expression evaluat es t o NULL, t he ELSE case is t he only one t hat can possibly m at ch; WHEN NULL will never m at ch because Oracle perform s an equalit y com parison on t he expressions. Bot h t he CASE st at em ent and t he CASE expression ( see t he next sect ion) should include an ELSE clause t hat will execut e st at em ent s if no WHEN clause evaluat es TRUE, because PL/ SQL's runt im e engine will raise an except ion if it finds no m at ching expression. The searched CASE st at em ent does not have a swit ch; inst ead, each WHEN clause has a com plet e Boolean expression. The first m at ching WHEN clause is execut ed and cont rol passes t o t he next st at em ent following t he END CASE. For exam ple:

CASE WHEN region_id = 'EAME' THEN mgr_name := 'SCHMIDT'; WHEN division = 'SALES' THEN mgr_name := 'KENNEDY'; ELSE mgr_name := 'GUPTA'; END CASE; 1.6.1.5 CASE expression (Oracle9i) There are also t wo t ypes of CASE expressions: sim ple and searched. You can use CASE expressions anywhere t hat you can use any ot her t ype of expressions in PL/ SQL program s. A sim ple CASE expression let s you choose an expression t o evaluat e based on a scalar value t hat you provide as input . The following exam ple shows a sim ple CASE expression being used wit h t he built - in DBMS_OUTPUT package t o out put t he value of a Boolean variable. DBMS.OUTPUT.PUT_LI NE is not overloaded t o handle Boolean t ypes, so in t his exam ple t he CASE expression convert s t he Boolean value in a charact er st ring, which PUT_LI NE can t hen handle:

DECLARE boolean_true BOOLEAN := TRUE;

boolean_false BOOLEAN := FALSE; boolean_null BOOLEAN; FUNCTION boolean_to_varchar2 (flag IN BOOLEAN) RETURN VARCHAR2 IS BEGIN RETURN CASE flag WHEN TRUE THEN 'True' WHEN FALSE THEN 'False' ELSE 'NULL' END; END; BEGIN DBMS_OUTPUT.PUT_LINE(boolean_to_varchar2(boolean_true)); DBMS_OUTPUT.PUT_LINE(boolean_to_varchar2(boolean_false)); DBMS_OUTPUT.PUT_LINE(boolean_to_varchar2(boolean_null)); END; A searched CASE expression evaluat es a list of expressions t o find t he first one t hat evaluat es t o TRUE, and t hen ret urns t he result s of an associat ed expression. I n t he following exam ple, a searched CASE expression ret urns t he proper bonus value for any given salary:

DECLARE salary NUMBER := 20000; employee_id NUMBER := 36325; PROCEDURE give_bonus (emp_id IN NUMBER, bonus_amt IN NUMBER) IS BEGIN DBMS_OUTPUT.PUT_LINE(emp_id); DBMS_OUTPUT.PUT_LINE(bonus_amt); END; BEGIN give_bonus(employee_id, CASE WHEN salary >= 10000 AND salary 20000 AND salary 40000 THEN 500 ELSE 0 END); END; 1.6.2 Sequential Control Statements PL/ SQL provides a GOTO st at em ent and a NULL st at em ent t o aid in sequent ial cont rol operat ions.

1.6.2.1 GOTO The GOTO st at em ent perform s uncondit ional branching t o a nam ed label. You should only rarely use a GOTO. At least one execut able st at em ent m ust follow t he label ( t he NULL st at em ent can be t his necessary execut able st at em ent ) . The form at of a GOTO st at em ent is:

GOTO ;

For exam ple:

BEGIN GOTO second_output; DBMS_OUTPUT.PUT_LINE('This line will never execute.');

DBMS_OUPUT.PUT_LINE('We are here!); END There are a num ber of scope rest rict ions on where a GOTO can branch cont rol. A GOTO:

Can branch out of an I F st at em ent , LOOP, or sub- block Cannot branch int o an I F st at em ent , LOOP, or sub- block Cannot branch from one sect ion of an I F st at em ent t o anot her ( from t he I F- THEN sect ion t o t he ELSE sect ion is illegal) Cannot branch int o or out of a sub- program Cannot branch from t he except ion sect ion t o t he execut able sect ion of a PL/ SQL block Cannot branch from t he execut able sect ion t o t he except ion sect ion of a PL/ SQL block, alt hough a RAI SE does t his

1.6.2.2 NULL The NULL st at em ent is an execut able st at em ent t hat does not hing. I t is useful when an execut able st at em ent m ust follow a GOTO label or t o aid readabilit y in an I F- THEN- ELSE st ruct ure. For exam ple:

IF :report.selection = 'DETAIL' THEN exec_detail_report; ELSE NULL; END IF; [ Team LiB ]

[ Team LiB ]

1.7 Loops The LOOP const ruct allows you t o execut e a sequence of st at em ent s repeat edly. There are t hree kind of loops: sim ple ( infinit e) , FOR, and WHI LE. You can use t he EXI T st at em ent t o break out of LOOP and pass cont rol t o t he st at em ent following t he END LOOP.

1.7.1 Simple Loop LOOP executable_statement(s) END LOOP; The sim ple loop should cont ain an EXI T or EXI T WHEN unless you want it t o execut e infinit ely. Use t he sim ple loop when you want t he body of t he loop t o execut e at least once. For exam ple:

LOOP FETCH company_cur INTO company_rec; EXIT WHEN company_cur%ROWCOUNT > 5 OR company_cur%NOTFOUND; process_company(company_cur); END LOOP; 1.7.2 Numeric FOR Loop FOR loop_index IN [REVERSE] lowest_number..highest_number LOOP executable_statement(s) END LOOP; The PL/ SQL runt im e engine aut om at ically declares t he loop index a PLS_I NTEGER variable; never declare a variable wit h t hat nam e yourself. The lowest _num ber and highest _num ber ranges can be variables, but are evaluat ed only once—on init ial ent ry int o t he loop. The REVERSE keyword causes PL/ SQL t o st art wit h t he highest _num ber and decrem ent down t o t he lowest _num ber . For exam ple, t his code:

BEGIN FOR counter IN 1 .. 4 LOOP DBMS_OUTPUT.PUT(counter); END LOOP; DBMS_OUTPUT.NEW_LINE; FOR counter IN REVERSE 1 .. 4 LOOP DBMS_OUTPUT.PUT(counter); END LOOP; DBMS_OUTPUT.NEW_LINE;END; yields t he following out put :

1234 4321 1.7.3 Cursor FOR Loop FOR record_index IN [cursor_name | (SELECT statement)] LOOP executable_statement(s) END LOOP; The PL/ SQL runt im e engine aut om at ically declares t he loop index a record of cursor_nam e% ROWTYPE; never declare a variable wit h t hat nam e yourself. The cursor FOR loop aut om at ically opens t he cursor, fet ches all rows ident ified by t he cursor, and t hen closes t he cursor. You can em bed t he SELECT st at em ent direct ly in t he cursor FOR loop. For exam ple:

FOR emp_rec IN emp_cur LOOP IF emp_rec.title = 'Oracle Programmer' THEN give_raise(emp_rec.emp_id,30) END IF; END LOOP; 1.7.4 WHILE Loop WHILE condition LOOP executable_statement(s) END LOOP; Use t he WHI LE loop in cases where you m ay not want t he loop body t o execut e even once:

WHILE NOT end_of_analysis LOOP perform_analysis; get_next_record; IF analysis_cursor%NOTFOUND AND next_step IS NULL THEN end_of_analysis := TRUE; END IF; END LOOP; 1.7.5 REPEAT UNTIL Loop Emulation PL/ SQL does not direct ly support a REPEAT UNTI L const ruct , but a m odified sim ple loop can em ulat e one. The synt ax for t his em ulat ed REPEAT UNTI L loop is:

LOOP executable_statement(s) EXIT WHEN Boolean_condition; END LOOP; Use t he em ulat ed REPEAT UNTI L loop when execut ing it erat ions indefinit ely before condit ionally t erm inat ing t he loop.

1.7.6 EXIT Statement EXIT [WHEN condition]; I f you do not include a WHEN clause in t he EXI T st at em ent , it will t erm inat e t he loop uncondit ionally. Ot herwise, t he loop t erm inat es only if t he Boolean condit ion evaluat es t o TRUE. The EXI T st at em ent is opt ional and can appear anywhere in t he loop.

1.7.7 Loop Labels Loops can be opt ionally labeled t o im prove readabilit y and execut ion cont rol, as we showed earlier in t he discussion of t he GOTO st at em ent . The label m ust appear im m ediat ely in front of t he st at em ent t hat init iat es t he loop. The following exam ple dem onst rat es t he use of loop labels t o qualify variables wit hin a loop and also t o t erm inat e nest ed and out er loops:

FOR yearind IN 1 .. 20 LOOP

LOOP ... IF year_loop.yearind > 10 THEN EXIT year_loop; END IF; END LOOP month_loop; END LOOP year_loop; [ Team LiB ]

[ Team LiB ]

1.8 Database Interaction PL/ SQL is t ight ly int egrat ed wit h t he underlying SQL layer of t he Oracle dat abase. You can execut e SQL st at em ent s ( UPDATE, I NSERT, DELETE, MERGE, and SELECT) direct ly in PL/ SQL program s. You can also execut e Dat a Definit ion Language ( DDL) st at em ent s t hrough t he use of dynam ic SQL. I n addit ion, you can m anage t ransact ions wit h COMMI T, ROLLBACK, and ot her Dat a Cont rol Language ( DCL) st at em ent s.

1.8.1 Transaction Management The Oracle RDBMS provides a t ransact ion m odel based on a unit of work. The PL/ SQL language support s m ost , but not all, of t he dat abase m odel for t ransact ions ( you cannot , for exam ple, specify ROLLBACK FORCE) . A t ransact ion begins wit h t he first change t o dat a and ends wit h eit her a COMMI T or a ROLLBACK. Transact ions are independent of PL/ SQL blocks. Transact ions can span m ult iple PL/ SQL blocks, or t here can be m ult iple t ransact ions in a single PL/ SQL block. The PL/ SQL- support ed t ransact ion st at em ent s include COMMI T, ROLLBACK, SAVEPOI NT, SET TRANSACTI ON, and LOCK TABLE, described in t he following sect ions.

1.8.1.1 COMMIT

COMMIT [WORK] [COMMENT text]; COMMI T m akes t he dat abase changes perm anent and visible t o ot her dat abase sessions. The WORK keyword is opt ional and only aids readabilit y—it is rarely used. The COMMENT t ext is opt ional and can be up t o 50 charact ers in lengt h. I t is only germ ane t o in- doubt dist ribut ed ( t wo- phase com m it ) t ransact ions. The dat abase st at em ent COMMI T FORCE, also for dist ribut ed t ransact ions, is not support ed in PL/ SQL.

1.8.1.2 ROLLBACK

ROLLBACK [WORK] [TO [SAVEPOINT] savepoint_name]; ROLLBACK undoes t he changes m ade in t he current t ransact ion eit her t o t he beginning of t he t ransact ion or t o a savepoint . A savepoint is a nam ed processing point in a t ransact ion, creat ed wit h t he SAVEPOI NT st at em ent . Rolling back t o a savepoint is a part ial rollback of a t ransact ion, wiping out all changes ( and savepoint s) t hat occurred lat er t han t he nam ed savepoint .

1.8.1.3 SAVEPOINT

SAVEPOINT savepoint_name; SAVEPOI NT est ablishes a savepoint in t he current t ransact ion. savepoint _nam e is an undeclared ident ifier—you do not declare it . More t han one savepoint can be est ablished wit hin a t ransact ion. I f you reuse a savepoint nam e, t hat savepoint is m oved t o t he lat er posit ion and you will not be able t o roll back t o t he init ial savepoint posit ion.

1.8.1.4 SET TRANSACTION

SET TRANSACTION READ ONLY;

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; SET TRANSACTION USE ROLLBACK SEGMENT rbseg_name; SET TRANSACTI ON has t hree t ransact ion cont rol funct ions: READ ONLY Marks t he beginning of a read- only t ransact ion. This indicat es t o t he RDBMS t hat a read- consist ent view of t he dat abase is t o be enforced for t he t ransact ion ( t he default is for t he st at em ent ) . This readconsist ent view m eans t hat only changes com m it t ed before t he t ransact ion begins are visible for t he durat ion of t he t ransact ion. The t ransact ion is ended wit h eit her a COMMI T or a ROLLBACK. Only LOCK TABLE, SELECT, SELECT I NTO, OPEN, FETCH, CLOSE, COMMI T, or ROLLBACK st at em ent s are perm it t ed during a read- only t ransact ion. I ssuing ot her st at em ent s, such as I NSERT or UPDATE, in a read- only t ransact ion result s in an ORA- 1456 error. I SOLATI ON LEVEL SERI ALI ZABLE Sim ilar t o a READ ONLY t ransact ion in t hat t ransact ion- level read consist ency is enforced inst ead of t he default st at em ent - level read consist ency. Serializable t ransact ions do allow changes t o dat a, however. USE ROLLBACK SEGMENT Tells t he RDBMS t o use t he specifically nam ed rollback segm ent rbseg_nam e. This st at em ent is useful when only one rollback segm ent is large, and a program knows t hat it needs t o use t he large rollback segm ent , such as during a m ont h- end close operat ion. For exam ple, if we know t hat our large rollback segm ent is nam ed rbs_large, we can t ell t he dat abase t o use it by issuing t he following st at em ent before our first change t o dat a: SET TRANSACTION USE ROLLBACK SEGMENT rbs_large; 1.8.1.5 LOCK TABLE

LOCK TABLE table_list IN lock_mode MODE [NOWAIT]; This st at em ent bypasses t he im plicit dat abase row- level locks by explicit ly locking one or m ore t ables in t he specified m ode. The t able_list is a com m a- delim it ed list of t ables. The lock_m ode is one of t he following: ROW SHARE, ROW EXCLUSI VE, SHARE UPDATE, SHARE, SHARE ROW EXCLUSI VE, or EXCLUSI VE. The NOWAI T keyword specifies t hat t he RDBMS should not wait for a lock t o be released. I f t here is a lock when NOWAI T is specified, t he RDBMS raises t he except ion " ORA- 00054: resource busy and acquire wit h NOWAI T specified." The default RDBMS locking behavior is t o wait indefinit ely.

1.8.2 Autonomous Transactions Aut onom ous t ransact ions, int roduced in Oracle8i, execut e wit hin a block of code as separat e t ransact ions from t he out er ( m ain) t ransact ion. Changes can be com m it t ed or rolled back in an aut onom ous t ransact ion wit hout com m it t ing or rolling back t he m ain t ransact ion. Changes com m it t ed in an aut onom ous t ransact ion are visible t o t he m ain t ransact ion, even t hough t hey occur aft er t he st art of t he m ain t ransact ion. Those changes com m it t ed in an aut onom ous t ransact ion are visible t o ot her t ransact ions as well. The RDBMS suspends t he m ain t ransact ion while t he aut onom ous t ransact ion execut es:

PROCEDURE main IS BEGIN UPDATE ... -- Main transaction begins here. DELETE ... at_proc; -- Call the autonomous transaction. SELECT ... INSERT ... COMMIT; -- Main transaction ends here.

END; PROCEDURE at_proc IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN -- Main transaction suspends here. SELECT ... INSERT ... -- Autonomous transaction begins here. UPDATE ... DELETE ... COMMIT; -- Autonomous transaction ends here. END; -- Main transaction resumes here. So, changes m ade in t he m ain t ransact ion are not visible t o t he aut onom ous t ransact ion, and if t he m ain t ransact ion holds any locks t hat t he aut onom ous t ransact ion wait s for, a deadlock occurs. Using t he NOWAI T opt ion on UPDATE st at em ent s in aut onom ous t ransact ions can help t o m inim ize t his kind of deadlock. Funct ions and procedures ( local program , st andalone, or packaged) , dat abase t riggers, t op- level anonym ous PL/ SQL blocks, and obj ect m et hods can be declared aut onom ous via t he com piler direct ive PRAGMA AUTONOMOUS_TRANSACTI ON. I n addit ion, t here m ust be a com m it or a rollback at each exit point in t he aut onom ous program .

[ Team LiB ]

[ Team LiB ]

1.9 Cursors in PL/SQL Every SQL st at em ent execut ed by t he RDBMS has a privat e SQL area t hat cont ains inform at ion about t he SQL st at em ent and t he set of dat a ret urned. I n PL/ SQL, a cursor is a nam e assigned t o a specific privat e SQL area for a specific SQL st at em ent . There can be eit her st at ic cursors, whose SQL st at em ent is det erm ined at com pile t im e, or dynam ic cursors, whose SQL st at em ent is det erm ined at runt im e. St at ic cursors are used only for DML st at em ent s ( SELECT, I NSERT, UPDATE, DELETE, MERGE, or SELECT FOR UPDATE) . These st at ic cursors can be explicit ly declared and nam ed or m ay appear in- line as an im plicit cursor. Dynam ic cursors are used for any t ype of valid SQL st at em ent including DDL ( CREATE, TRUNCATE, ALTER) and DCL ( GRANT, REVOKE) . Dynam ic cursors are im plem ent ed wit h t he EXECUTE I MMEDI ATE st at em ent .

1.9.1 Explicit Cursors Explicit cursors are SELECT st at em ent s t hat are DECLAREd explicit ly in t he declarat ion sect ion of t he current block or in a package specificat ion. Use OPEN, FETCH, and CLOSE in t he execut ion or except ion sect ions of your program s.

1.9.1.1 Declaring explicit cursors To use an explicit cursor, you m ust first declare it in t he declarat ion sect ion of a block or package. There are t hree t ypes of explicit cursor declarat ions:

A cursor wit hout param et ers; for exam ple:

CURSOR company_cur IS SELECT company_id FROM company; A cursor t hat accept s argum ent s t hrough a param et er list ; for exam ple:

CURSOR company_cur (id_in IN NUMBER) IS SELECT name FROM company WHERE company_id = id_in; A cursor header t hat cont ains a RETURN clause in place of t he SELECT st at em ent ; for exam ple:

CURSOR company_cur (id_in IN NUMBER) RETURN company%ROWTYPE; This last exam ple shows t hat t he cursor can be declared separat ely from it s im plem ent at ion; for exam ple, t he header in a package specificat ion and t he im plem ent at ion in t he package body. See Sect ion 1.14 for m ore inform at ion.

1.9.1.2 Opening explicit cursors To open a cursor, use t he following synt ax:

OPEN cursor_name [(argument [,argument ...])]; where cursor_nam e is t he nam e of t he cursor as declared in t he declarat ion sect ion. The argum ent s are required if t he definit ion of t he cursor cont ains a param et er list .

You m ust open an explicit cursor before you can fet ch rows from t hat cursor. When t he cursor is opened, t he processing act ually includes t he parse, bind, open, and execut e phases of SQL st at em ent execut ion. This OPEN processing includes det erm ining an execut ion plan, associat ing host variables and cursor param et ers wit h t he placeholders in t he SQL st at em ent , det erm ining t he result set , and, finally, set t ing t he current row point er t o t he first row in t he result set . When using a cursor FOR loop, t he OPEN is im plicit in t he FOR st at em ent . I f you t ry t o open a cursor t hat is already open, PL/ SQL will raise an " ORA- 06511: PL/ SQL: cursor already open" except ion.

1.9.1.3 Fetching from explicit cursors The FETCH st at em ent places t he cont ent s of t he current row int o local variables. To ret rieve all rows in a result set , each row needs t o be fet ched. The synt ax for a FETCH st at em ent is:

FETCH cursor_name INTO record_or_variable_list; where cursor_nam e is t he nam e of t he cursor as declared and opened.

1.9.1.4 Closing explicit cursors Aft er all rows have been fet ched, a cursor needs t o be closed. Closing a cursor enables t he PL/ SQL m em ory opt im izat ion algorit hm t o release t he associat ed m em ory at an appropriat e t im e. You can close an explicit cursor by specifying a CLOSE st at em ent as follows:

CLOSE cursor_name; where cursor_nam e is t he nam e of t he cursor declared and opened. I f you declare a cursor in a local anonym ous, procedure, or funct ion block, t hat cursor will aut om at ically close when t he block t erm inat es. Package- based cursors m ust be closed explicit ly, or t hey st ay open for t he durat ion of your session. Closing a cursor t hat is not open raises an I NVALI D CURSOR except ion.

1.9.1.5 Explicit cursor attributes There are four at t ribut es associat ed wit h cursors: I SOPEN, FOUND, NOTFOUND, and ROWCOUNT. These at t ribut es can be accessed wit h t he % delim it er t o obt ain inform at ion about t he st at e of t he cursor. The synt ax for a cursor at t ribut e is:

cursor_name%attribute where cursor_nam e is t he nam e of t he explicit cursor. The behaviors of t he explicit cursor at t ribut es are described in t he following t able:

At t ribut e

D e scr ipt ion TRUE if cursor is open.

% I SOPEN FALSE if cursor is not open. I NVALI D_CURSOR is raised if cursor has not been OPENed. NULL before t he first fet ch. % FOUND

TRUE if record was fet ched successfully. FALSE if no row was ret urned. I NVALI D_CURSOR if cursor has been CLOSEd. I NVALI D_CURSOR is raised if cursor has not been OPENed. NULL before t he first fet ch.

% NOTFOUND FALSE if record was fet ched successfully. TRUE if no row was ret urned. I NVALI D_CURSOR if cursor has been CLOSEd. I NVALI D_CURSOR is raised if cursor has not been OPENed. % ROWCOUNT The num ber of rows fet ched from t he cursor. I NVALI D_CURSOR if cursor has been CLOSEd. Frequent ly, a cursor at t ribut e is checked as part of a WHI LE loop t hat fet ches rows from a cursor, as shown here:

DECLARE caller_rec caller_pkg.caller_cur%ROWTYPE; BEGIN OPEN caller_pkg.caller_cur; LOOP FETCH caller_pkg.caller_cur into caller_rec; EXIT WHEN caller_pkg.caller_cur%NOTFOUND OR caller_pkg.caller_cur%ROWCOUNT > 10; UPDATE call SET caller_id = caller_rec.caller_id WHERE call_timestamp < SYSDATE; END LOOP; CLOSE caller_pkg.caller_cur; END; 1.9.2 Implicit Cursors Whenever a SQL st at em ent is direct ly in t he execut ion or except ion sect ion of a PL/ SQL block, you are working wit h im plicit cursors. SQL st at em ent s handled t his way include I NSERT, UPDATE, DELETE, MERGE, and SELECT I NTO. Unlike explicit cursors, im plicit cursors do not need t o be declared, OPENed, FETCHed, or CLOSEd. SELECT st at em ent s handle t he % FOUND and % NOTFOUND at t ribut es different ly from t he way t hat explicit

cursors do. When an im plicit SELECT st at em ent does not ret urn any rows, PL/ SQL im m ediat ely raises t he NO_DATA_FOUND except ion and cont rol passes t o t he except ion sect ion. When an im plicit SELECT ret urns m ore t han one row, PL/ SQL im m ediat ely raises t he TOO_MANY_ROWS except ion and cont rol passes t o t he except ion sect ion. I m plicit cursor at t ribut es are referenced via t he SQL cursor. For exam ple:

BEGIN UPDATE activity SET last_accessed := SYSDATE WHERE UID = user_id; IF SQL%NOTFOUND THEN INSERT INTO activity_log (uid,last_accessed) VALUES (user_id,SYSDATE); END IF END; The following t able list s t he im plicit cursor at t ribut es:

At t r ibu t e s SQL% I SOPEN

D e scr ipt ion Always FALSE because t he cursor is opened im plicit ly and closed im m ediat ely aft er t he st at em ent is execut ed. NULL before t he st at em ent .

SQL% FOUND

TRUE if one or m ore rows were insert ed, m erged, updat ed, or delet ed or if only one row was select ed. FALSE if no row was select ed, m erged, updat ed, insert ed, or delet ed. NULL before t he st at em ent .

SQL% NOTFOUND

TRUE if no row was select ed, m erged, updat ed, insert ed, or delet ed. FALSE if one or m ore rows were insert ed, m erged, updat ed, or delet ed.

SQL% ROWCOUNT

Num ber of rows affect ed by t he cursor.

Pseudo index- by t able cont aining t he num bers of rows affect ed by t he st at em ent s SQL% BULK_ROWCOUNT execut ed in bulk bind operat ions. See Sect ion 1.17.8 for m ore inform at ion. ( I nt roduced wit h Oracle8 i.) Use t he RETURNI NG clause in I NSERT, UPDATE, and DELETE st at em ent s t o obt ain dat a m odified by t he associat ed DML st at em ent . This clause allows you t o avoid an addit ional SELECT st at em ent t o query t he result s of t he DML st at em ent . For exam ple:

BEGIN UPDATE activity SET last_accessed := SYSDATE WHERE UID = user_id RETURNING last_accessed, cost_center INTO timestamp, chargeback_acct; 1.9.2.1 SELECT FOR UPDATE clause By default , t he Oracle RDBMS locks rows as t hey are changed. To lock all rows in a result set , use t he FOR UPDATE clause in your SELECT st at em ent when you OPEN t he cursor, inst ead of when you change t he dat a. Using t he FOR UPDATE clause does not require you t o act ually m ake changes t o t he dat a; it only locks t he rows when opening t he cursor. These locks are released on t he next COMMI T or ROLLBACK. As always, t hese

row locks do not affect ot her SELECT st at em ent s unless t hey, t oo, are FOR UPDATE. The FOR UPDATE clause is appended t o t he end of t he SELECT st at em ent and has t he following synt ax:

SELECT ... FROM ... FOR UPDATE [OF column_reference] [NOWAIT]; where colum n_reference is a com m a- delim it ed list of colum ns t hat appear in t he SELECT clause. The NOWAI T keyword t ells t he RDBMS t o not wait for ot her blocking locks t o be released. The default is t o wait forever. I n t he following exam ple, only colum ns from t he invent ory ( pet ) t able are referenced FOR UPDATE, so no rows in t he dog_breeds ( dog) t able are locked when hounds_in_st ock_cur is opened:

DECLARE CURSOR hounds_in_stock_cur IS SELECT pet.stock_no, pet.breeder, dog.size FROM dog_breeds dog ,inventory pet WHERE dog.breed = pet.breed AND dog.class = 'HOUND' FOR UPDATE OF pet.stock_no, pet.breeder; BEGIN 1.9.2.2 WHERE CURRENT OF clause UPDATE and DELETE st at em ent s can use a WHERE CURRENT OF clause if t hey reference a cursor declared FOR UPDATE. This synt ax indicat es t hat t he UPDATE or DELETE should m odify t he current row ident ified by t he FOR UPDATE cursor. The synt ax is:

[UPDATE | DELETE ] ... WHERE CURRENT OF cursor_name; By using WHERE CURRENT OF, you do not have t o repeat t he WHERE clause in t he SELECT st at em ent . For exam ple:

DECLARE CURSOR wip_cur IS SELECT acct_no, enter_date FROM wip WHERE enter_date < SYSDATE - 7 FOR UPDATE; BEGIN FOR wip_rec IN wip_cur LOOP INSERT INTO acct_log (acct_no, order_date) VALUES (wip_rec.acct_no, wip_rec.enter_ date); DELETE FROM wip WHERE CURRENT OF wip_cur; END LOOP; END; 1.9.3 Dynamic Cursors Dynam ic cursors are im plem ent ed wit h an EXECUTE I MMEDI ATE st at em ent t oget her wit h t he OPEN FOR, FETCH, and CLOSE st at em ent s. The EXECUTE I MMEDI ATE st at em ent support s single- row queries and DDL, while t he OPEN FOR, FETCH, and CLOSE st at em ent s support dynam ic m ult i- row queries. The synt ax for t hese st at em ent s is:

EXECUTE IMMEDIATE sql_statement [INTO {variable [,variable ...] | record}] [USING [IN | OUT | IN OUT] bind_argument [,[IN | OUT | IN OUT] bind_argument ...] ] [{RETURNING | RETURN} INTO bind_argument [,bind_argument]...]; The EXECUTE I MMEDI ATE st at em ent parses and execut es t he SQL st at em ent in a single st ep. The EXECUTE I MMEDI ATE st at em ent requires a t erm inat ing sem icolon, but t he sql_st at em ent m ust not have a t railing sem icolon. For exam ple:

EXECUTE IMMEDIATE 'TRUNCATE TABLE foo'; EXECUTE IMMEDIATE 'GRANT SELECT ON '|| tabname_v || ' TO ' || grantee_list; The OPEN FOR st at em ent assigns a m ult i- row query t o a weakly t yped cursor variable. The rows are t hen FETCHed and t he cursor CLOSEd:

DECLARE TYPE cv_typ IS REF CURSOR; cv cv_typ; laccount_no NUMBER; lbalance NUMBER; BEGIN OPEN cv FOR 'SELECT account_no, balance FROM accounts WHERE balance < 500'; LOOP FETCH cv INTO laccount_no, lbalance; EXIT WHEN cv%NOTFOUND; -- Process the row. END LOOP; CLOSE cv; END; Because SQL st at em ent s usually execut e repeat edly, declare your dynam ic cursor wit h bind variables and pass t he values t o Oracle at runt im e. The parsed form of t he st at em ent can be reused from t he shared pool, im proving perform ance. For exam ple:

EXECUTE IMMEDIATE 'INSERT INTO hr.regions (region_id, region_name) VALUES (:r_id, :r_name)' USING id, name; 1.9.4 Cursor Variables A cursor variable is a dat a st ruct ure t hat point s t o a cursor obj ect , which in t urn point s t o t he cursor's result set . You can use cursor variables t o m ore easily ret rieve rows in a result set from client and server program s. You can also use cursor variables t o hide m inor variat ions in queries. The synt ax for a REF_CURSOR t ype ( cursor variable) is:

TYPE ref_cursor_name IS REF CURSOR [RETURN record_type]; I f you do not include a RETURN clause, t hen you are declaring a weak REF CURSOR. Cursor variables declared from weak REF CURSORs can be associat ed wit h any query at runt im e. A REF CURSOR declarat ion wit h a

RETURN clause defines a " st rong" REF CURSOR. A cursor variable based on a st rong REF CURSOR can be associat ed wit h queries whose result set s m at ch t he num ber and dat at ype of t he record st ruct ure aft er t he RETURN at runt im e. To use cursor variables, you m ust first creat e a REF_CURSOR t ype, t hen declare a cursor variable based on t hat t ype. The following exam ple shows t he use of bot h weak and st rong REF CURSORs:

DECLARE -- Create a cursor type based on the company's table. TYPE company_curtype IS REF CURSOR RETURN companies%ROWTYPE; -- Create the variable based on the REF CURSOR. company_cur company_curtype; -- And now the weak, general approach. TYPE any_curtype IS REF CURSOR; generic_curvar any_curtype; The synt ax t o OPEN a cursor variable is:

OPEN cursor_name FOR SELECT_statement; FETCH and CLOSE a cursor variable using t he sam e synt ax as for explicit cursors. There are a num ber of rest rict ions on cursor variables:

You cannot declare package- level cursor variables because t hey do not have a persist ent st at e. ( You can declare t hem in packaged procedures and funct ions, however.) You cannot assign NULLs t o a cursor variable nor can you use com parison operat ors t o t est for equalit y, inequalit y, or nullit y. Neit her dat abase colum ns nor collect ions can st ore cursor variables. You cannot use RPCs t o pass cursor variables from one server t o anot her.

1.9.5 Cursor Expressions A cursor expression is a cursor t hat is used as a colum n expression in t he SELECT list of an explicit cursor. The synt ax for a cursor expression is:

CURSOR (subquery) Cursor expressions can reduce t he am ount of redundant dat a ret urned t o a calling program over t echniques t hat involve j oining t he t ables t oget her. The cursor expression is aut om at ically opened when t he parent row is fet ched. Cursor expressions can be nest ed as well. These nest ed cursors are closed when one of t he following occurs:

The nest ed cursor is explicit ly closed by t he program . The parent cursor is closed.

The parent cursor is re- execut ed. An except ion is raised during t he fet ch of t he parent row. An exam ple of a cursor expression follows:

DECLARE TYPE refcursor IS REF CURSOR; CURSOR order_cur IS SELECT o.order_date ,o.order_status ,CURSOR(SELECT p.translated_name ,i.unit_price ,i.quantity FROM oe.order_items i ,oe.product_descriptions p WHERE i.product_id = p.product_id AND i.order_id = o.order_id) FROM oe.orders o WHERE order_date BETWEEN TO_DATE('01-Jan-03') AND TO_DATE('31-Jan_03'); odate oe.orders.order_date%TYPE; ostatus oe.orders.order_status%TYPE; od_cur refcursor; tname oe.product_descriptions.translated_name%TYPE; price oe.order_items.unit_price%TYPE; qty oe.order_items.quantity%TYPE; BEGIN OPEN order_cur; LOOP FETCH order_cur INTO odate, ostatus, od_cur; EXIT WHEN order_cur%NOTFOUND; LOOP FETCH od_cur INTO tname, price, qty; EXIT WHEN od_cur%NOTFOUND; DBMS_OUTPUT.PUT_LINE(odate||','||ostatus ||','||tname||','||price||','||qty); END LOOP; END LOOP; CLOSE order_cur; END; [ Team LiB ]

[ Team LiB ]

1.10 Exception Handling PL/ SQL allows developers t o raise and handle errors ( except ions) in a very flexible and powerful way. Each PL/ SQL block can have it s own except ion sect ion in which except ions can be t rapped and handled ( resolved or passed on t o t he enclosing block) . When an except ion occurs ( is raised) in a PL/ SQL block, it s execut ion sect ion im m ediat ely t erm inat es. Cont rol is passed t o t he except ion sect ion. Every except ion in PL/ SQL has an error num ber and error m essage; som e except ions also have nam es.

1.10.1 Declaring Exceptions Som e except ions ( see t he following t able) have been pre- defined by Oracle in t he STANDARD package or ot her built - in packages, such as UTL_FI LE. You can also declare your own except ions as follows:

DECLARE exception_name EXCEPTION; Er r or

N a m e d e x ce pt ion

ORA- 00001

DUP_VAL_ON_I NDEX

ORA- 00051

TI MEOUT_ON_RESOURCE

ORA- 00061

TRANSACTI ON_BACKED_OUT

ORA- 01001

I NVALI D_CURSOR

ORA- 01012

NOT_LOGGED_ON

ORA- 01017

LOGI N_DENI ED

ORA- 01403

NO_DATA_FOUND

ORA- 01410

SYS_I NVALI D_ROWI D

ORA- 01422

TOO_MANY_ROWS

ORA- 01476

ZERO_DI VI DE

ORA- 01725

USERENV_COMMMI TSCN_ERROR

ORA- 01722

I NVALI D_NUMBER

ORA- 06500

STORAGE_ERROR

ORA- 06501

PROGRAM_ERROR

ORA- 06502

VALUE_ERROR

ORA- 06504

ROWTYPE_MI SMATCH

ORA- 06511

CURSOR_ALREADY_OPEN

ORA- 06530

ACCESS_I NTO_NULL

ORA- 06531

COLLECTI ON_I S_NULL

ORA- 06532

SUBSCRI PT_OUTSI DE_LI MI T

ORA- 06533

SUBSCRI PT_BEYOND_COUNT

ORA- 09592

CASE_NOT_FOUND

ORA- 30625

SELF_I S_NULL

ORA- 29280

I NVALI D_PATH

ORA- 29281

I NVALI D_MODE

ORA- 29282

I NVALI D_FI LEHANDLE

ORA- 29283

I NVALI D_OPERATI ON

ORA- 29284

READ_ERROR

ORA- 29285

WRI TE_ERROR

ORA- 29286

I NTERNAL_ERROR

ORA- 29287

I NVALI D_MAXLI NESI ZE

ORA- 29288

I NVALI D_FI LENAME

ORA- 29289

ACCESS_DENI ED

ORA- 29290

I NVALI D_OFFSET

ORA- 29291

DELETE_FAI LED

ORA- 29292

RENAME_FAI LED

An except ion can be declared only once in a block, but nest ed blocks can declare an except ion wit h t he sam e nam e as an out er block. I f t his m ult iple declarat ion occurs, scope t akes precedence over nam e when handling t he except ion. The inner block's declarat ion t akes precedence over a global declarat ion. When you declare your own except ion, you m ust RAI SE it explicit ly. All declared except ions have an error code of 1 and t he error m essage " User- defined except ion," unless you use t he EXCEPTI ON_I NI T pragm a. You can associat e an error num ber wit h a declared except ion wit h t he PRAGMA EXCEPTI ON_I NI T st at em ent using t he following synt ax:

DECLARE exception_name EXCEPTION; PRAGMA EXCEPTION_INIT (exception_name, error_number); where error_num ber is a lit eral value ( variable references are not allowed) . This num ber can be an Oracle error, such as - 1855, or an error in t he user- definable - 20000 t o - 20999 range.

1.10.2 Raising Exceptions An except ion can be raised in t hree ways:

By t he PL/ SQL runt im e engine By an explicit RAI SE st at em ent in your code By a call t o t he built - in funct ion RAI SE_APPLI CATI ON_ERROR The synt ax for t he RAI SE st at em ent is:

RAISE exception_name; where except ion_nam e is t he nam e of an except ion t hat you have declared, or an except ion t hat is declared in t he STANDARD package. I f you use t he RAI SE st at em ent inside an except ion handler, you can om it t he except ion nam e t o re- raise t he current except ion:

RAISE; This synt ax is not valid out side t he except ion sect ion.

The RAI SE_APPLI CATI ON_ERROR built - in funct ion has t he following header:

RAISE_APPLICATION_ERROR ( num BINARY_INTEGER, msg VARCHAR2, keeperrorstack BOOLEAN DEFAULT FALSE); where num is t he error num ber ( an int eger bet ween - 20999 and - 20000) , m sg is t he associat ed error m essage, and keeperrorst ack cont rols t he cont ent s of t he error st ack.

1.10.3 Scope The scope of an except ion sect ion is t hat port ion of t he code t hat is " covered" by t he except ion sect ion. An except ion handler will only handle or at t em pt t o handle except ions raised in t he execut able sect ion of t he PL/ SQL block. Except ions raised in t he declarat ion or except ion sect ions are aut om at ically passed t o t he out er block. Any line or set of PL/ SQL code can be placed inside it s own block and given it s own except ion sect ion. This allows you t o lim it t he propagat ion of an except ion.

1.10.4 Propagation Except ions raised in a PL/ SQL block propagat e t o an out er block if t hey are unhandled or re- raised in t he except ion sect ion. When an except ion occurs, PL/ SQL looks for an except ion handler t hat checks for t he except ion ( or is t he WHEN OTHERS clause) in t he current block. I f a m at ch is not found, t hen PL/ SQL propagat es t he except ion t o t he enclosing block or calling program . This propagat ion cont inues unt il t he except ion is handled or propagat ed out of t he out erm ost block, back t o t he calling program . I n t his case, t he except ion is " unhandled" and ( 1) st ops t he calling program , and ( 2) causes an aut om at ic rollback of any out st anding t ransact ions. Once an except ion is handled, it will not propagat e upward. I f you want t o t rap an except ion, display a m eaningful error m essage, and have t he except ion propagat e upward as an error, you m ust re- raise t he except ion. The RAI SE st at em ent can re- raise t he current except ion or raise a new except ion, as shown here:

PROCEDURE delete_dept(deptno_in IN NUMBER) DECLARE still_have_employees EXCEPTION PRAGMA EXCEPTION_INIT(still_have_employees. -2292) BEGIN DELETE FROM dept WHERE deptno = deptno_in; EXCEPTION WHEN still_have_employees THEN DBMS_OUTPUT.PUT_LINE ('Please delete employees in dept first'); ROLLBACK; RAISE; /* Re-raise the current exception. */ END; 1.10.4.1 WHEN OTHERS clause Use t he WHEN OTHERS clause in t he except ion handler as a cat ch- all t o t rap any except ions t hat are not handled by specific WHEN clauses in t he except ion sect ion. I f present , t his clause m ust be t he last except ion

handler in t he except ion sect ion. You specify t his clause as follows:

EXCEPTION WHEN OTHERS THEN ... 1.10.4.2 SQLCODE and SQLERRM SQLCODE and SQLERRM are built - in funct ions t hat provide t he SQL error code and m essage for t he current except ion. Use t hese funct ions inside t he except ion sect ion's WHEN OTHERS clause t o handle specific errors by num ber. The EXCEPTI ON_I NI T pragm a allows you t o handle errors by nam e. For exam ple, t he following code:

CREATE TABLE err_test (widget_name VARCHAR2(100) ,widget_count NUMBER ,CONSTRAINT no_small_numbers CHECK (widget_count > 1000)); BEGIN INSERT INTO err_test (widget_name, widget_count) VALUES ('Athena',2); EXCEPTION WHEN OTHERS THEN IF SQLCODE = -2290 AND SQLERRM LIKE '%NO_SMALL_NUMBERS%' THEN DBMS_OUTPUT.PUT_LINE('widget_count is too small'); ELSE DBMS_OUTPUT.PUT_LINE('Exception not handled,' ||'SQLcode='||SQLCODE); DBMS_OUTPUT.PUT_LINE(SQLERRM); END IF; END; produces t his out put :

widget_count is too small The built - in package DBMS_UTI LI TY's FORMAT_ERROR_STACK and FORMAT_CALL_STACK procedures can be used t o capt ure t he full error st ack and call st ack. See t he book Oracle Built - in Packages for m ore inform at ion on DBMS_UTI LI TY.

1.10.4.3 Exceptions and DML When an except ion is raised in a PL/ SQL block, it does not roll back your current t ransact ion, even if t he block it self issued an I NSERT, UPDATE, or DELETE. You m ust issue your own ROLLBACK st at em ent if you want t o clean up your t ransact ion as a result of t he except ion. I f your except ion goes unhandled ( propagat es out of t he out erm ost block) , however, m ost host environm ent s will t hen force an aut om at ic, unqualified rollback of any out st anding changes in your session.

[ Team LiB ]

[ Team LiB ]

1.11 Records in PL/SQL A PL/ SQL record is a dat a st ruct ure com posed of m ult iple pieces of inform at ion called fields. To use a record, you m ust first define it and declare a variable of t his t ype. There are t hree t ypes of records: t able- based, cursor- based, and program m er- defined.

1.11.1 Declaring Records You define and declare records eit her in t he declarat ion sect ion of a PL/ SQL block or globally, via a package specificat ion. You do not have t o explicit ly define t able- based or cursor- based records, as t hey are im plicit ly defined wit h t he sam e st ruct ure as a t able or a cursor. Variables of t hese t ypes are declared via t he % ROWTYPE at t ribut e. The record's fields correspond t o t he t able's colum ns or t he colum ns in t he SELECT list . For exam ple:

DECLARE -- Declare table-based record for company table. comp_rec company%ROWTYPE CURSOR comp_summary_cur IS SELECT C.company_id,SUM(S.gross_sales) gross FROM company C ,sales S WHERE C.company_id = S.company_id; -- Declare a cursor-based record. comp_summary_rec comp_summary_cur%ROWTYPE; Program m er- defined records m ust be explicit ly defined wit h t he TYPE st at em ent in t he PL/ SQL declarat ion sect ion or in a package specificat ion. Variables of t his t ype can t hen be declared as shown here:

DECLARE TYPE name_rectype IS RECORD( prefix VARCHAR2(15) ,first_name VARCHAR2(30) ,middle_name VARCHAR2(30) ,sur_name VARCHAR2(30) ,suffix VARCHAR2(10) ); TYPE employee_rectype IS RECORD ( emp_id NUMBER(10) NOT NULL ,mgr_id NUMBER(10) ,dept_no dept.deptno%TYPE ,title VARCHAR2(20) ,name empname_rectype ,hire_date DATE := SYSDATE ,fresh_out BOOLEAN ); -- Declare a variable of this type. new_emp_rec employee_rectype; BEGIN

1.11.2 Referencing Fields of Records I ndividual fields are referenced via dot not at ion:

record_name.field_name For exam ple:

employee.first_name I ndividual fields wit hin a record can be read from or writ t en t o. They can appear on eit her t he left or right side of t he assignm ent operat or:

BEGIN insurance_start_date := new_emp_rec.hire_date + 30; new_emp_rec.fresh_out := FALSE; ... 1.11.3 Record Assignment An ent ire record can be assigned t o anot her record of t he sam e t ype, but one record cannot be com pared t o anot her record via Boolean operat ors. This is a valid assignm ent :

shipto_address_rec := customer_address_rec This is not a valid com parison:

IF shipto_address_rec = customer_address_rec THEN ... END IF; The individual fields of t he records need t o be com pared inst ead. Values can be assigned t o records or t o t he fields wit hin a record in four different ways:

The assignm ent operat or can be used t o assign a value t o a field:

new_emp_rec.hire_date := SYSDATE; You can SELECT I NTO a whole record or t he individual fields:

SELECT INTO FROM WHERE

emp_id,dept,title,hire_date,college_recruit new_emp_rec emp surname = 'LI'

You can FETCH I NTO a whole record or t he individual fields:

FETCH emp_cur INTO new_emp_rec; FETCH emp_cur INTO new_emp_rec.emp_id, new_emp_rec.name; You can assign all of t he fields of one record variable t o anot her record variable of t he sam e t ype:

IF rehire THEN new_emp_rec := former_emp_rec; ENDIF;

This aggregat e assignm ent t echnique works only for records declared wit h t he sam e TYPE st at em ent .

1.11.4 Nested Records Nest ed records are records cont ained in fields t hat are records t hem selves. Nest ing records is a powerful way t o norm alize dat a st ruct ures and hide com plexit y wit hin PL/ SQL program s. For exam ple:

DECLARE -- Define a record. TYPE phone_rectype IS RECORD ( area_code VARCHAR2(3), exchange VARCHAR2(3), phn_number VARCHAR2(4), extension VARCHAR2(4)); -- Define a record composed of records. TYPE contact_rectype IS RECORD ( day_phone# phone_rectype, eve_phone# phone_rectype, cell_phone# phone_rectype); -- Declare a variable for the nested record. auth_rep_info_rec contact_rectype; BEGIN

[ Team LiB ]

[ Team LiB ]

1.12 Named Program Units PL/ SQL allows you t o creat e a variet y of nam ed program unit s, or cont ainers for code. These include: Procedure A program t hat execut es one or m ore st at em ent s Funct ion A program t hat ret urns a value Package A cont ainer for procedures, funct ions, and dat a st ruct ures Trigger A program t hat execut es in response t o dat abase changes Obj ect t ype Oracle's version of an obj ect - orient ed class; obj ect t ypes can cont ain m em ber procedures and funct ions

1.12.1 Procedures Procedures are program unit s t hat execut e one or m ore st at em ent s and can receive or ret urn zero or m ore values t hrough t heir param et er list s. The synt ax of a procedure is:

CREATE [OR REPLACE] PROCEDURE name [ (parameter [,parameter]) ] [AUTHID { CURRENT_USER | DEFINER } ] [DETERMINISTIC] { IS | AS } declaration_section BEGIN executable_section [EXCEPTION exception_section] END [name]; A procedure is called as a st andalone execut able PL/ SQL st at em ent :

apply_discount(new_company_id, 0.15); 1.12.2 Functions Funct ions are program unit s t hat execut e zero or m ore st at em ent s and ret urn a value t hrough t he RETURN clause. Funct ions can also receive or ret urn zero or m ore values t hrough t heir param et er list s. The synt ax of a funct ion is:

CREATE [OR REPLACE] FUNCTION name [ (parameter [,parameter]) ] RETURN return_datatype [AUTHID { CURRENT_USER | DEFINER } ]

[DETERMINISTIC] [PARALLEL_ENABLE] [PIPELINED] [AGGREGATE USING] { IS | AS } [declaration_section] BEGIN executable_section [EXCEPTION exception_section] END [name]; A funct ion m ust have at least one RETURN st at em ent in t he execut ion sect ion. The RETURN clause in t he funct ion header specifies t he dat at ype of t he ret urned value. See Sect ion 1.12.3.9 for inform at ion on t he keywords OR REPLACE, AUTHI D, DETERMI NI STI C, PARALLEL_ENABLE, PI PELI NED, and AGGREGATE USI NG. See Sect ion 1.12.3.11 for addit ional inform at ion on AUTHI D. A funct ion can be called anywhere t hat an expression of t he sam e t ype can be used. You can call a funct ion:

I n an assignm ent st at em ent :

sales95 := tot_sales(1995,'C'); To set a default value:

DECLARE sales95 NUMBER DEFAULT tot_sales(1995,'C'); BEGIN I n a Boolean expression:

IF tot_sales(1995,'C') > 10000 THEN ... I n a SQL st at em ent :

SELECT first_name ,surname FROM sellers WHERE tot_sales(1995,'C') > 1000; As an argum ent in anot her program unit 's param et er list . Here, for exam ple, m ax_discount is a program m er- defined funct ion and SYSDATE is a built - in funct ion:

apply_discount(company_id, max_discount(SYSDATE)); 1.12.3 Parameters Procedures, funct ions, and cursors m ay have a param et er list . This list cont ains one or m ore param et ers t hat allow you t o pass inform at ion back and fort h bet ween t he sub- program and t he calling program . Each param et er is defined by it s nam e, dat at ype, m ode, and opt ional default value. The synt ax for a param et er is:

parameter_name [mode] [NOCOPY] datatype [ { := | DEFAULT } value] 1.12.3.1 Datatype

The dat at ype can be any PL/ SQL or program m er- defined dat at ype, but cannot be const rained by a size ( NUMBER is valid, NUMBER( 10) is not valid) . The act ual size of t he param et er is det erm ined from t he calling program or via a % TYPE const raint .

CREATE OR REPLACE PROCEDURE empid_to_name (in_id emp.emp_id%TYPE -- Compiles OK. ,out_last_name VARCHAR2 -- Compiles OK. ,out_first_name VARCHAR2(10) -- Won't compile. ) IS ... The lengt hs of out _last _nam e and out _first _nam e are det erm ined by t he calling program :

DECLARE surname VARCHAR2(10); first_name VARCHAR2(10); BEGIN empid_to_name(10, surname, first_name); END; 1.12.3.2 Mode The m ode of a param et er specifies whet her t he param et er can be read from or writ t en t o, as shown in t he following t able:

M ode

D e scr ipt ion

Pa r a m e t e r u sa ge

IN

Read- only

The value of t he act ual param et er can be referenced inside t he program , but t he param et er cannot be changed.

OUT or I N OUT

Read/ writ e

The program can bot h reference ( read) and m odify ( writ e) t he param et er.

I f t he m ode is not explicit ly defined, it default s t o I N. OUT param et ers are not t he sam e as I N OUT param et ers. When running t he called program , t he runt im e engine ignores ( set s t o NULL) any argum ent value you supply for an OUT param et er; it preserves t he value provided for an I N OUT. I f an except ion is raised during execut ion of a procedure or funct ion, assignm ent s m ade t o OUT or I N OUT param et ers get rolled back unless t he param et er includes t he NOCOPY opt ion. The NOCOPY com piler hint for param et ers m akes t he param et er a call by reference inst ead of a call by value. Norm ally, PL/ SQL passes I N/ OUT param et ers by value—a copy of t he param et er is creat ed for t he subprogram . When param et er it em s get large, as collect ions and obj ect s do, t he copy can eat m em ory and slow down processing. NOCOPY direct s PL/ SQL t o pass t he param et er by reference, using a point er t o t he single copy of t he param et er. The disadvant age of NOCOPY is t hat when an except ion is raised during execut ion of a program t hat has m odified an OUT or I N OUT param et er, t he changes t o t he act ual param et ers are not " rolled back" because t he param et ers were passed by reference inst ead of being copied.

1.12.3.3 Default values I N param et ers can be given default values. I f an I N param et er has a default value, t hen you do not need t o supply an argum ent for t hat param et er when you call t he program unit . I t aut om at ically uses t he default value. For exam ple:

CREATE OR REPLACE PROCEDURE hire_employee (emp_id IN VARCHAR2 ,hire_date IN DATE := SYSDATE ,company_id IN NUMBER := 1 ) IS ... Here are som e exam ple calls t o t he above procedure:

-- Use two default values. hire_employee(new_empno); -- Use one default value. hire_employee(new_empno,'12-Jan-1999'); -- Use non-trailing default value, named notation. hire_employee(emp_id=>new_empno, comp_id=>12); 1.12.3.4 Parameter-passing notations Form al param et ers are t he nam es t hat are declared in t he header of a procedure or funct ion. Act ual param et ers ( argum ent s) are t he values or expressions placed in t he param et er list when a procedure or funct ion is called. I n t he em pid_t o_nam e exam ple shown earlier in Sect ion 1.12.3.1, t he act ual param et ers t o t he procedure are in_id, out _last _nam e, and out _first _nam e. The form al param et ers used in t he call t o t his procedure are 10, surnam e, and first _nam e. PL/ SQL let s you use eit her of t wo st yles for passing argum ent s in param et er list s: posit ional not at ion or nam ed not at ion. Posit ional not at ion The default . Each value in t he list of argum ent s supplied in t he program call is associat ed wit h t he param et er in t he corresponding posit ion. Nam ed not at ion Explicit ly associat es t he argum ent value wit h it s param et er by nam e ( not posit ion) . When you use nam ed not at ion, you can supply t he argum ent s in any order and you can om it I N argum ent s t hat have default values. The call t o t he em pid_t o_nam e procedure is shown here wit h bot h not at ions:

BEGIN -- Implicit positional notation. empid_to_name(10, surname, first_name); -- Explicit named notation. empid_to_name(in_id=>10 ,out_last_name=>surname ,out_first_name=>first_name); END; You m ay com bine posit ional and nam ed not at ion, as long as posit ional argum ent s appear t o t he left of any nam ed not at ion argum ent s; for exam ple:

empid_to_name(10, surname, out_first_name => first_name); When calling st ored funct ions from SQL, nam ed not at ion is not support ed.

1.12.3.5 Local programs A local program is a procedure or funct ion t hat is defined in t he declarat ion sect ion of a PL/ SQL block. The declarat ion of a local program m ust appear at t he end of t he declarat ion sect ion, aft er t he declarat ions of any t ypes, records, cursors, variables, and except ions. A program defined in a declarat ion sect ion m ay only be referenced wit hin t hat block's execut able and except ion sect ions. I t is not defined out side t hat block. The following program defines a local procedure and funct ion:

PROCEDURE track_revenue IS l_total NUMBER; PROCEDURE calc_total (year_in IN INTEGER) IS BEGIN calculations here ... END; FUNCTION below_minimum (comp_id IN INTEGER) RETURN BOOLEAN IS BEGIN ... END; BEGIN ...main procedure logic here END; Local program s m ay be overloaded wit h t he sam e rest rict ions as overloaded packaged program s.

1.12.3.6 Program overloading PL/ SQL allows you t o define t wo or m ore program s wit h t he sam e nam e wit hin any declarat ion sect ion, including a package specificat ion or body. This is called over loading. I f t wo or m ore program s have t he sam e nam e, t hey m ust be different in som e ot her way so t hat t he com piler can det erm ine which program should be used. Here is an exam ple of overloaded program s in a built - in package specificat ion:

PACKAGE DBMS_OUTPUT IS PROCEDURE PUT_LINE (a VARCHAR2); PROCEDURE PUT_LINE (a NUMBER); PROCEDURE PUT_LINE (a DATE); END; Each PUT_LI NE procedure is ident ical, except for t he dat at ype of t he param et er. That is enough difference for t he com piler. To overload program s successfully, one or m ore of t he following condit ions m ust be t rue:

Param et ers m ust differ by dat at ype fam ily ( num ber, charact er, dat et im e, or Boolean) . The program t ype m ust be different ( you can overload a funct ion and a procedure of t he sam e nam e

and ident ical param et er list ) . The num bers of param et ers m ust be different . You cannot overload program s if:

Only t he dat at ypes of t he funct ions' RETURN clauses are different . Param et er dat at ypes are wit hin t he sam e fam ily ( CHAR and VARCHAR2, NUMBER and I NTEGER, et c.) . Only t he m odes of t he param et ers are different .

1.12.3.7 Forward declarations Program s m ust be declared before t hey can be used. PL/ SQL support s m ut ual recursion , in which program A calls program B, whereupon program B calls program A. To im plem ent t his m ut ual recursion, you m ust use a forward declarat ion of t he program s. This t echnique declares a program in advance of t he program definit ion, t hus m aking it available for ot her program s t o use. The forward declarat ion is t he program header up t o t he I S/ AS keyword:

PROCEDURE perform_calc(year_in IN NUMBER) IS /* Forward declaration for total_cost function. */ FUNCTION total_cost (...) RETURN NUMBER; /* The net_profit function can now use total_cost. */ FUNCTION net_profit(...) RETURN NUMBER IS BEGIN RETURN total_sales(...) - total_cost(...); END; /* The Total_cost function calls net_profit. */ FUNCTION total_cost (...) RETURN NUMBER IS BEGIN IF net_profit(...) < 0 THEN RETURN 0; ELSE RETURN...; END IF; END; BEGIN /* procedure perform_calc */ ... END perform_calc; 1.12.3.8 Table functions Table funct ions t ake a collect ion or REF CURSOR ( set of rows) as input and ret urn a collect ion of records ( set of rows) as out put . The PI PE ROW com m and is used t o ident ify t he input and out put st ream s. This st ream lined nat ure allows you t o pipeline t able funct ions t oget her, elim inat ing t he need t o st age t ables

bet ween t ransform at ions. Table funct ions t ypically appear in t he FROM clause of SQL st at em ent s. For exam ple:

CREATE FUNCTION pet_family (dad_in IN pet_t, mom_in IN pet_t) RETURN pet_nt PIPELINED IS l_count PLS_INTEGER; retval pet_nt := pet_nt ( ); BEGIN PIPE ROW (dad_in); PIPE ROW (mom_in);

-- identify streaming input -- identify streaming input

IF mom_in.breed = 'RABBIT' THEN l_count := 12; ELSIF mom_in.breed = 'DOG' THEN l_count := 4; ELSIF mom_in.breed = 'KANGAROO' THEN l_count := 1; END IF; FOR indx IN 1 .. l_count LOOP -- stream the results into the ouput pipeline PIPE ROW (pet_t ('BABY' || indx, mom_in.breed ,SYSDATE)); END LOOP; RETURN; END; 1.12.3.9 Compiling stored PL/SQL programs The following keywords are available when creat ing Oracle9i st ored program s: OR REPLACE Used t o rebuild an exist ing program unit , preserving privileges grant ed on it . AUTHI D Defines whet her t he program will execut e wit h t he privileges of, and resolve nam es like, t he obj ect owner ( DEFI NER) , or as t he user execut ing t he funct ion ( CURRENT_USER) . Prior t o Oracle8i, only t he built - in packages DBMS_SQL and DBMS_UTI LI TY execut ed as CURRENT_USER. The default AUTHI D is DEFI NER. DETERMI NI STI C Required for funct ion- based indexes. A funct ion is DETERMI NI STI C if it always ret urns t he sam e value when called wit h t he sam e param et ers. Det erm inist ic funct ions do not m eaningfully reference package variables or t he dat abase. The built - in I NI TCAP is det erm inist ic, but SYSDATE is not . PARALLEL_ENABLED [ ( PARTI TI ON in_parm BY { ANY HASH | RANGE} ) ] Tells t he opt im izer t hat a funct ion is safe for parallel execut ion. The PARTI TI ON BY clause is only available t o funct ions t hat have a REF CURSOR I N param et er. This clause is used wit h t able funct ions and t ells t he opt im izer how t he input can be part it ioned. PI PELI NED ( Oracle9i) Used wit h t able funct ions. Specifies t hat t he result s of t his t able funct ion should be ret urned it erat ively via t he PI PE ROW com m and. A pipelined funct ion can st art t o ret urn dat a as it is generat ed inst ead of all at once aft er processing is com plet e. AGGREGATE USI NG ( Oracle9i)

Required for aggregat e funct ions. Tells Oracle t hat t he funct ion evaluat es a group of rows and ret urns a single result . For exam ple, t he built - in funct ion AVG is an aggregat e funct ion.

1.12.3.10 Native compilation of PL/SQL (Oracle9i) Wit h Oracle9i you can speed up m any of your PL/ SQL program s by com piling t he st ored program s nat ively. Oracle will t ranslat e your PL/ SQL program int o C code and com pile it int o a shared library ( DLL on NT) . You m ust have a support ed C com piler on your dat abase server m achine t o use nat ive com pilat ion. To com pile nat ively, you m ust follow t hese st eps:

Edit t he m akefile, spnc_m akefile.m k, which you should find in t he $ORACLE_HOME/ plsql subdirect ory. Set t he init ializat ion param et er PLSQL_COMPI LER_FLAGS = ` NATI VE'. I ndividual developers m ay alt er t he value of PLSQL_COMPI LER_FLAGS using t he ALTER SESSI ON st at em ent . The following param et ers m any also need t o be set : PLSQL_NATI VE_C_COMPI LER, PLSQL_NATI VE_LI NKER, PLSQL_NATI VE_LI BRARY_DI R, PLSQL_NATI VE_MAKE_UTI LI TY, and PLSQL_NATI VE_MAKE_FI LE_NAME. The DBA can set t hese param et ers in t he Oracle init ializat ion file or using an ALTER SYSTEM st at em ent . Creat e or replace your st ored program s. Verify t he nat ive com pilat ion by querying t he dat a dict ionary view USER_STORED_SETTI NGS and also by locat ing t he shared library or DLL in t he dat abase server's file syst em .

1.12.3.11 Privileges and stored PL/SQL St ored SQL support s t wo m odels for addressing privileges at runt im e. The default is definer right s, which t ells Oracle t hat t he privileges of t he owner or definer of t he program should be used. Wit h t he definer right s m odel, t he owner of t he program m ust have t he required privileges grant ed direct ly t o him —he cannot inherit t he privileges from a role. Wit h invoker right s, t he user who execut es t he program does so using his own privileges. Anonym ous PL/ SQL blocks always execut e wit h invoker right s. To creat e a program t hat uses t he invoker right s m odel, include t he keywords AUTHI D CURRENT_USER in your program 's declarat ion.

[ Team LiB ]

[ Team LiB ]

1.13 Triggers Triggers are program s t hat execut e in response t o changes in t able dat a or cert ain dat abase event s. There is a predefined set of event s t hat can be " hooked" wit h a t rigger, enabling you t o int egrat e your own processing wit h t hat of t he dat abase. A t riggering event fires or execut es t he t rigger. There are t hree t ypes of t riggering event s:

DML event s fire when an I NSERT, UPDATE, or DELETE st at em ent execut es. DDL event s fire when a CREATE, ALTER, or DROP st at em ent execut es. Dat abase event s fire when one of t he predefined dat abase- level event s occurs. Com plet e list s of t hese event s are included in lat er sect ions.

1.13.1 Creating Triggers The synt ax for creat ing a t rigger on a DML event is:

CREATE [OR REPLACE] TRIGGER trigger_name { BEFORE | AFTER | INSTEAD OF } trigger_event ON {table_or_view_reference | NESTED TABLE nested_table_column OF view} [REFERENCING [OLD AS old] [NEW AS new] [PARENT AS parent]] [FOR EACH ROW ][WHEN trigger_condition] trigger_body; The synt ax for creat ing a t rigger on a DDL or dat abase event is:

CREATE [OR REPLACE] TRIGGER trigger_name { BEFORE | AFTER } trigger_event ON [ DATABASE | schema ] [WHEN trigger_condition] trigger_body; Trigger event s are list ed in t he following t able:

Tr igge r e ve n t

D e scr ipt ion

I NSERT

Fires whenever a row is added t o t he t able_or_view_reference.

UPDATE

Fires whenever an UPDATE changes t he t able_or_view_reference. UPDATE t riggers can addit ionally specify an OF clause t o rest rict firing t o updat es OF cert ain colum ns.

DELETE

Fires whenever a row is delet ed from t he t able_or_view_reference. Does not fire on a TRUNCATE of t he t able.

ALTER

Fires whenever an ALTER st at em ent changes a dat abase obj ect . I n t his cont ext , obj ect s are t hings like t ables or packages ( found in ALL_OBJECTS) . Can apply t o a single schem a or t he ent ire dat abase.

DROP

Fires whenever a DROP st at em ent rem oves an obj ect from t he dat abase. I n t his cont ext , obj ect s are t hings like t ables or packages ( found in ALL_OBJECTS) . Can apply t o a single schem a or t he ent ire dat abase.

SERVERERROR

Fires whenever a server error m essage is logged. Only AFTER t riggers are allowed in t his cont ext .

LOGON

Fires whenever a session is creat ed ( a user connect s t o t he dat abase) . Only AFTER t riggers are allowed in t his cont ext .

LOGOFF

Fires whenever a session is t erm inat ed ( a user disconnect s from t he dat abase) . Only BEFORE t riggers are allowed in t his cont ext .

STARTUP

Fires when t he dat abase is opened. Only AFTER t riggers are allowed in t his cont ext .

SHUTDOWN

Fires when t he dat abase is closed. Only BEFORE t riggers are allowed in t his cont ext .

Triggers can fire BEFORE or AFTER t he t riggering event . AFTER dat a t riggers are slight ly m ore efficient t han BEFORE t riggers. The REFERENCI NG clause is allowed only for t he dat a event s I NSERT, UPDATE, and DELETE. I t let s you give a non- default nam e t o t he old and new pseudo- records. These pseudo- records give t he program visibilit y t o t he pre- and post - change values in row- level t riggers. These records are defined like % ROWTYPE records, except t hat colum ns of t ype LONG or LONG RAW cannot be referenced. They are prefixed wit h a colon in t he t rigger body, and referenced wit h dot not at ion. Unlike ot her records, t hese fields can only be assigned individually—aggregat e assignm ent is not allowed. All old fields are NULL wit hin I NSERT t riggers, and all new fields are NULL wit hin DELETE t riggers. FOR EACH ROW defines t he t rigger t o be a row- level t rigger. Row- level t riggers fire once for each row affect ed. The default is a st at em ent - level t rigger, which fires only once for each t riggering st at em ent . The WHEN t rigger_condit ion specifies t he condit ions t hat m ust be m et for t he t rigger t o fire. St ored funct ions and obj ect m et hods are not allowed in t he t rigger condit ion. The t rigger body is a st andard PL/ SQL block. For exam ple:

CREATE OR REPLACE TRIGGER add_tstamp BEFORE INSERT ON emp REFERENCING NEW as new_row FOR EACH ROW BEGIN -- Automatically timestamp the entry. SELECT CURRENT_TIMESTAMP INTO :new_row.entry_timestamp FROM dual; END add_tstamp; Triggers are enabled on creat ion, and can be disabled ( so t hey do not fire) wit h an ALTER st at em ent , issued wit h t he following synt ax:

ALTER TRIGGER trigger_name { ENABLE | DISABLE }; ALTER TABLE table_name { ENABLE | DISABLE } ALL TRIGGERS; 1.13.2 Trigger Predicates When using a single t rigger for m ult iple event s, use t he t rigger predicat es I NSERTI NG, UPDATI NG, and DELETI NG in t he t rigger condit ion t o ident ify t he t riggering event , as shown in t his exam ple:

CREATE OR REPLACE TRIGGER emp_log_t AFTER INSERT OR UPDATE OR DELETE ON emp FOR EACH ROW DECLARE dmltype CHAR(1); BEGIN IF INSERTING THEN dmltype := 'I'; INSERT INTO emp_log (emp_no, who, operation) VALUES (:new.empno, USER, dmltype); ELSIF UPDATING THEN dmltype := 'U'; INSERT INTO emp_log (emp_no, who, operation) VALUES (:new.empno, USER, dmltype); END IF; END; 1.13.3 DML Events The DML event s include I NSERT, UPDATE, and DELETE st at em ent s on a t able or view. Triggers on t hese event s can be st at em ent - level t riggers ( t able only) or row- level t riggers and can fire BEFORE or AFTER t he t riggering event . BEFORE t riggers can m odify t he dat a in affect ed rows, but perform an addit ional logical read. AFTER t riggers do not perform t his addit ional logical read, and t herefore perform slight ly bet t er, but are not able t o change t he : new values. AFTER t riggers are t hus bet t er suit ed for dat a validat ion funct ionalit y. Triggers cannot be creat ed on SYS- owned obj ect s. The order in which t hese t riggers fire, if present , is as follows: BEFORE st at em ent - level t rigger For each row affect ed by t he st at em ent : BEFORE row- level t rigger The t riggering st at em ent AFTER row- level t rigger AFTER st at em ent - level t rigger

1.13.4 DDL Events The DDL event s are CREATE, ALTER, and DROP. These t riggers fire whenever t he respect ive DDL st at em ent is execut ed. DDL t riggers can apply t o eit her a single schem a or t he ent ire dat abase.

1.13.5 Database Events The dat abase event s are SERVERERROR, LOGON, LOGOFF, STARTUP, and SHUTDOWN. Only BEFORE t riggers are allowed for LOGOFF and SHUTDOWN event s. Only AFTER t riggers are allowed for LOGON, STARTUP, and

SERVERERROR event s. A SHUTDOWN t rigger will fire on a SHUTDOWN NORMAL and a SHUTDOWN I MMEDI ATE, but not on a SHUTDOWN ABORT.

[ Team LiB ]

[ Team LiB ]

1.14 Packages A package is a collect ion of PL/ SQL obj ect s t hat are grouped t oget her. There are a num ber of benefit s t o using packages, including inform at ion hiding, obj ect - orient ed design, t op- down design, obj ect persist ence across t ransact ions, and im proved perform ance. Elem ent s t hat can be placed in a package include procedures, funct ions, const ant s, variables, cursors, except ion nam es, and TYPE st at em ent s ( for associat ive arrays [ form erly known as index- by t ables] , records, REF CURSORs, et c.) .

1.14.1 Package Structure A package can have t wo part s: t he specificat ion and t he body. The package specificat ion is required and list s all t he obj ect s t hat are publicly available ( i.e., m ay be referenced from out side t he package) for use in applicat ions. I t also provides all t he inform at ion a developer needs in order t o use obj ect s in t he package; essent ially, it is t he package's API . The package body cont ains all t he code needed t o im plem ent procedures, funct ions, and cursors list ed in t he specificat ion, as well as any privat e obj ect s ( accessible only t o ot her elem ent s defined in t hat package) , and an opt ional init ializat ion sect ion. I f a package specificat ion does not cont ain any procedures or funct ions and no privat e code is needed, t hen t hat package does not need t o have a package body. The synt ax for t he package specificat ion is:

CREATE [OR REPLACE] PACKAGE package_name [ AUTHID { CURRENT_USER | DEFINER } ] { IS | AS } [definitions of public TYPEs ,declarations of public variables, types, and objects ,declarations of exceptions ,pragmas ,declarations of cursors, procedures, and functions ,headers of procedures and functions] END [package_name]; The synt ax for t he package body is:

CREATE [OR REPLACE] PACKAGE BODY package_name { IS | AS } [definitions of private TYPEs ,declarations of private variables, types, and objects ,full definitions of cursors

,full definitions of procedures and functions] [BEGIN executable_statements [EXCEPTION exception_handlers ] ] END [package_name]; The opt ional OR REPLACE keywords are used t o rebuild an exist ing package, preserving any EXECUTE privileges previously grant ed t o ot her account s. The declarat ions in t he specificat ions cannot be repeat ed in t he body. Bot h t he execut able sect ion and t he except ion sect ion are opt ional in a package body. I f t he execut able sect ion is present , it is called t he init ializat ion sect ion and it execut es only once—t he first t im e any package elem ent is referenced during a session. You m ust com pile t he package specificat ion before t he body specificat ion. When you grant EXECUTE aut horit y on a package t o anot her schem a or t o PUBLI C, you are giving access only t o t he specificat ion; t he body rem ains hidden. Here's an exam ple of a package:

CREATE OR REPLACE PACKAGE time_pkg IS FUNCTION GetTimestamp RETURN DATE; PRAGMA RESTRICT_REFERENCES (GetTimestamp, WNDS); PROCEDURE ResetTimestamp(new_time DATE DEFAULT SYSDATE); END time_pkg; CREATE OR REPLACE PACKAGE BODY time_pkg IS StartTimeStamp DATE := SYSDATE; -- StartTimeStamp is package data. FUNCTION GetTimestamp RETURN DATE IS BEGIN RETURN StartTimeStamp; END GetTimestamp; PROCEDURE ResetTimestamp(new_time DATE DEFAULT SYSDATE) IS BEGIN StartTimeStamp := new_time; END ResetTimestamp; END time_pkg; 1.14.2 Referencing Package Elements The elem ent s declared in t he specificat ion are referenced from t he calling applicat ion via dot not at ion:

package_name.package_element For exam ple, t he built - in package DBMS_OUTPUT has a procedure PUT_LI NE, so a call t o t his package would look like t his:

DBMS_OUTPUT.PUT_LINE('This is parameter data'); 1.14.3 Package Data Dat a st ruct ures declared wit hin a package specificat ion or body, but out side any procedure or funct ion in t he package, are package dat a. The scope of package dat a is your ent ire session, spanning t ransact ion boundaries and act ing as globals for your program s. Keep t he following guidelines in m ind as you work wit h package dat a:

The st at e of your package variables is not affect ed by COMMI Ts and ROLLBACKs. A cursor declared in a package has global scope. I t rem ains OPEN unt il you close it explicit ly or unt il your session ends. A good pract ice is t o hide your dat a st ruct ures in t he package body and provide " get and set " program s t o read and writ e t hat dat a. This t echnique can help prot ect your dat a.

1.14.4 SERIALLY_REUSABLE Pragma I f you need package dat a t o exist only during a call t o t he packaged funct ions or procedures, and not bet ween calls of t he current session, you can pot ent ially save runt im e m em ory by using t he pragm a SERI ALLY_REUSABLE. Aft er each call, PL/ SQL closes t he cursors and releases t he m em ory used in t he package. This t echnique is applicable only t o large user com m unit ies execut ing t he sam e rout ine. Norm ally, t he dat abase server's m em ory requirem ent s grow linearly wit h t he num ber of users; wit h SERI ALLY_REUSABLE, t his growt h can be less t han linear, because work areas for package st at es are kept in a pool in t he Oracle's Syst em Global Area ( SGA) and are shared am ong all users. This pragm a m ust appear in bot h t he specificat ion and t he body, as shown here:

CREATE OR REPLACE PACKAGE my_pkg IS PRAGMA SERIALLY_REUSABLE; PROCEDURE foo; END my_pkg; CREATE OR REPLACE PACKAGE BODY my_pkg IS PRAGMA SERIALLY_REUSABLE; PROCEDURE foo IS ... END my_pkg; 1.14.5 Package Initialization The first t im e a user references a package elem ent , t he ent ire package is loaded int o t he SGA of t he dat abase inst ance t o which t he user is connect ed. That code is t hen shared by all sessions t hat have EXECUTE aut horit y on t he package. Any package dat a are t hen inst ant iat ed int o t he session's User Global Area ( UGA) , a privat e area in eit her t he Syst em Global Area or t he Program Global Area ( PGA) . I f t he package body cont ains an init ializat ion sect ion, t hat code will be execut ed. The init ializat ion sect ion is opt ional and appears at t he end of t he package body, beginning wit h a BEGI N st at em ent and ending wit h t he EXCEPTI ON sect ion ( if present ) or t he END of t he package. The following package init ializat ion sect ion runs a query t o t ransfer t he user's m inim um balance int o a global package variable. Program s can t hen reference t he packaged variable ( via t he funct ion) t o ret rieve t he

balance, rat her t han execut e t he query r epeat edly :

CREATE OR REPLACE PACKAGE usrinfo IS FUNCTION minbal RETURN VARCHAR2; END usrinfo; / CREATE OR REPLACE PACKAGE BODY usrinfo IS g_minbal NUMBER; -- Package data FUNCTION minbal RETURN VARCHAR2 IS BEGIN RETURN g_minbal; END; BEGIN -- Initialization section SELECT minimum_balance INTO g_minbal FROM user_configuration WHERE username = USER; EXCEPTION WHEN NO_DATA_FOUND THEN g_minbal := NULL; END usrinfo; [ Team LiB ]

[ Team LiB ]

1.15 Calling PL/SQL Functions in SQL St ored funct ions can be called from SQL st at em ent s in a m anner sim ilar t o built - in funct ions like DECODE, NVL, or RTRI M. This is a powerful t echnique for incorporat ing business rules int o SQL in a sim ple and elegant way. Unfort unat ely, t here are a num ber of caveat s and rest rict ions. The m ost not able caveat is t hat st ored funct ions execut ed from SQL are not by default guarant eed t o follow t he st at em ent - level read consist ency m odel of t he dat abase. Unless t he SQL st at em ent and any st ored funct ions in t hat st at em ent are in t he sam e read- consist ent t ransact ion ( even if t hey are read- only) , each execut ion of t he st ored funct ion m ay look at a different t im e- consist ent set of dat a. To avoid t his pot ent ial problem , you need t o ensure read consist ency program m at ically by issuing t he SET TRANSACTI ON READ ONLY or SET TRANSACTI ON I SOLATI ON LEVEL SERI ALI ZABLE st at em ent before execut ing your SQL st at em ent cont aining t he st ored funct ion. A COMMI T or ROLLBACK t hen needs t o follow t he SQL st at em ent t o end t his read- consist ent t ransact ion.

1.15.1 Calling a Function The synt ax for calling a st ored funct ion from SQL is t he sam e as t hat used t o reference it from PL/ SQL:

[schema_name.][pkg_name.]func_name[@db_link] [parm_list] schem a_nam e is opt ional and refers t o t he user/ owner of t he funct ion or package. pkg_nam e is opt ional and refers t o t he package cont aining t he called funct ion. func_nam e is required and is t he funct ion nam e. db_link is opt ional and refers t o t he dat abase link nam e t o t he rem ot e dat abase cont aining t he funct ion. parm _list is opt ional, as are t he param et ers passed t o t he funct ion. The following are exam ple calls t o t he Get Tim est am p funct ion in t he t im e_pkg exam ple seen earlier in Sect ion 1.14.1:

-- Capture system events. INSERT INTO v_sys_event (timestamp ,event ,qty_waits) SELECT time_pkg.GetTimestamp ,event ,total_waits FROM v$system_event -- Capture system statistics. INSERT INTO v_sys_stat (timestamp,stat#,value) SELECT time_pkg.GetTimestamp ,statistic# ,value FROM v$sysstat; 1.15.2 Requirements and Restrictions There are a num ber of requirem ent s for calling st ored funct ions in SQL:

All param et ers m ust be I N; no I N OUT or OUT param et ers are allowed. The dat at ypes of t he funct ion's param et ers and RETURN m ust be com pat ible wit h RDBMS dat at ypes. You cannot have argum ent s or RETURN t ypes like BOOLEAN, program m er- defined record, associat ive array, et c.

The param et ers passed t o t he funct ion m ust use posit ional not at ion; nam ed not at ion is not support ed. The funct ion m ust be st ored in t he dat abase, not in a local program , Developer/ 2000 PL/ SQL library, or form .

1.15.3 Calling Packaged Functions in SQL Prior t o Oracle8i, it was necessary t o assert t he purit y level of a packaged procedure or funct ion when using it direct ly or indirect ly in a SQL st at em ent . Beginning wit h Oracle8i, t he PL/ SQL runt im e engine det erm ines a program 's purit y level aut om at ically if no assert ion exist s. The RESTRI CT_REFERENCES pragm a is st ill support ed for backward com pat ibilit y, but has been deprecat ed in Oracle9i. The RESTRI CT_REFERENCES pragm a assert s a purit y level. The synt ax for t he RESTRI CT_REFERENCES pragm a is:

PRAGMA RESTRICT_REFERENCES (program_name | DEFAULT, purity_level); The keyword DEFAULT applies t o all m et hods of an obj ect t ype or all program s in a package. There can be from one t o five purit y levels, in any order, in a com m a- delim it ed list . The purit y level describes t o what ext ent t he program or m et hod is free of side effect s. Side effect s are list ed in t he following t able wit h t he purit y levels t hey address:

Pu r it y le ve l

D e scr ipt ion

Re st r ict ion

WNDS

Writ e No Dat abase St at e

Execut es no I NSERT, UPDATE, or DELETE st at em ent s.

RNDS

Read No Dat abase St at e

Execut es no SELECT st at em ent s.

WNPS

Writ e No Package St at e

Does not m odify any package variables.

RNPS

Read No Package St at e

Does not read any package variables.

TRUST



Does not enforce t he rest rict ions declared but allows t he com piler t o t rust t hey are t rue.

1.15.4 Column/Function Name Precedence I f your funct ion has t he sam e nam e as a t able colum n in your SELECT st at em ent and t he funct ion has no param et er, t hen t he colum n t akes precedence over t he funct ion. To force t he RDBMS t o resolve t he nam e t o your funct ion, prepend t he schem a nam e t o it :

CREATE TABLE emp(new_sal NUMBER ...); CREATE FUNCTION new_sal RETURN NUMBER IS ...; SELECT new_sal FROM emp; SELECT scott.new_sal FROM emp; [ Team LiB ]

-- Resolves to column. -- Resolves to function.

[ Team LiB ]

1.16 Oracle's Object-Oriented Features I n Oracle, an obj ect t ype com bines at t ribut es ( dat a st ruct ures) and m et hods ( funct ions and procedures) int o a single program m ing const ruct . The obj ect t ype const ruct allows program m ers t o define t heir own reusable dat at ypes for use in PL/ SQL program s and t able and colum n definit ions. An obj ect t ype m ust be creat ed in a dat abase before it can be used in a PL/ SQL program . An inst ance of an obj ect t ype is an obj ect in t he sam e way t hat a variable is an inst ance of a scalar t ype. Obj ect s are eit her persist ent ( st ored in t he dat abase) or t ransient ( st ored only in PL/ SQL variables) . Obj ect s can be st ored in a dat abase as a row in a t able ( a row obj ect ) or as a colum n in a t able. A t able of row obj ect s can be creat ed wit h synt ax such as t his:

CREATE TABLE table_name OF object_type; When st ored in such a t able, t he obj ect ( row) has an OI D ( Obj ect I Dent ifier) t hat is unique t hroughout t he dat abase.

1.16.1 Object Types An obj ect t ype has t wo part s: t he specificat ion and t he body. The specificat ion is required and cont ains t he at t ribut es and m et hod specificat ions. The synt ax for creat ing t he obj ect t ype specificat ion is:

CREATE [OR REPLACE] TYPE obj_type_name [AUTHID { CURRENT_USER | DEFINER } ] { { IS | AS } OBJECT | UNDER parent_type_name } ( attribute_name datatype,..., [ [ [NOT] OVERRIDING ] [ {NOT] FINAL ] [ {NOT} INSTANTIABLE ] method_spec,...,] [PRAGMA RESTRICT_REFERENCES(program_name, purities)] ) [ [NOT] FINAL ] [ [NOT] INSTANTIABLE ]; Where m et hod_spec is one of t he following:

MEMBER { PROCEDURE | FUNCTION } program_spec or:

STATIC { PROCEDURE | FUNCTION } program_spec or:

{ ORDER | MAP } MEMBER FUNCTION comparison_function_spec or:

CONSTRUCTOR FUNCTION constructor_function_spec At t ribut e specificat ions m ust appear before m et hod specificat ions. Obj ect at t ribut es, like t able colum ns, are defined wit h a nam e and a dat at ype. The nam e can be any legal ident ifier, and t he dat at ype can be alm ost

any dat at ype known t o SQL ot her t han LONG, LONG RAW, ROWI D, and UROWI D. At t ribut es can be declared on ot her program m er- defined obj ect t ypes or collect ion t ypes, but not on t he Oracle9i t ypes ANYTYPE, ANYDATA, or ANYDATASET. At t ribut es cannot be of dat at ypes unique t o PL/ SQL, such as BOOLEAN. Met hod headers appear in t he obj ect t ype specificat ion in a com m a- delim it ed list . Unlike in a package specificat ion, com m as ( not sem icolons) t erm inat e t he obj ect t ype program specificat ions. To support obj ect com parisons and sort ing, t he t ype can opt ionally include one com parison m et hod—eit her ORDER or MAP. Mem ber m et hods can be overloaded in obj ect t ypes following t he sam e rules as funct ion and procedure overloading in packages. Met hod " specs" t hat appear above in t he synt ax can act ually be call specs for Java classes in t he dat abase or for ext ernal procedures writ t en in C. The synt ax for creat ing t he obj ect t ype body is:

CREATE [OR REPLACE] TYPE BODY obj_type_name { IS | AS } ( [ { ORDER | MAP } MEMBER FUNCTION comparison_function_body; ] [ { MEMBER | STATIC } { FUNCTION | PROCEDURE } program_body;]... ) ; Again, t he program bodies can be call specs t o Java or C program s. The keywords CONSTRUCTOR, UNDER, FI NAL, and I NSTANTI ABLE are all new wit h Oracle9i.

1.16.2 Type Inheritance (Oracle9i) Beginning wit h Oracle9i, you can define subt ypes of obj ect t ypes following a single- inherit ance m odel. Oracle does not have a m ast er root - level obj ect t ype of t he kind t hat you m ight find in ot her obj ect program m ing m odels; inst ead; each t ype is " st andalone" unless declared ot herwise. The UNDER keyword specifies t hat t he t ype exist s as a subt ype in a hierarchy. When you are using UNDER, t he parent t ype m ust be m arked NOT FI NAL. By default , t ypes are FI NAL, m eaning t hat you cannot declare a subt ype of t hat t ype. A subt ype cont ains all of t he at t ribut es and m et hods of it s parent ( supert ype) and m ay cont ain addit ional at t ribut es and m et hods. Met hods can override corresponding m et hods from t he parent . Changes t o t he supert ype—such as t he addit ion of at t ribut es or m et hods—are aut om at ically reflect ed in t he subt ypes. By default , obj ect t ypes are I NSTANTI ABLE—t hat is, an invoking program m ay creat e an obj ect of t hat t ype. The phrase NOT I NSTANTI ABLE t ells Oracle t hat you don't want any obj ect s of t he t ype, in which case Oracle will not creat e a const ruct or for it . This variat ion generally m akes sense only wit h t ypes t hat will serve as parent s of ot her t ypes.

1.16.3 Methods There are four kinds of m et hods: m em ber, st at ic, const ruct or, and com parison.

1.16.3.1 Member methods

A m em ber m et hod is a procedure or funct ion designat ed wit h t he keyword MEMBER. Calling program s m ay invoke such a m et hod only on obj ect s t hat have been inst ant iat ed.

1.16.3.2 Static methods A st at ic m et hod has no access t o a current ( SELF) obj ect . Such a m et hod is declared using t he keyword STATI C and can be invoked at any t im e using t ype.m et hod synt ax.

1.16.3.3 Constructor methods Even if you don't declare any m et hods, every inst ant iable obj ect has a default const ruct or m et hod which allows a calling program t o creat e new obj ect s of t hat t ype. This built - in m et hod:

Has t he sam e nam e as t he obj ect t ype I s a funct ion t hat ret urns an obj ect of t hat t ype Accept s at t ribut es in nam ed or posit ional not at ion Must be called wit h a value ( or NULL) for every at t ribut e—t here is no DEFAULT clause for obj ect at t r ibut es Cannot be m odified Oracle9i program m ers can replace t his default const ruct or wit h t heir own using t he CONSTRUCTOR FUNCTI ON synt ax. This m et hod m ust have t he sam e nam e as t he obj ect t ype, but t here are no rest rict ions on it s param et er list . The RETURN clause of t he const ruct or's header m ust be RETURN SELF AS RESULT. Oracle support s t he overloading of program m er- defined const ruct ors. All non- st at ic m et hods have t he im plied param et er SELF, which refers t o t he current inst ance of t he obj ect . The default m ode for t he SELF param et er is I N for funct ions and I N OUT for procedures. A program m er can alt er t he m ode by explicit ly including SELF in t he form al param et er list .

1.16.3.4 Comparison methods The com parison m et hods, ORDER and MAP, est ablish ordinal posit ions of obj ect s for com parisons such as " < " or " bet ween" and for sort ing ( ORDER BY, GROUP BY, DI STI NCT) . Oracle invokes a com parison m et hod aut om at ically whenever it needs t o perform such an operat ion. MAP and ORDER m et hods are act ually special t ypes of m em ber m et hods—t hat is, t hey only execut e in t he cont ext of an exist ing obj ect . An ORDER funct ion accept s t wo param et ers: SELF and anot her obj ect of t he sam e t ype. I t m ust ret urn an I NTEGER value as explained in t he following t able:

Re t u r n va lu e

Obj e ct com pa r ison

Any negat ive int eger ( com m only - 1) SELF < second obj ect 0

SELF = second obj ect

Any posit ive int eger ( com m only 1)

SELF > second obj ect

NULL

Undefined com parison: at t ribut es needed for t he com parison are NULL

For exam ple, t he Senat e ranks m aj orit y part y m em bers higher t han non- m aj orit y part y m em bers and wit hin t he m aj orit y ( or non- m aj orit y) by years of service. Here is an exam ple ORDER funct ion incorporat ing t hese

rules:

CREATE TYPE senator_t AS OBJECT ( majority boolean_t, yrs_service NUMBER, ORDER MEMBER FUNCTION ranking (other IN senator_t) RETURN INTEGER ); CREATE OR REPLACE TYPE BODY senator_t AS ORDER MEMBER FUNCTION ranking (other IN senator_t) RETURN INTEGER IS BEGIN IF SELF.majority.istrue( ) AND other.majority.istrue( ) THEN RETURN SIGN(SELF.yrs_service other.yrs_service); ELSIF SELF.majority.istrue( ) AND other.majority.isfalse( ) THEN RETURN 1; ELSIF SELF.majority.isfalse( ) AND other.majority.istrue( ) THEN RETURN -1; ELSIF SELF.majority.isfalse( ) AND other.majority.isfalse( ) THEN RETURN SIGN(SELF.yrs_service other.yrs_service); END IF; END ranking; END; A MAP funct ion accept s no param et ers and ret urns a scalar dat at ype such as DATE, NUMBER, or VARCHAR2 for which Oracle already knows a collat ing sequence. The MAP funct ion t ranslat es, or m aps, each obj ect int o t his scalar dat at ype space. I f no ORDER or MAP funct ion exist s for an obj ect t ype, SQL, but not PL/ SQL, support s only lim it ed equalit y com parisons of obj ect s. Obj ect s are equal if t hey are of t he sam e obj ect t ype and if each at t ribut e is equal. Use MAP if possible when frequent ly sort ing or com paring a large num ber of obj ect s, as in a SQL st at em ent ; an int ernal opt im izat ion reduces t he num ber of funct ion calls. Wit h ORDER, t he funct ion m ust run once for every com parison.

1.16.4 Methods in Subtypes (Oracle9i) The m et hod m odifiers OVERRI DI NG, FI NAL, and NOT I NSTANTI ABLE specify how m et hod overriding works in t he subt ype: OVERRI DI NG

Tells Oracle t hat t he subt ype's m et hod will override t he supert ype's m et hod. FI NAL Tells Oracle t hat new subt ypes m ay not override t his m et hod. NOT I NSTANTI ABLE Tells Oracle t hat t his m et hod is not available in t he subt ype. As you can im agine, cert ain com binat ions of t hese m odifiers are disallowed. Oracle9i support s dynam ic m et hod dispat ch t o det erm ine which overridden m et hod t o invoke at runt im e. That is, it will choose t he m et hod in t he m ost specific subt ype associat ed wit h t he current ly inst ant iat ed obj ect .

1.16.5 Manipulating Objects in PL/SQL and SQL Var iables declared as obj ect s begin t heir life at om ically null, m eaning t hat t he expression:

object IS NULL evaluat es t o TRUE. At t em pt ing t o assign values t o t he at t ribut es of an at om ically null obj ect will ret urn an ACCESS_I NTO_NULL except ion. I nst ead, you m ust init ialize t he obj ect , in one of t hese ways:

Use eit her t he default const ruct or m et hod or a user- defined const ruct or Assign t o it t he value of an exist ing obj ect Use SELECT I NTO or FETCH I NTO Here is an exam ple using each init ializat ion t echnique:

DECLARE project_boiler_plate build_web_site

project_t; project_t;

-- Initialize via constructor. new_web_mgr proj_mgr_t := proj_mgr_t('Ruth', 'Home Office'); -- Initialize via Oracle9i user-defined constructor -- that provides defaults new_web_mgr proj_mgr_t := NEW proj_mgr_t( ); CURSOR template_cur IS SELECT VALUE(proj) FROM projects WHERE project_type = 'TEMPLATE' AND sub_type = 'WEB SITE'; BEGIN OPEN template_cur; -- Initialize via FETCH INTO. FETCH template_cur INTO project_boiler_plate; -- Initialize via assignment. build_web_site := project_boiler_plate;

... Aft er an obj ect is init ialized, it can be st ored in t he dat abase, and you can t hen locat e and use t hat obj ect wit h t he REF, VALUE, and DEREF operat ors.

1.16.6 Upcasting and Downcasting (Oracle9i) Oracle9i support s im plicit upcast ing ( widening) of a subt ype and provides t he TREAT operat or t o downcast ( narrow) a supert ype. TREAT can also explicit ly upcast a subt ype. Assum ing t hat book_t is a subt ype of cat alog_it em _t , t he following exam ple shows bot h upcast s and downcast s:

DECLARE my_book book_t := NEW book_t( ); your_book book_t; some_catalog_item catalog_item_t; BEGIN /* An implied upcast */ some_catalog_item := my_book; /* An explicit downcast */ your_book := TREAT(some_catalog_item AS book_t); END; The synt ax of TREAT is:

TREAT (object_instance AS [ REF ] type) where obj ect _inst ance is a value t hat is of a part icular supert ype in an obj ect hierarchy, and t y pe is t he nam e of subt ype ( or supert ype) in t he sam e hierarchy. The TREAT expression won't com pile if you at t em pt t o cast a t ype t o anot her from a different t ype hierarchy. I f you supply an obj ect from t he correct t ype hierarchy, TREAT will ret urn eit her t he cast ed obj ect or NULL—but not an error. You can also use dot not at ion t o obt ain access t o t he cast ed obj ect 's at t ribut es and m et hods:

TREAT (object_instance AS type).{ attribute | method(args...) } ] SQL also support s TREAT and im plied upcast ing.

1.16.6.1 REF operator REF, short for REFerence, designat es a dat at ype m odifier or an operat or t o ret rieve a logical point er t o an obj ect . This point er encapsulat es t he OI D and can sim plify navigat ion am ong relat ed dat abase obj ect s. The synt ax for a REF operat or is:

REF(table_alias_name) For exam ple:

SELECT REF(p) FROM pets p WHERE ... A PL/ SQL variable can hold a reference t o a part icular obj ect t ype:

DECLARE petref REF Pet_t; BEGIN SELECT REF(p) INTO petref FROM pets p WHERE ... Through delet ions, REFs can reference a nonexist ent obj ect —called a dangling REF—result ing in a st at e t hat can be det ect ed wit h t he I S DANGLI NG predicat e. For exam ple:

UPDATE pets SET owner_ref = NULL WHERE owner_ref IS DANGLING. Oracle's built - in package UTL_REF provides program m at ic access t o st ored obj ect s via t heir REF.

1.16.6.2 VALUE operator Use t he VALUE operat or t o ret rieve a row obj ect as a single obj ect rat her t han m ult iple colum ns. The synt ax for t he VALUE operat or is:

VALUE(table_alias_name) For exam ple:

SELECT VALUE(p) FROM pets p WHERE ... 1.16.6.3 DEREF operator Use t he DEREF operat or t o ret rieve t he value of an obj ect for which you have a REF. The synt ax for DEREF is:

DEREF(table_alias_name) For exam ple:

DECLARE person_ref REF person_t; author person_t; BEGIN -- Get the ref. SELECT REF(p) INTO person_ref FROM persons WHERE p.last_name ='Pribyl'; -- Dereference the pointer back to the value. SELECT DEREF(person_ref) INTO author FROM dual; ... I n addit ion, Oracle uses an OI D int ernally as a unique key t o each obj ect . As wit h a ROWI D, you don't t ypically use an OI D direct ly. The following t able shows ways of referencing persist ent obj ect s:

Sch e m e

D e scr ipt ion

Applica t ion s

OI D

An opaque, globally unique handle, produced when t he obj ect is st ored in t he dat abase as a t able ( row) obj ect .

This is t he persist ent obj ect 's handle; it 's what REFs point t o. Your program never uses it direct ly.

VALUE

An operat or. I n SQL, it act s on an obj ect in an obj ect t able and ret urns t he obj ect 's cont ent s. Different from t he VALUES keyword found in som e I NSERT st at em ent s.

Allows quasi- norm alizing of obj ect - relat ional dat abases and j oining of obj ect t ables using dot navigat ion. I n PL/ SQL, REFs serve as input / out put variables.

REF

A point er t o an obj ect . May be used wit hin a SQL st at em ent as an operat or or in a declarat ion as a t ype m odifier.

Used when fet ching a t able ( row) obj ect int o a variable, or when you need t o refer t o an obj ect t able as an obj ect inst ead of a list of colum ns.

DEREF

Reverse point er lookup for REFs.

Used for ret rieving t he cont ent s of an obj ect when all you know is it s REF.

1.16.7 Changing Object Types You can add m et hods, but not at t ribut es, t o an obj ect t ype st ored in t he dat abase using t he ALTER TYPE st at em ent . There are several form s of t his st at em ent :

ALTER TYPE typename { ADD | MODIFY | DROP } ATTRIBUTE attribute_spec { INVALIDATE | CASCADE { [ NOT ] INCLUDING TABLE DATA | CONVERT TO SUBSTITUTABLE } [ FORCE ] }; ALTER TYPE typename [ NOT ] { INSTANTIABLE | FINAL } { INVALIDATE | CASCADE { [ NOT ] INCLUDING TABLE DATA | CONVERT TO SUBSTITUTABLE } [ FORCE ] }; ALTER TYPE typename COMPILE [ DEBUG ] [ SPECIFICATION | BODY ] [ REUSE SETTINGS ]; Because alt ering t he st ruct ure of a t ype can have quit e a few repercussions on dat abase obj ect s, Oracle requires you eit her t o I NVALI DATE t he dependent obj ect s or t o CASCADE t he change. When m aking a change from FI NAL t o NOT FI NAL and cascading t he change, you can cause exist ing t able obj ect s t o be eit her NOT SUBSTI TUTABLE ( t he default ) or SUBSTI TUTABLE. The following is an exam ple of adding an at t ribut e:

ALTER TYPE catalog_item_t ADD ATTRIBUTE publication_date VARCHAR2(400) CASCADE INCLUDING TABLE DATA; The next exam ple shows adding a m et hod:

ALTER TYPE catalog_item_t ADD MEMBER PROCEDURE save, CASCADE; Aft er adding a m et hod t o a spec, you would use CREATE OR REPLACE TYPE BODY t o im plem ent it in t he body ( include all t he ot her m et hods as well) .

There are a variet y of rest rict ions on m odifying t ypes; for exam ple, you cannot change a t ype from I NSTANTI ABLE t o NOT I NSTANTI ABLE if you have creat ed t ables t hat depend on t he t ype. The synt ax for dropping an obj ect t ype is:

DROP TYPE type_name [FORCE]; You can drop only an obj ect t ype t hat has not been im plem ent ed in a t able ( or you can drop t he t ables first ) . The FORCE opt ion will drop obj ect t ypes even if t hey have dependencies, but FORCE will irreversibly invalidat e any dependent obj ect s such as t ables. FORCE does not do a DROP CASCADE. I f you are dropping a t ype whose parent t ype has t able dependent s, t his form of t he st at em ent :

DROP TYPE subtype_name VALIDATE; will " validat e" t he safet y of dropping t he subt ype before perform ing it . That is, Oracle will only perform t he drop if t here are no obj ect s of t he subt ype in any subst it ut able colum ns of t he parent t ype.

[ Team LiB ]

[ Team LiB ]

1.17 Collections There are t hree t ypes of collect ions: associat ive arrays ( form erly known as index- by t ables or PL/ SQL t ables) , nest ed t ables, and VARRAYs. Associat ive arrays Single- dim ension, unbounded collect ions of hom ogeneous elem ent s available only in PL/ SQL, not in t he dat abase. Associat ive arrays are init ially sparse; t hey have nonconsecut ive subscript s. Nest ed t ables Single- dim ension, unbounded collect ions of hom ogeneous elem ent s available in bot h PL/ SQL and t he dat abase as colum ns or t ables. Nest ed t ables are init ially dense ( t hey have consecut ive subscript s) , but t hey can becom e sparse t hrough delet ions. VARRAYs Variable- size arrays. Single- dim ension, bounded collect ions of hom ogeneous elem ent s available in bot h PL/ SQL and t he dat abase. VARRAYs are never sparse. Unlike nest ed t ables, t heir elem ent order is preserved when you st ore and ret rieve t hem from t he dat abase. The following t able com pares t hese sim ilar collect ion t ypes:

Colle ct ion t ype Charact erist ic

Associat ive array

Nest ed t able

VARRAY

Dim ensionalit y

Single

Single

Single

Usable in SQL?

No

Yes

Yes

Usable as a colum n dat at ype in a t able?

No

Yes; dat a st ored " out of Yes; dat a t ypically line" ( in a separat e st ored " in line" ( in t he t able) sam e t able)

Uninit ialized st at e

Em pt y ( cannot be NULL) ; elem ent s are undefined

At om ically null; illegal t o reference elem ent s

At om ically null; illegal t o reference elem ent s

I nit ializat ion

Aut om at ic, when declared

Via const ruct or, fet ch, assignm ent

Via const ruct or, fet ch, assignm ent

BI NARY_I NTEGER ( 2,147,483,647 I n PL/ SQL, elem ent s referenced by

.. 2,147,483,647) or charact er st ring ( VARCHAR2) ; m axim um lengt h of VARCHAR2 is 30, m inim um lengt h is 1

Posit ive int eger Posit ive int eger bet ween bet ween 1 and 1 and 2,147483,647 2,147483,647

Sparse?

Yes

I nit ially no; aft er delet ions, yes

No

Bounded?

No

Can be ext ended

Yes

Yes

No; m ay need t o EXTEND first

No; m ay need t o EXTEND first , and cannot EXTEND past t he upper bound

Can assign a value t o any elem ent at any t im e?

Means of ext ending

Assign value t o elem ent wit h a new subscript

Use built - in EXTEND or TRI M funct ion t o condense, wit h no predefined m axim um

Use EXTEND or TRI M, but only up t o declared m axim um size.

Can be com pared for equalit y ?

No

No

No

No

Yes

Elem ent s ret ain ordinal posit ion and subscript N/ A—can't be st ored in when st ored and ret rieved dat abase from t he dat abase

1.17.1 Declaring a Collection Collect ions are im plem ent ed as TYPEs. As wit h any program m er- defined t ype, you m ust first define t he t ype; t hen you can declare inst ances of t hat t ype. The TYPE definit ion can be st ored in t he dat abase or declared in t he PL/ SQL program . Each inst ance of t he TYPE is a collect ion. The synt ax for declaring an associat ive array is:

TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY {BINARY_INTEGER | VARCHAR2 (size_limit)}; The synt ax for a nest ed t able is:

[CREATE [OR REPLACE]] TYPE type_name IS TABLE OF element_type [NOT NULL]; The synt ax for a VARRAY is:

[CREATE [OR REPLACE]] TYPE type_name IS VARRAY | VARYING ARRAY (max_elements) OF element_type [NOT NULL]; The CREATE keyword defines t he st at em ent t o be DDL and indicat es t hat t his t ype will exist in t he dat abase. The opt ional OR REPLACE keywords are used t o rebuild an exist ing t ype, preserving t he privileges. t ype_nam e is any valid ident ifier t hat will be used lat er t o declare t he collect ion. m ax_elem ent s is t he m axim um size of t he VARRAY. elem ent _t ype is t he t ype of t he collect ion's elem ent s. All elem ent s are of a single t ype, which can be m ost scalar dat at ypes, an obj ect t ype, or a REF obj ect t ype. I f t he elem ent s are obj ect s, t he obj ect t ype it self cannot have an at t ribut e t hat is a collect ion. Explicit ly disallowed collect ion dat at ypes are BOOLEAN, NCHAR, NCLOB, NVARCHAR2, REF CURSOR, TABLE, and VARRAY. NOT NULL indicat es t hat a collect ion of t his t ype cannot have any null elem ent s. However, t he collect ion can be at om ically null ( uninit ialized) .

1.17.2 Initializing Collections I nit ializing an associat ive array is t rivial—sim ply declaring it also init ializes it . I nit ializing a nest ed t able or a VARRAY can be done in any of t hree ways: explicit ly wit h a const ruct or, or im plicit ly wit h a fet ch from t he dat abase or wit h a direct assignm ent of anot her collect ion variable. The const ruct or is a built - in funct ion wit h t he sam e nam e as t he collect ion. I t const ruct s t he collect ion from t he elem ent s passed t o it . The first exam ple shows how you can creat e a nest ed t able of colors and explicit ly init ialize it t o t hree elem ent s wit h a const ruct or:

DECLARE TYPE colors_tab_t IS TABLE OF VARCHAR2(30); colors_tab_t('RED','GREEN','BLUE'); BEGIN The next exam ple shows how you can creat e t he nest ed t able of colors and im plicit ly init ialize it wit h a fet ch from t he dat abase:

-- Create the nested table to exist in the database. CREATE TYPE colors_tab_t IS TABLE OF VARCHAR2(32); -- Create table with nested table type as column. CREATE TABLE color_models (model_type VARCHAR2(12) ,colors color_tab_t) NESTED TABLE colors STORE AS color_model_colors_tab; -- Add some data to the table. INSERT INTO color_models VALUES('RGB',color_tab_t('RED','GREEN','BLUE')); INSERT INTO color_models VALUES('CYMK',color_tab_t('CYAN','YELLOW', 'MAGENTA' 'BLACK')); -- Initialize a collection of colors from the table. DECLARE basic_colors colors_tab_t; BEGIN SELECT colors INTO basic_colors FROM color_models WHERE model_type = 'RGB'; ... END; The t hird exam ple shows how you can im plicit ly init ialize t he t able via an assignm ent from an exist ing collect ion:

DECLARE basic_colors Color_tab_t := Color_tab_t ('RED','GREEN','BLUE'); my_colors Color_tab_t; BEGIN my_colors := basic_colors; my_colors(2) := 'MUSTARD'; 1.17.3 Adding and Removing Elements Elem ent s in an associat ive array can be added sim ply by referencing new subscript s. To add elem ent s t o nest ed t ables or VARRAYs, you m ust first enlarge t he collect ion wit h t he EXTEND funct ion, and t hen you can assign a value t o a new elem ent using one of t he m et hods described in t he previous sect ion. Use t he DELETE funct ion t o rem ove an elem ent in a nest ed t able regardless of it s posit ion. The TRI M funct ion can also be used t o rem ove elem ent s, but only from t he end of a collect ion. To avoid unexpect ed result s, do

not use bot h DELETE and TRI M on t he sam e collect ion.

1.17.4 Collection Pseudo-Functions There are several pseudo- funct ions defined for collect ions: CAST, MULTI SET, and TABLE. CAST Maps a collect ion of one t ype t o a collect ion of anot her t ype. SELECT column_value FROM TABLE(SELECT CAST(colors AS color_tab_t) FROM color_models_a WHERE model_type ='RGB'); MULTI SET Maps a dat abase t able t o a collect ion. Wit h MULTI SET and CAST, you can ret rieve rows from a dat abase t able as a collect ion- t yped colum n. SELECT b.genus ,b.species, CAST(MULTISET(SELECT bh.country FROM bird_habitats bh WHERE bh.genus = b.genus AND bh.species = b.species) AS country_tab_t) FROM birds b; TABLE Maps a collect ion t o a dat abase t able ( t he inverse of MULTI SET) . SELECT * FROM color_models c WHERE 'RED' IN (SELECT * FROM TABLE(c.colors)); You can use TABLE( ) t o unnest a t ransient collect ion: DECLARE birthdays Birthdate_t := Birthdate_t('24-SEP-1984', '19-JUN-1993'); BEGIN FOR the_rec IN (SELECT COLUMN_VALUE FROM TABLE(CAST(birthdays AS Birthdate_t)))

1.17.5 Collection Methods There are a num ber of built - in funct ions ( m et hods) defined for all collect ions. These m et hods are called wit h dot not at ion:

collection_name.method_name[(parameters)] The m et hods are list ed in t he following t able:

Collect ion m e t h od COUNT funct ion

D e scr ipt ion Ret urns t he current num ber of elem ent s in t he collect ion.

Rem oves elem ent i or elem ent s i t hrough j from a nest ed t able or associat ive array. When DELETE [ ( i [ , j ] called wit h no param et ers, rem oves all elem ent s in t he collect ion. Reduces t he COUNT if ) ] procedure t he elem ent is not already DELETEd. Does not apply t o VARRAYs. EXI STS ( i ) funct ion

Ret urns TRUE or FALSE t o indicat e whet her elem ent i exist s. I f t he collect ion is an uninit ialized nest ed t able or VARRAY, ret urns FALSE.

EXTEND [ ( n [ , i ] ) ] procedure

Appends n elem ent s t o a collect ion, init ializing t hem t o t he value of elem ent i. n is opt ional and default s t o 1.

FI RST funct ion

Ret urns t he lowest index in use. Ret urns NULL when applied t o em pt y init ialized collect ions.

LAST funct ion

Ret urns t he great est index in use. Ret urns NULL when applied t o em pt y init ialized collect ions.

LI MI T funct ion

Ret urns t he m axim um num ber of allowed elem ent s in a VARRAY. Ret urns NULL for associat ive arrays and nest ed t ables.

PRI OR ( i ) funct ion

Ret urns t he index im m ediat ely before elem ent i. Ret urns NULL if i is less t han or equal t o FI RST.

NEXT ( i ) funct ion

Ret urns t he index im m ediat ely aft er elem ent i. Ret urns NULL if i is great er t han or equal t o COUNT.

TRI M [ ( n ) ] procedure

Rem oves n elem ent s at t he end of t he collect ion wit h t he largest index. n is opt ional and default s t o 1. I f n is NULL, TRI M does not hing. Associat ive arrays cannot be TRI Mm ed.

The EXI STS funct ion ret urns a BOOLEAN, and all ot her funct ions and procedures ret urn BI NARY_I NTEGER except for collect ions indexed by VARCHAR2, which can ret urn charact er st rings. All param et ers are of t he BI NARY_I NTEGER t ype. Only EXI STS can be used on uninit ialized nest ed t ables or VARRAYs. Ot her m et hods applied t o t hese at om ically null collect ions will raise t he COLLECTI ON_I S_NULL except ion. DELETE and TRI M bot h rem ove elem ent s from a nest ed t able, but TRI M also rem oves t he placeholder, while DELETE does not . This behavior m ay be confusing, because TRI M can rem ove previously DELETEd elem ent s. Here is an exam ple of som e collect ion m et hods in use wit h an associat ive array:

DECLARE TYPE population_type IS TABLE OF NUMBER INDEX BY VARCHAR2(64); continent_population population_type; howmany NUMBER; limit VARCHAR2(64); BEGIN continent_population('Australia') := 30000000; -- Create new entry continent_population('Antarctica') := 1000; -- Replace old value continent_population('Antarctica') := 1001; limit := continent_population.FIRST; DBMS_OUTPUT.PUT_LINE (limit); DBMS_OUTPUT.PUT_LINE (continent_population(limit)); limit := continent_population.LAST; DBMS_OUTPUT.PUT_LINE (limit); DBMS_OUTPUT.PUT_LINE (continent_population(limit)); END; /

This exam ple produces t he following out put :

Antarctica 1001 Australia 30000000 Here is an exam ple of som e collect ion m et hods in use wit h a nest ed t able:

DECLARE TYPE colors_tab_t IS TABLE OF VARCHAR2(30); my_list colors_tab_t := colors_tab_t('RED','GREEN','BLUE'); element BINARY_INTEGER; BEGIN DBMS_OUTPUT.PUT_LINE('my_list has ' ||my_list.COUNT||' elements'); my_list.DELETE(2); -- delete element two DBMS_OUTPUT.PUT_LINE('my_list has ' ||my_list.COUNT||' elements'); FOR element IN my_list.FIRST..my_list.LAST LOOP IF my_list.EXISTS(element) THEN DBMS_OUTPUT.PUT_LINE(my_list(element) || ' Prior= '||my_list.PRIOR(element) || ' Next= ' ||my_list.NEXT(element)); ELSE DBMS_OUTPUT.PUT_LINE('Element '|| element ||' deleted. Prior= '||my_ list.PRIOR(element) || ' Next= '||my_list.NEXT(element)); END IF; END LOOP; END; This exam ple produces t he out put :

my_list has 3 elements my_list has 2 elements RED Prior= Next= 3 Element 2 deleted. Prior= 1 Next= 3 BLUE Prior= 1 Next= 1.17.6 Collections and Privileges As wit h ot her TYPEs in t he dat abase, you need t he EXECUTE privilege on t hat TYPE in order t o use a collect ion t ype creat ed by anot her schem a ( user account ) in t he dat abase. Not e t hat Oracle9i Release 2 m ade it possible t o use synonym s for user- defined TYPE nam es.

1.17.7 Nested Collections (Oracle9i) Nest ed collect ions are collect ions cont ained in m em bers t hat are collect ions t hem selves. Nest ing collect ions is

a powerful way t o im plem ent obj ect - orient ed program m ing const ruct s wit hin PL/ SQL program s. For exam ple:

CREATE TYPE books IS TABLE OF VARCHAR2(64); CREATE TYPE our_books IS TABLE OF books; 1.17.8 Bulk Binds You can use collect ions t o im prove t he perform ance of SQL operat ions execut ed it erat ively by using bulk binds. Bulk binds reduce t he num ber of cont ext swit ches bet ween t he PL/ SQL engine and t he dat abase engine. Two PL/ SQL language const ruct s im plem ent bulk binds: FORALL and BULK COLLECT I NTO. The synt ax for t he FORALL st at em ent is:

FORALL bulk_index IN lower_bound..upper_bound sql_statement;

[SAVE EXCEPTIONS]

bulk_index can be used only in t he sql_st at em ent and only as a collect ion index ( subscript ) . When PL/ SQL processes t his st at em ent , t he whole collect ion, inst ead of each individual collect ion elem ent , is sent t o t he dat abase server for processing. To delet e all t he account s in t he collect ion inact ives from t he t able ledger, do t his:

FORALL i IN inactives.FIRST..inactives.LAST DELETE FROM ledger WHERE acct_no = inactives(i); The default is for Oracle t o st op aft er t he first except ion encount ered. Use t he keywords SAVE EXCEPTI ONS t o t ell Oracle t hat processing should cont inue aft er encount ering except ions. The cursor at t ribut e % BULK_EXCEPTI ONS st ores a collect ion of records cont aining t he errors. These records have t wo fields, EXCEPTI ON_I NDEX and EXCEPTI ON_CODE, which cont ain t he FOR ALL it erat ion during which t he except ion was raised, as well as t he SQLCODE for t he except ion. I f no except ions are raised, t he SQL% BULK_EXCEPTI ON.COUNT m et hod ret urns 0. For exam ple:

DECLARE TYPE NameList IS TABLE OF VARCHAR2(32); name_tab NameList := NameList('Pribyl' ,'Dawes','Feuerstein','Gennick' ,'Pribyl','Beresniewicz','Dawes','Dye'); error_count NUMBER; bulk_errors EXCEPTION; PRAGMA exception_init(bulk_errors, -24381); BEGIN FORALL indx IN name_tab.FIRST..name_tab.LAST SAVE EXCEPTIONS INSERT INTO authors (name) VALUES (name_tab(indx)); -- authors has pk index on name EXCEPTION WHEN others THEN error_count := SQL%BULK_EXCEPTIONS.COUNT; DBMS_OUTPUT.PUT_LINE('Number of errors is ' || error_count); FOR indx IN 1..error_count LOOP DBMS_OUTPUT.PUT_LINE('Error ' || indx || ' occurred during '||'iteration ' || SQL%BULK_EXCEPTIONS(indx).ERROR_INDEX); DBMS_OUTPUT.PUT_LINE('Error is ' || SQLERRM(-SQL%BULK_EXCEPTIONS(indx).ERROR_CODE)); END LOOP; END;

/ Number of errors is 2 Error 1 occurred during iteration 5 Error is ORA-00001: unique constraint (.) violated Error 2 occurred during iteration 7 Error is ORA-00001: unique constraint (.) violated The synt ax for t he BULK COLLECT I NTO clause is:

BULK COLLECT INTO collection_name_list; where collect ion_nam e_list is a com m a- delim it ed list of collect ions, one for each colum n in t he SELECT. Collect ions of records cannot be a t arget of a BULK COLLECT I NTO clause. However, Oracle does support ret rieving a set of t yped obj ect s and " bulk collect ing" t hem int o a collect ion of obj ect s. The BULK COLLECT I NTO clause can be used in SELECT I NTO, FETCH I NTO, or RETURNI NG I NTO st at em ent s. For exam ple:

DECLARE TYPE vendor_name_tab IS TABLE OF vendors.name%TYPE; TYPE vendor_term_tab IS TABLE OF vendors.terms%TYPE; v_names vendor_name_tab; v_terms vendor_term_tab; BEGIN SELECT name, terms BULK COLLECT INTO v_names, v_terms FROM vendors WHERE terms < 30; ... END; The next funct ion delet es product s in an input list of cat egories, and t he SQL RETURNI NG clause ret urns a list of delet ed product s:

FUNCTION cascade_category_delete (categorylist clist_t) RETURN prodlist_t IS prodlist prodlist_t; BEGIN FORALL aprod IN categorylist.FIRST..categorylist.LAST DELETE FROM product WHERE product_id IN categorylist(aprod) RETURNING product_id BULK COLLECT INTO prodlist; RETURN prodlist; END; You can use t he SQL% BULK_ROWCOUNT cursor at t ribut e for bulk bind operat ions. I t is like an associat ive array cont aining t he num ber of rows affect ed by t he execut ions of t he bulk bound st at em ent s. The n t h elem ent of SQL% BULK_ROWCOUNT cont ains t he num ber of rows affect ed by t he n t h execut ion of t he SQL st at em ent . For exam ple:

FORALL i IN inactives.FIRST..inactives.LAST DELETE FROM ledger WHERE acct_no = inactives(i); FOR counter IN inactives.FIRST..inactives.LAST

LOOP IF SQL%BULK_ROWCOUNT(counter) = 0 THEN DBMS_OUTPUT.PUT_LINE('No rows deleted for '|| counter); END IF; END LOOP; You cannot pass SQL% BULK_ROWCOUNT as a param et er t o anot her program , or use an aggregat e assignm ent t o anot her collect ion. % ROWCOUNT cont ains a sum m at ion of all % BULK_ROWCOUNT elem ent s. % FOUND and % NOTFOUND reflect only t he last execut ion of t he SQL st at em ent .

[ Team LiB ]

[ Team LiB ]

1.18 External Procedures Ext ernal procedures provide a m echanism for calling out t o a non- dat abase program , such as a DLL under NT or a shared library under Unix. Every session calling an ext ernal procedure will have it s own ext proc process st art ed by t he list ener. This ext proc process is st art ed wit h t he first call t o t he ext ernal procedure and t erm inat es when t he session exit s. The shared library needs t o have a corresponding library creat ed for it in t he dat abase.

1.18.1 Creating an External Procedure The following are t he st eps you need t o follow in order t o creat e an ext ernal procedure.

1.18.1.1 Set up the listener Ext ernal procedures require a list ener. I f you are running an Oracle Net dat abase list ener, it can be used as t he ext proc list ener as well, alt hough you m ay increase securit y by separat ing it from t he ext ernal procedure list ener and launching it from a privilege- lim it ed account . Here is one way t o st ruct ure t he list ener.ora file:

LISTENER = (ADDRESS = (PROTOCOL=TCP)(HOST=hostname)(PORT=1521)) EXTPROC_LISTENER = (ADDRESS = (PROTOCOL = IPC)(KEY = extprocKey)) SID_LIST_LISTENER = (SID_DESC = (GLOBAL_DBNAME = global_name) (ORACLE_HOME = oracle_home_directory) (SID_NAME = SID) ) SID_LIST_EXTPROC_LISTENER = (SID_DESC = (SID_NAME = extprocSID) (ORACLE_HOME = oracle_home_directory) (ENVS = "EXTPROC_DLLS= qualifier:shared_object_file_list") (PROGRAM = extproc) ) ext procKey Short ident ifier used by Oracle Net t o dist inguish t his list ener from ot her pot ent ial I PC list eners. I t s act ual nam e is arbit rary, because your program s will never see it . Oracle uses EXTPROC0 as t he default nam e for t he first Oracle Net inst allat ion on a given m achine. This ident ifier m ust be t he sam e in t he address list of t he list ener.ora and t nsnam es.ora files. ext procSI D Arbit rary unique ident ifier for t he ext ernal procedure list ener. I n t he default inst allat ion, Oracle uses t he value PLSExt Proc.

ENVS Means of passing environm ent variables t o t he ext ernal procedure list ener. The exam ple above shows only one nam e/ value pair, but any num ber of pairs are perm it t ed. Use name=value synt ax, separat ing each nam e/ value pair wit h a com m a, as in (ENVS="LD_LIBRARY_PATH= /lib:/oracle/product/9.2/lib,EXTPROC_DLLS=ANY") EXTPROC_DLLS Environm ent variable designat ing non- default locat ions of shared libraries/ DLLs. Wit hout t his set t ing, t he default securit y set t ings of Oracle9i Release 2 require t he library/ DLL t o be in t he bin subdirect ory on Windows plat form s, and in Oracle's lib subdirect ory on Unix. The qualifier is act ually opt ional; if it is not present , t he addit ional files given in a colon- delim it ed shared_obj ect _file_list are allowed. I f qualifier is present , it m ust be one of t he keywords ALL ( no locat ion checking) or ONLY ( disallows t he default locat ions) . Here is an exam ple ENVS ent ry support ing t wo shared libraries found in non- default locat ions:

(ENVS="EXTPROC_DLLS=ONLY:/u01/app/oracle/admin/local/lib/ extprocsh.so:/u01/app/oracle/admin/local/lib/ RawdataToPrinter.so") I nst allat ions unconcerned wit h securit y m ay wish t o perm it any locat ion using an ent ry such as t he following:

(ENVS="EXTPROC_DLLS=ALL") See t he Oracle9i Applicat ion Developers Guide - Fundam ent als or t he Oracle9i Net Services Adm inist rat ors Guide for m ore det ails on configuring ext ernal procedures and your list ener.

1.18.1.2 Identify or create the shared library or DLL This st ep has not hing t o do wit h PL/ SQL and m ay or m ay not have anyt hing t o do wit h t he dat abase. You m ust writ e your own C rout ines and link t hem int o a shared library/ DLL or use an exist ing library's funct ions or procedures. I n t he sim ple exam ple in t he next sect ion, we will use t he exist ing random - num ber- generat ing calls available from t he operat ing syst em .

1.18.1.3 Create the library in the database Creat e a library in t he dat abase for t he shared library or DLL using t he CREATE LI BRARY st at em ent :

CREATE [OR REPLACE] LIBRARY library_name { IS | AS } 'absolute_path_and_file' [ AGENT 'agent_db_link']; The opt ional AGENT clause represent s a dat abase link associat ed wit h t he service nam e of an ext ernal procedure list ener. I n t his way t he library can invoke a separat e runt im e inst ant iat ion of t he ext proc process. This process can run on a different dat abase server, alt hough t hat server m ust st ill reside on t he sam e m achine as t he calling program . To rem ove libraries from t he dat abase, you use t he DROP LI BRARY st at em ent :

DROP LIBRARY library_name; To call out t o t he C runt im e library's rand funct ion, you don't have t o code any C rout ines at all, because t he

call is already linked int o a shared library, and because it s argum ent s are direct ly t ype- m appable t o PL/ SQL. I f t he rand funct ion is in t he st andard / lib/ libc.so shared library, as on Solaris, you would issue t he following CREATE LI BRARY st at em ent :

CREATE OR REPLACE LIBRARY libc_l AS '/lib/libc.so'; -- References C runtime library. This is t he t ypical corresponding st at em ent for Microsoft Windows:

CREATE OR REPLACE LIBRARY libc_l AS 'C:\WINDOWS\SYSTEM32\CRTDLL.DLL'; 1.18.1.4 Create the PL/SQL wrapper for the external procedure The synt ax for t he wrapper procedure is:

CREATE [OR REPLACE] PROCEDURE proc_name [parm_list] { AS | IS } LANGUAGE C [NAME external_name] LIBRARY library_name [ AGENT IN (formal_parameter_name) ] [WITH CONTEXT] [PARAMETERS (external_parameter_list)]; where: pr oc_nam e Nam e of t he wrapper procedure. library_nam e Nam e of t he library creat ed wit h t he CREATE LI BRARY st at em ent . agent _nam e This clause is a way of designat ing a different agent process, sim ilar t o t he AGENT clause on t he library, but deferring t he select ion of t he agent unt il runt im e. You will pass in t he value of t he agent as a form al PL/ SQL param et er t o t he call spec; it will supersede t he nam e of t he agent given in t he library, if any. ext ernal_nam e Nam e of t he ext ernal rout ine as it appears in t he library. I t default s t o t he wrapper package nam e. PL/ SQL package nam es are usually saved in uppercase, so t he ext ernal_nam e m ay need t o be enclosed in double quot es t o preserve case. WI TH CONTEXT Used t o pass a cont ext point er t o t he ext ernal rout ine, so it can m ake Oracle Call I nt erface ( OCI ) calls back t o t he dat abase. PARAMETERS I dent ify t he ext ernal_param et er_list , which is a com m a- delim it ed list cont aining t he posit ion and dat at ype of param et ers t hat get passed t o t he ext ernal rout ine. For m ore det ails on t he ext ernal_param et er_list , see Sect ion 1.18.2. The wrapper PL/ SQL funct ion or procedure is oft en in a package. Using t he preceding random num ber generat or exam ple, we could creat e t he wrapper package as follows:

CREATE OR REPLACE PACKAGE random_utl

AS FUNCTION rand RETURN PLS_INTEGER; PRAGMA RESTRICT_REFERENCES(rand,WNDS,RNDS,WNPS,RNPS); PROCEDURE srand (seed IN PLS_INTEGER); PRAGMA RESTRICT_REFERENCES(srand,WNDS,RNDS,WNPS,RNPS); END random_utl; CREATE PACKAGE BODY random_utl AS FUNCTION rand RETURN PLS_INTEGER IS LANGUAGE C -- Language of routine. NAME "rand" -- Function name in the LIBRARY libc_l; -- The library created above. PROCEDURE srand (seed IN PLS_INTEGER) IS LANGUAGE C NAME "srand" -- Name is lowercase in this LIBRARY libc_l PARAMETERS (seed ub4); --Map to unsigned INT END random_utl; To use t his ext ernal random num ber funct ion, we sim ply call t he package procedure srand t o seed t he generat or, t hen t he package funct ion rand t o get random num bers:

DECLARE random_nbr PLS_INTEGER; seed PLS_INTEGER; BEGIN SELECT TO_CHAR(SYSDATE,'SSSSS') INTO seed FROM dual; random_utl.srand(seed);

-- Seed the generator.

random_nbr := random_utl.rand; -- Get the number. DBMS_OUTPUT.PUT_LINE('number='||random_nbr); random_nbr := random_utl.rand; -- Get the number. DBMS_OUTPUT.PUT_LINE('number='||random_nbr); END; You can generat e random num bers wit hout t he com plexit y or overhead of an ext ernal call by using t he built in package DBMS_RANDOM. To learn m ore about DBMS_RANDOM and ot her built - ins, check out Oracle Built in Packages.

1.18.2 Parameters When it com es t o passing PL/ SQL variables t o C variables, we encount er m any inconsist encies. For exam ple, PL/ SQL support s nullit y, while C does not ; PL/ SQL can have variables in different charact er set s, while C cannot ; and t he dat at ypes in PL/ SQL do not direct ly m ap t o C dat at ypes. The PARAMETERS clause specifies t he ext ernal param et er list , a com m a- delim it ed list cont aining param et ers. The synt ax for t hese param et ers ( ot her t han CONTEXT) is:

{ pname | RETURN | SELF } [ property ] [ BY REFERENCE ] [ external_datatype ] I f your call spec includes WI TH CONTEXT, t he corresponding elem ent in t he param et er list is sim ply:

CONTEXT The keyword CONTEXT indicat es t he posit ion in t he param et er list at which t he cont ext point er will be passed. By convent ion, CONTEXT appears as t he first param et er in t he ext ernal param et er list . The keyword RETURN indicat es t hat t he descript ions are for t he ret urn value from t he ext ernal rout ine. By default , RETURN is passed by value. You can use t he keywords BY REFERENCE t o pass by reference ( use point ers) . param et er_nam e is a PL/ SQL form al param et er nam e. By default , I N form al param et ers are passed by value. You can use t he keywords BY REFERENCE t o pass by reference ( as a point er) . I N OUT and OUT form al param et ers are always passed by reference. pr oper t y breaks out furt her t o t he general synt ax:

INDICATOR | INDICATOR STRUCT | LENGTH | MAXLEN | TDO | CHARSETID | CHARSETFORM I NDI CATOR indicat es whet her t he corresponding param et er is NULL. I n t he C program , if t he indicat or equals t he const ant OCI _I ND_NULL, t he param et er is NULL. I f t he indicat or equals t he const ant OCI _I ND_NOTNULL, t he indicat or is not NULL. For I N param et ers, I NDI CATOR is passed by value ( by default ) . For I N OUT, OUT, and RETURN param et ers, I NDI CATOR is passed by reference. You can pass a user- defined t ype t o an ext ernal procedure. To do so, you will t ypically pass t hree param et ers: t he act ual obj ect value; a TDO ( Type Descript or Obj ect ) param et er as defined in C by t he Oracle Type Translat or; and an I NDI CATOR STRUCT param et er, t o designat e whet her t he obj ect is NULL. LENGTH and MAXLEN can be used t o pass t he current and m axim um lengt h of st rings or RAWs. For I N param et ers, LENGTH is passed by value ( by default ) . For I N OUT, OUT, and RETURN param et ers, LENGTH is passed by reference. MAXLEN is not valid for I N param et ers. For I N OUT, OUT, and RETURN param et ers, MAXLEN is passed by reference and is read- only. CHARSETI D and CHARSETFORM are used t o support NLS charact er set s. They are t he sam e as t he OCI at t ribut es OCI _ATTR_CHARSET_I D and OCI _ATTR_CHARSET_FORM. For I N param et ers, CHARSETI D and CHARSETFORM are passed by value ( by default ) and are read- only. For I N OUT, OUT, and RETURN param et ers, CHARSETI D and CHARSETFORM are passed by reference and are read- only. SELF is used if an obj ect m em ber funct ion is im plem ent ed as a callout inst ead of a PL/ SQL rout ine. When m oving dat a bet ween PL/ SQL and C, each PL/ SQL dat at ype m aps t o an " ext ernal dat at ype," ident ified by a PL/ SQL keyword, which in t urn m aps t o an allowed set of C t ypes:

PL/ SQL t ypes

Ext ernal dat at ypes

C t ypes

PL/ SQL includes a special set of keywords t o use as t he ext ernal dat at ype in t he PARAMETERS clause. I n som e cases, t he ext ernal dat at ypes have t he sam e nam e as t he C t ypes. I f you pass a PL/ SQL variable of t ype PLS_I NTEGER, t he corresponding default ext ernal t ype is I NT, which m aps t o an int in C. But Oracle's VARCHAR2 uses t he STRI NG ext ernal dat at ype, which norm ally m aps t o a char * in C. The following t able list s all of t he possible dat at ype conversions support ed by Oracle's PL/ SQL- t o- C int erface. Not e t hat t he allowable conversions depend on bot h t he dat at ype and t he m ode of t he PL/ SQL form al param et er. Default m appings are shown in bold ( if am biguous) .

C da t a t ype s cor r e spon din g t o PL/ SQL pa r a m e t e r s t h a t a r e ...

D a t a t ype of PL/ SQL pa r a m e t e r

PL/ SQL k e yw or d ide n t ifyin g e x t e r n a l t ype

I N or fu n ct ion r e t u r n va lu e s

I N OUT, OUT, or a n y pa r a m e t e r de sign a t e d a s be in g pa sse d BY REFEREN CE

I N T, UNSI GNED I NT, CHAR, UNSI GNED CHAR, SHORT, UNSI GNED SHORT, LONG, UNSI GNED LONG, SB1, UB1, SB2, UB2, SB4, UB4, SI ZE_T

in t , unsigned int , char, unsigned char, short , unsigned short , long, unsigned long, sb1, ub1, sb2, ub2, sb4, ub4, size_t

Sam e list of t ypes as at left , but use a point er( e.g., t he default is int * rat her t han int )

Sam e as above, except default is UNSI GNED I NT

Sam e as above, except default is unsigned int

Sam e as above, except default is unsigned int *

STRI N G,

ch a r * ,

OCI STRI NG

OCI St ring *

NUMBER

OCI NUMBER

OCI Num ber *

OCI Num ber *

DOUBLE PRECI SI ON

DOUBLE

double

double *

FLOAT, REAL

FLOAT

float

float *

RAW, LONG RAW

RAW , OCI RAW

u n sign e d ch a r * , OCI Raw u n sign e d ch a r * , * OCI Raw *

DATE

OCI DATE

OCI Dat e *

OCI Dat e *

OCI Dat eTim e *

OCI Dat eTim e *

I NTERVAL DAY TO SECOND, I NTERVAL YEAR OCI I NTERVAL TO MONTH

OCI I nt erval *

OCI I nt erval *

BFI LE, BLOB, CLOB

OCI LOBLOCATOR *

OCI LOBLOCATOR * *

Descript or of userdefined t ype ( collect ion or TDO obj ect )

OCI Type *

OCI Type *

Value of user- defined collect ion

OCI COLL

OCI Coll * * , OCI Array * * , OCI Table * *

OCI Coll * * , OCI Array * * , OCI Table * *

Value of user- defined obj ect

DVOI D

dvoid *

dvoid * for final t ypes; dvoid * * for non- final t ypes

Long int eger fam ily: BI NARY_I NTEGER, BOOLEAN, PLS_I NTEGER Short int eger fam ily: NATURAL, NATURALN, POSI TI VE, POSI TI VEN, SI GNTYPE Charact er fam ily: VARCHAR2, CHAR, NCHAR, LONG, NVARCHAR2, VARCHAR, CHARACTER, ROWI D

ch a r * , OCI St ring *

Tim est am p fam ily: TI MESTAMP, TI MESTAMP OCI DATETI ME WI TH TI ME ZONE, TI MESTAMP WI TH LOCAL TI ME ZONE

[ Team LiB ]

OCI LOBLOCATOR

[ Team LiB ]

1.19 Java Language Integration Java program m ers can writ e server- side classes t hat invoke SQL and PL/ SQL using st andard JDBC or SQLJ calls. PL/ SQL program m ers can call server- side Java m et hods by writ ing a PL/ SQL cover or call spec for Java using Oracle DDL. Server- side Java in Oracle m ay be fast er t han PL/ SQL for com put e- int ensive program s, but not as nim ble for dat abase access. PL/ SQL is m uch m ore efficient for dat abase- int ensive rout ines because, unlike Java, it doesn't have t o pay t he overhead for convert ing SQL dat at ypes for use inside t he st ored program . Oracle program m ers will want t o cont inue t o use PL/ SQL for program s t hat perform a lot of dat abase I / O, and use Java for t he best raw com put at ion perform ance. The first st ep in creat ing a Java st ored procedure ( JSP) is writ ing or ot herwise obt aining funct ional Java code. Having source code is not necessary, t hough, so you can use class libraries from t hird part ies. The classes m ust , however, m eet t he following requirem ent s:

Met hods published t o SQL and PL/ SQL m ust be declared st at ic. PL/ SQL has no m echanism for inst ant iat ing non- st at ic Java classes. The classes m ust not issue any GUI calls ( for exam ple, t o AWT) at runt im e. I f you writ e your own JSP, and it needs t o connect t o t he dat abase for access t o t ables or st ored procedures, use st andard JDBC and/ or SQLJ calls in your code. Many JDBC and SQLJ reference m at erials are available t o provide assist ance in calling SQL or PL/ SQL from Java, but be sure t o review t he Oracle- specific docum ent at ion t hat ships wit h your release. Once you have t he Java class in hand, eit her in source or .class file form at , t he next st ep is loading it int o t he dat abase. Oracle's loadj ava com m and- line ut ilit y is a convenient way t o accom plish t he load. Refer t o Oracle's docum ent at ion for furt her assist ance wit h loadj ava. The t hird st ep is t o creat e a call spec for t he Java m et hod, specifying t he AS LANGUAGE JAVA clause of t he CREATE com m and. You m ay creat e a funct ion or procedure cover as appropriat e. Finally, you m ay grant EXECUTE privileges on t he new JSP using GRANT EXECUTE, and PL/ SQL rout ines can now call t he JSP as if it were anot her PL/ SQL m odule.

1.19.1 Example Let 's writ e a sim ple " Hello, World" JSP t hat will accept an argum ent :

package oreilly.plsquick.demos; public class Hello { public static String sayIt (String toWhom) { return "Hello, " + toWhom + "!"; } } Saved in a file called Hello.j ava, t he source code can be loaded direct ly int o Oracle. Doing so will aut om at ically com pile t he code. Here is a sim ple form of t he loadj ava com m and:

loadjava -user scott/tiger -oci8 oreilly/plsquick/ demos/Hello.java The Hello.j ava file follows t he Java file placem ent convent ion for packages and t hus exist s in a subdirect ory nam ed oreilly/ plsquick/ dem os. We can fire up our favorit e SQL int erpret er, connect as SCOTT/ TI GER, and creat e t he call spec for t he Hello.sayI t ( ) m et hod:

CREATE FUNCTION hello_there (to_whom IN VARCHAR2) RETURN VARCHAR2 AS LANGUAGE JAVA NAME 'oreilly.plsquick.demos.Hello.sayIt (java.lang.String) return java.lang.String'; / Now we can call our funct ion very easily:

BEGIN DBMS_OUTPUT.PUT_LINE(hello_there('world')); END; / And we get t he following as t he expect ed out put :

Hello, world! 1.19.2 Publishing Java to PL/SQL To writ e a call spec, use t he AS LANGUAGE JAVA clause in a CREATE st at em ent . The synt ax for t his clause is:

{ IS | AS } LANGUAGE JAVA NAME 'method_fullname [ (type_fullname,... ] [ RETURN type_fullname ]' m et hod_fullnam e is t he package- qualified nam e of t he Java class and m et hod. I t is case- sensit ive and uses dot s t o separat e part s of t he package full nam e. t ype_fullnam e is t he package- qualified nam e of t he Java dat at ype. Not ice t hat a sim ple st ring, not a SQL nam e, follows t he NAME keyword. Type m apping follows m ost JDBC rules regarding t he legal m apping of SQL t ypes t o Java t ypes. Oracle ext ensions exist for Oracle- specific dat at ypes. Most dat at ype m appings are relat ively st raight forward, but passing Oracle obj ect s of a user- defined t ype is harder t han one would t hink. Oracle provides a JPublisher t ool t hat generat es t he Java required t o encapsulat e an Oracle obj ect and it s corresponding REF. Refer t o Oracle's JPublisher docum ent at ion for guidelines on usage. The AS LANGUAGE JAVA clause is t he sam e regardless of whet her you are using Java as a st andalone JSP, t he im plem ent at ion of a packaged program , or t he body of an obj ect t ype m et hod. For exam ple, here is t he com plet e synt ax for creat ing JSPs as PL/ SQL- callable funct ions or procedures:

CREATE [OR REPLACE] { PROCEDURE procedure_name [(param[, param]...)] | FUNCTION function_name [(param[, param]...)] RETURN sql_type } [AUTHID {DEFINER | CURRENT_USER}]

[PARALLEL_ENABLE] [DETERMINISTIC] { IS | AS } LANGUAGE JAVA NAME 'method_fullname [ (type_fullname,... ] [ RETURN type_fullname ]' When using Java as t he im plem ent at ion of a packaged procedure or funct ion, Oracle allows you t o place t he Java call spec in eit her t he package specificat ion ( where t he call spec subst it ut es for t he subprogram specificat ion) or in t he package body ( where t he call spec subst it ut es for t he subprogram body) . Sim ilarly, when using JSPs in obj ect t ype m et hods, t he Java call spec can subst it ut e for eit her t he obj ect t ype m et hod specificat ion or it s body. Not e t hat Java funct ions t ypically m ap t o PL/ SQL funct ions, but Java funct ions declared void m ap t o PL/ SQL procedures. Also, you will quickly learn t hat m ist akes in m apping PL/ SQL param et ers t o Java param et ers becom e evident only at runt im e.

1.19.3 Data Dictionary To learn what Java library unit s are available in your schem a, look in t he USER_OBJECTS dat a dict ionary view where t he obj ect _t ype is like ` JAVA% '. I f you see a Java class wit h I NVALI D st at us, it has not yet been successfully resolved. Not e t hat t he nam es of t he Java source library unit s need not m at ch t he nam es of t he classes t hey produce.

[ Team LiB ]

[ Team LiB ]

1.20 Reserved Words As we m ent ioned earlier in t his book, t he PL/ SQL language recognizes cert ain ident ifiers ( language keywords and ident ifiers from t he STANDARD package) as having special m eaning. You m ust not redefine t hese reserved words as ident ifiers in your program s. We com piled t he following t able of reserved words by t aking t he list Oracle publishes in t he V$RESERVED_WORDS dat a dict ionary view and t rying t o declare t hem ( as variables and/ or procedures) . I f t he declarat ions failed, we added t he words t o t he list . Avoid using t hese words in your program s.

ACCESS

ADD

ALL

ALTER

AND

ANY

AS

ASC

AT

AUDIT

BEGIN

BETWEEN

BY

CASE

CHAR

CHECK

CLOSE

CLUSTER

COLUMN

COLUMNS

COMMENT

COMMIT

COMPRESS

CONNECT

CREATE

CURRENT

CURSOR

DATE

DECIMAL

DECLARE

DEFAULT

DELETE

DESC

DISTINCT

DROP

ELSE

END

EXCLUSIVE

EXISTS

FILE

FLOAT

FOR

FROM

FUNCTION

GRANT

GROUP

HAVING

IDENTIFIED

IF

IMMEDIATE

IN

INCREMENT

INDEX

INDEXES

INITIAL

INSERT

INTEGER

INTERSECT

INTO

IS

LEVEL

LIKE

LOCK

LONG

MAXEXTENTS

MINUS

MLSLABEL

MODE

MODIFY

NOAUDIT

NOCOMPRESS

NOT

NOWAIT

NULL

NUMBER

OF

OFFLINE

ON

ONLINE

OPEN

OPTION

OR

ORDER

OVERLAPS

PACKAGE

PCTFREE

PRIOR

PRIVILEGES

PROCEDURE

PUBLIC

RAW

RENAME

RESOURCE

RETURN

REVOKE

ROLLBACK

ROW

ROWID

ROWNUM

ROWS

SAVEPOINT

SELECT

SESSION

SET

SHARE

SIZE

SMALLINT

START

SUCCESSFUL

SYNONYM

SYSDATE

TABLE

THEN

TO

TRIGGER

TYPE

UID

UNION

UNIQUE

UPDATE

USE

USER

VALIDATE

VALUES

VARCHAR

VARCHAR2

VIEW

WHEN

WHENEVER

WHERE

WITH

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W]

[ Team LiB ]

[ Team LiB ] [ SYM BOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] - - ( double hyphen) , specifying single- line com m ent s / * and * / , specifying m ult iline com m ent s

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] AGGREGATE USI NG keyword ALTER TYPE st at em ent anchored declarat ions AS LANGUAGE JAVA clause assigning records associat ive arrays adding/ rem oving elem ent s init ializing synt ax for declaring AUTHI D keyword aut onom ous t ransact ions 2nd

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] BFI LE dat at ype binary int eger dat at ypes BLOB dat at ype block st ruct ure in PL/ SQL body, package BOOLEAN dat at ype Boolean lit erals bulk binds and collect ions

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] CASE expressions CASE st at em ent s CAST pseudo- funct ion charact er dat at ypes charact er set in PL/ SQL CLOB dat at ype collect ions adding/ rem oving elem ent s bulk binds and declarat ion synt ax for init ializing m et hods for pseudo- funct ions for t ypes of com m ent s in PL/ SQL COMMI T st at em ent condit ional cont rol st at em ent s CONSTANT keyword const rained declarat ions const rained subt ypes CONSTRUCTOR keyword CONTEXT keyword cont rol st at em ent s condit ional sequent ial COUNT funct ion CREATE LI BRARY st at em ent cursor expressions cursor variables cursors in PL/ SQL

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] dat a dict ionary views USER_OBJECTS USER_STORED_SETTI NGS V$RESERVED_WORDS V$TI MEZONE_NAMES dat abase event s and t riggers 2nd dat abase int eract ion dat at ype conversions dat at ypes of param et ers dat e dat at ypes dat et im e int erval lit erals ( Oracle9i) DBMS_RANDOM built - in package DDL event s and t riggers 2nd decim al num eric dat at ypes declaring except ions program s records default values for param et ers DELETE procedure DELETI NG t rigger predicat e delim it ers in PL/ SQL DEREF operat or DETERMI NI STI C keyword DML event s and t riggers 2nd downcast ing subt ypes DROP event 2nd dynam ic cursors 2nd

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] except ion handling EXCEPTI ON_I NI T pragm a EXECUTE I MMEDI ATE st at em ent EXI STS funct ion EXI T st at em ent s explicit cursors expressions, cursor EXTEND procedure ext ernal procedures creat ing creat ing PL/ SQL wrappers for param et ers and ext proc processes EXTPROC_DLLS environm ent variable ext procKey ident ifier ext procSI D ident ifier

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] FETCH st at em ent fields of records FI NAL keyword m et hods in subt ypes FI RST funct ion float ing- point num bers, dat at ypes for FOR EACH ROW st at em ent FOR loops forward declarat ions of program s % FOUND at t ribut e funct ions in PL/ SQL

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] GOTO st at em ent s

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] handling except ions

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] ident ifiers in PL/ SQL I F- THEN- ELSE st at em ent s im plicit cursors I N param et ers init ializing collect ions obj ect s pack ages I NSERTI NG t rigger predicat e I NSTANTI ABLE keyword I NTERVAL keyword I S DANGLI NG predicat e. I S NULL/ I S NOT NULL synt ax % I SOPEN at t ribut e

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] Java language int egrat ion Java st ored procedures ( JSPs) JPublisher t ool

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] language fundam ent als of PL/ SQL large obj ect ( LOB) dat at ypes LAST funct ion libraries, creat ing in dat abase LI MI T funct ion list eners, set t ing up for ext ernal procedures lit erals loadj ava ut ilit y LOB ( large obj ect ) dat at ypes local program s LOCK TABLE st at em ent LOGON/ LOGOFF event s 2nd loops in PL/ SQL

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] m et hods in subt ypes ( Oracle9i) m et hods, t ypes of m odes of param et ers MULTI SET pseudo- funct ion m ut ual recursion

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] nam ed not at ion NCHAR dat at ype NCLOB dat at ype nest ed collect ions nest ed t ables init ializing 2nd synt ax for declaring nest ing records NEXT funct ion NLS ( nat ional charact er set ) dat at ypes ext ernal procedures and NOCOPY opt ion NOT I NSTANTI ABLE m et hod m odifier NOT NULL const raint % NOTFOUND at t ribut e NULL st at em ent s NULLs in PL/ SQL num eric dat at ypes num eric lit erals NVARCHAR2 dat at ype

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] obj ect t ypes, changing obj ect - orient ed feat ures OPEN FOR st at em ent OR REPLACE keyword Oracle obj ect - orient ed feat ures and PL/ SQL Oracle8i aut onom ous t ransact ions and 2nd det erm ining purit y levels of program s SQL% BULK_ROWCOUNT at t ribut e and Oracle9i CASE expressions CASE st at em ent s com piling st ored PL/ SQL program s dat et im e int erval dat at ypes 2nd ext ernal procedures m et hods in subt ypes nat ively com piling st ored program s obj ect t ypes t ype inherit ance upcast ing/ downcast ing subt ypes OUT param et ers overloading program s OVERRI DI NG m et hod m odifier

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] packaged funct ions, calling in SQL packages in PL/ SQL PARALLEL_ENABLED keyword param et ers default values for ext ernal procedures and m odes of passing argum ent s in param et er list s PI PE ROW com m and PI PELI NED keyword PLS_I NTEGER dat at ype posit ional not at ion PRAGMA keyword predicat es, t rigger PRI OR funct ion privileges and st ored PL/ SQL procedures in PL/ SQL propagat ing except ions purit y levels of program s, det erm ining

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] raising except ions records in PL/ SQL recursion, m ut ual REF operat or REF_CURSOR t ypes referencing fields of records REPEAT UNTI L loop em ulat ion reserved words in PL/ SQL 2nd RESTRI CT_REFERENCES pragm a 2nd RETURN keyword ROLLBACK st at em ent % ROWCOUNT at t ribut e % ROWTYPE at t ribut e

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] SAVEPOI NT st at em ent scalar dat at ypes scope of except ions searched CASE expressions searched CASE st at em ent s SELECT FOR UPDATE clause sequent ial cont rol st at em ent s SERI ALLY_REUSABLE pragm a 2nd SERVERERROR event 2nd SET TRANSACTI ON st at em ent SHUTDOWN event 2nd specificat ion, package SQL st at em ent s, calling st ored funct ions from SQL% BULK_ROWCOUNT at t ribut e SQL% FOUND at t ribut e SQL% I SOPEN at t ribut e SQL% NOTFOUND at t ribut e SQL% ROWCOUNT at t ribut e SQLCODE funct ion SQLERRM funct ion STARTUP event 2nd st at em ent s in PL/ SQL st at ic cursors st ored funct ions, calling from SQL st at em ent s st ored program s, com piling nat ively st ring lit erals subt ypes, const rained/ unconst rained

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T ] [ U] [ V] [ W] t able funct ions TABLE pseudo- funct ion t im e dat at ypes t ransact ion m anagem ent TREAT operat or t riggers in PL/ SQL TRI M procedure % TYPE at t ribut e t ype inherit ance ( Oracle9i)

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] unconst rained subt ypes UNDER keyword upcast ing subt ypes UPDATI NG t rigger predicat e USER_OBJECTS dat a dict ionary view USER_STORED_SETTI NGS dat a dict ionary view

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W] V$RESERVED_WORDS dat a dict ionary view V$TI MEZONE_NAMES dat a dict ionary view VALUE operat or VARCHAR2 dat at ype variables declaring default values of VARRAYs init ializing 2nd synt ax for declaring

[ Team LiB ]

[ Team LiB ] [ SYMBOL] [ A] [ B] [ C] [ D] [ E] [ F] [ G] [ H] [ I ] [ J] [ L] [ M] [ N] [ O] [ P] [ R] [ S] [ T] [ U] [ V] [ W ] WHEN OTHERS clause WHERE CURRENT OF clause WHI LE loops wrappers for ext ernal procedures

[ Team LiB ]