Oracle PL/SQL Best Practices
By St even Feuer st ein
Publisher : O'Reilly
Pub Dat e : Apr il 2001
I SBN : 0- 596- 00121- 5
Pages : 202
Or a cle PL/ SQL Be st Pr a ct ice s is a con cise , e a sy - t o- u se su m m a r y of be st
pr a ct ice s in t h e pr ogr a m de v e lop m e n t pr oce ss. I t cov e r s cod in g st y le , w r it in g SQL in PL/ SQL, d a t a st r u ct u r e s, con t r ol st r u ct u r e s, e x ce pt ion h a n dlin g, p r og r a m a n d p a ck a ge con st r u ct ion , a n d b u ilt - in p a ck a ge s. Com ple m e n t a r y code e x a m p le s a r e a v a ila b le on t h e O' Re illy w e b sit e . I n clu de s a pu ll- ou t q u ick - r e fe r e n ce ca r d.
Pr e fa ce
When I fir st st ar t ed w r it ing about t he Or acle PL/ SQL language back in 1994, t he only sour ces of infor m at ion w er e t h e pr oduct docu m ent at ion ( such as it w as) and t he occasional paper and pr esent at ion at Or acle User Gr oup ev ent s. Today, t her e ar e at least a dozen books t hat focu s exclusively on PL/ SQL, num er ous pr oduct s t hat help you w r it e PL/ SQL code ( int egr at ed dev elopm ent envir onm ent s, kn ow ledge bases, et c.) , t r aining classes, and w eb sit es. And t he com m unit y of PL/ SQL developer s cont inues t o gr ow in size and m at ur it y, even w it h t he advent of Java.
Access t o infor m at ion about PL/ SQL is no longer t he challenge. I t can, on t he ot her hand, be difficult t o m ake sense of all t he new feat ur es, t he num er ous r esou r ces, t he choices for t ools, and so on. When it com es t o w r it ing a pr ogr am or an ent ir e
applicat ion, developer s have, ov er and over again, expr essed t he desir e for advice. They ask:
• How should I for m at m y code?
• What nam ing convent ions, if any, sh ould I use?
• How can I w r it e m y packages so t hat t hey can be m or e easily m aint ained?
• What is t he best w ay t o quer y infor m at ion fr om t he dat abase?
• How can I get all t he developer s on m y t eam t o handle er r or s t he sam e w ay?
So m any qu est ions, so m uch bur ning desir e t o w r it e code w ell, and so few r esou r ces available t o help us do t hat .
im m ediat ely applicable, quickly locat ed advice t hat w ill assist you in w r it ing code t hat is r eadable, m aint ainable, and efficient .
You w ill undoubt edly find r ecom m endat ions in t his book t hat also appear in som e of m y ot her books; I hope you w ill not be offended by t his r epet it ion. I t 's sim ply im possible t o offer in a single book ev er yt hing t hat can and should be w r it t en about t he Or acle PL/ SQL language. While I plan t o r einfor ce t hese best pr act ices in t he appr opr iat e places in m y ot her t ext s, I believe t hat w e w ill all benefit fr om also having t hem available in one concise book, a book designed, beginning t o end, t o give you quick access t o m y r ecom m endat ions for ex cellent PL/ SQL coding
t echniques.
St r u ct u r e of Th is Book
Or acle PL / SQL Best Pr act ices is com posed of nine chapt er s and on e appendix. Each
chapt er cont ains a set of best pr act ices for a par t icular ar ea of funct ionalit y in t he PL/ SQL language. For each best pr act ice, I 've pr ovided as m any of t he following elem ent s as ar e applicable:
Tit le
A single sent ence t hat descr ibes t he best pr act ice and pr ovides an ident ifier for it in t he for m XXX- n n ( w her e XXX is t he t ype of best pr act ice—for exam ple,
EXC for except ion handling—and nn is t he sequ ent ial num ber w it hin t his set
of best pr act ices) ; see Sect ion P.4 for how t o use t his ident ifier online. I have, w henev er possible, sou ght t o m ak e t his t it le st and on it s ow n. I n ot her w or ds, you sh ould be able t o glance at it and under st and it s im pact on how you w r it e code. This w ay, aft er y ou've r ead t he ent ir e best pr act ice, you can use
Appendix A t o inst ant ly r em ind you of best pr act ices as you w r it e y our code.
Descr ipt ion
A lengt hier explanat ion of t he best pr act ice. I t 's sim ply not possible t o cov er all t he nuances in a single sent ence!
Exam ple
We lear n best fr om exam ples, so j ust about ev er y best pr act ice illust r at es, t hr ough code and/ or an ecdot e, t he value of t h e best pr act ice. Wh enev er it m akes sense, I put t he exam ple code in a file t hat you can u se ( or lear n fr om ) in your ow n pr ogr am m ing envir onm ent . You'll find t hese files on t h e O'Reilly w eb sit e ( see Sect ion P.4 lat er in t his Pr eface) .
Benefit s
Why sh ould you bot her w it h t his best pr act ice? How cr ucial is it for you t o follow t his par t icular r ecom m endat ion? This sect ion offer s a quick r eview of t he m ain benefit s you w ill see by follow ing t he best pr act ice.
Wouldn't it be gr eat if w e lived in a w or ld in w hich follow ing a best pr act ice w as all- ar ound easier t h an t he " quick and dir t y" appr oach? That is,
unfor t unat ely, not alw ays t he case. This elem ent w ar ns y ou about t he
challenges, or dr aw back s, y ou m ight face as you im plem ent t he best pr act ice.
Resour ces
I n t he w or ld of t he I nt er net , ever yt hing is connect ed; no pr ogr am m er st ands alone! This sect ion r ecom m ends r esou r ces, r an ging fr om books t o URLs t o files cont aining code, t hat you can use t o h elp you successfully follow t his best pr act ice. Wher e filenam es ar e sh ow n in t his sect ion, t hey r efer t o files available on, or r efer enced by, t he O'Reilly w eb sit e.
Her e ar e br ief descr ipt ions of t he chapt er s and appendix:
Chapt er 1 st eps back fr om specific pr ogr am m ing r ecom m endat ions. I t offer s advice about how t o im pr ov e t he over all pr ocess by w hich you w r it e code.
Chapt er 2 offer s a ser ies of suggest ions on h ow t o for m at and or ganize your code so t hat it is m or e r eadable and, t her efor e, m or e m aint ainable.
Chapt er 3 t akes a close look at how y ou ought t o declar e and m anage dat a w it hin your PL/ SQL pr ogr am s.
Chapt er 4 is a " back t o basics" chapt er t hat t alks about t he best w ay t o w r it e I F st at em ent s, loops, and ev en t he GOTO st at em ent ! Sur e, t hese ar en't t er r ibly
com plicat ed const r u ct s, but t her e ar e st ill r ight and w r ong w ays t o w or k w it h t hem .
Chapt er 5 cov er s anot h er cr it ical aspect of r obust applicat ion dev elopm ent : ex cept ion handling, or w hat t o do w hen t hings go w r ong.
Chapt er 6 focuses on t h e m ost cr ucial aspect of PL/ SQL dev elopm ent : how y ou should w r it e t he SQL st at em ent s in your pr ogr am s.
Chapt er 7 offer s advice on how best t o build your pr ocedur es, funct ions, and t r igger s—t he pr ogr am unit s t hat cont ain your business logic. I t also includes best
pr act ices for par am et er const r uct ion.
Chapt er 8 st eps back fr om individual pr ogr am unit s t o pr esent r ecom m endat ions for packages, t h e building blocks of any w ell- designed PL/ SQL- based applicat ion.
Chapt er 9 focuses on how t o t ak e best advant age of a few of t he m ost oft en used of t he packages pr ovided t o us by Or acle Cor por at ion.
Appendix A com piles t he best pr act ice t it les acr oss all t he chapt er s int o a concise r esou r ce. Once y ou hav e st udied t he individual best pr act ices, y ou can use t his appendix as a ch ecklist , t o be r eview ed befor e you begin coding a new pr ogr am or applicat ion.
My pr im ar y goal in w r it ing t his book w as t o cr eat e a r esou r ce t hat w ould m ake a concr et e, n ot iceable differ ence in t he qualit y of t he PL/ SQL code y ou w r it e. To accom plish t his, t he book needs t o be useful and usable not j ust for gener al st udy, but also for day- t o- day , pr ogr am - t o- pr ogr am t asks. I t also n eeds t o be concise and t o t he point . A 1,000- page t ext on best pr act ices w ould be ov er w helm ing,
int im idat ing, and har d t o use.
The r esult is t his r elat ively br ief ( I consider an y publicat ion under 200 pages a m aj or per sonal accom plishm ent ! ) , highly st r uct ur ed book . I r ecom m end t hat you appr oach
Or acle PL/ SQL Best Pr act ices as follow s:
1. Read Sect ion P.3. Som e of t h e best pr act ices in t his book—w hole chapt er s, in
fact—w ill have a m uch higher im pact t han ot her s on t he qualit y and efficiency
of your code. I f you find t hat your cur r ent pr act ices ( or t hose of y our or ganizat ion) ar e far fr om t he m ar k, t h en y ou w ill have ident ified your pr ior it ies for init ial st udy.
2. Skip t o Appendix A and per use t he best pr act ice t it les fr om each chapt er . I f you hav e been pr ogr am m ing for any lengt h of t im e, you w ill pr obably find your self t hinking: " Yes, I do t hat ," and " Uh- huh, w e'v e got t hat one cov er ed." Gr eat ! I w ould st ill encour age y ou t o r ead w hat I 've got t o say on t hose t opics, as y ou m ight be able t o deepen y our know ledge or lear n new t echniques. I n any case, a quick r eview of t he appendix w ill allow you t o ident ify ar eas t hat ar e new t o y ou, or per h aps st r ike a ch or d, as in " Oh m y gosh, t hat pr ogr am I w r ot e last w eek does ex act ly w hat St even say s t o av oid. Bet t er ch eck t hat out ! "
3. Dive int o individual chapt er s or best pr act ices w it hin chapt er s. Read a best pr act ice, w r est le w it h it , if necessar y, t o m ake sur e t hat y ou r eally, t r uly agr ee w it h it . And t hen apply t hat best pr act ice. This isn't an academ ic ex er cise. You w ill only t r uly absor b t he lesson if you apply it t o you r code—if
you hav e a pr oblem or pr ogr am t hat can be im pr ov ed by t he best pr act ice.
I f y ou ar e n ew t o pr ogr am m ing or new t o PL/ SQL, y ou w ill cer t ainly also benefit gr eat ly fr om a cov er - t o- cov er r eading of t he t ex t . I n t his case, don 't t r y t o fully absor b and t est out ev er y best pr act ice. I nst ead, r ead and t hink about t he best pr act ices w it hout t he pr essu r e of applying each one. When you ar e don e, t r y t o pict ur e t he best pr act ices as a w hole, r einfor cing t he follow ing t hem es:
• I w ant t o w r it e code t hat I—and ot her s—can easily under st and and change as
needed.
• The w or ld is t er r ibly com plex, so I should st r ive t o k eep m y code sim ple. I can t hen m eet t hat com plexit y t hr ough car efully designed int er act ion bet w een elem ent s of m y code.
Then y ou w ill be r eady t o go back t o individual chapt er s and deepen you r under st anding of individual best pr act ices.
The ot her cr ucial w ay t o t ake advant age of t his book is t o use t he code pr ovided on t he com panion w eb sit e. See Sect ion P.4 for det ailed infor m at ion on t he soft w ar e t hat w ill help you br ing your best pr act ices t o life.
This book cont ains abou t 120 dist inct r ecom m endat ions. I could have included m any, m any m or e. I n fact , I filled up a Rej ect s docum ent as I w r ot e t he book. Following t he pr ov en, " t op- dow n" appr oach, I fir st cam e up w it h a list of best pr act ices in each ar ea of t he language. Then I w ent t hr ough each ar ea, filling in t he descr ipt ions, exam ples, and so on . As I did t his, I encount er ed num er ous " best pr act ices" t hat sur ely w er e t he r ight w ay t o do t hings. The r ealit y, how ev er , is t hat few people w ould ever bot her t o r em em ber and follow t hem , and if t hey did bot her , it w ould not m ake a significant differ ence in t heir code.
I had r ealized, you see, t hat not all best pr act ices ar e cr eat ed equal. Som e ar e m uch, m uch m or e im por t ant t han ot her s. And som e ar e j ust bet t er left out of t he book, so t hat r eader s ar en't dist r act ed by " clut t er ." I hope t hat t he r esult—t his book—has an
im m ediat e and last ing im pact . But ev en am ong t he best pr act ices I didn't r ej ect , som e st and out as being especially im por t ant—so I 'v e decided t o aw ar d t hese best
pr act ices t h e following pr izes:
Gr and Pr ize
SQL- 00: Est ablish and follow clear r ules for how t o w r it e SQL in your applicat ion. ( See Chapt er 6.)
Fir st Pr ize
MOD- 01: Encapsulat e and nam e business r ules and for m ulas behind funct ion header s. ( See Chapt er 7.)
Second Pr ize: Tw o Winner s
EXC- 00: Set guidelines for applicat ion- wide er r or handling befor e you st ar t coding. ( See Chapt er 5.)
PKG- 02: Pr ovide w ell- defined int er faces t o business dat a and funct ional m anipulat ion using packages. ( See Chapt er 8.)
Thir d Pr ize: Fou r Winner s
MOD- 03: Lim it execut ion sect ion sizes t o a single page using m odularizat ion. ( See Chapt er 7.)
DAT- 15: Expose package globals using " get and set " m odules. ( See Chapt er 3.)
DEV- 03: Walk t hr ough each ot her 's code. ( See Chapt er 1.)
STYL- 09: Com m ent t er sely w it h value- added infor m at ion. ( See Chapt er 2.)
I f y ou follow each of t hese " best of t he best " pr act ices, you w ill end up w it h applicat ions t hat ar e t he j oy and envy of developer s ever y w her e!
The best w ay t o lear n how t o w r it e good code is by analyzing and follow ing exam ples. Alm ost ev er y best pr act ice offer ed in t his book includes a code exam ple, bot h in t he t ext and in dow nloadable for m fr om t he Or acle PL/ SQL Best Pr act ices sit e, av ailable t hr ough t he O'Reilly & Associat es sit e at :
ht t p: / / w w w .or eilly.com / cat alog/ or best pr ac
To locat e t he code for y our best pr act ice, sim ply ent er t h e best pr act ice ident ifier , such as BI P- 1 0 , in t he sear ch field. You w ill t hen be dir ect ed t o t h e associat ed code. You can also br ow se t he sit e by t opic ar ea. You can ev en offer y our ow n insight s about PL/ SQL best pr act ices, so I encour age you t o visit and cont r ibut e.
As a r ule, I w ill follow m y ow n best pr act ices in t hese exam ples ( unless t he point of t he code is t o dem onst r at e a " bad pr act ice" ! ) . So, for exam ple, y ou w ill r ar ely see m e using DBMS_OUTPUT.PUT_ LI NE, ev en t hou gh t his " show m e" capabilit y is needed in m any pr ogr am s. As I m ent ion in [BI P- 01: Av oid using t he
DBMS_OUTPUT.PUT_LI NE pr ocedu r e dir ect ly.] , you should avoid calling t his pr ocedur e dir ect ly; inst ead, build or use an encapsulat ion over
DBMS_OUTPUT.PUT_LI NE. So r at her t han seeing code like t his:
DBMS_OUTPUT.PUT_LINE (l_date_published);
you w ill inst ead encount er a call t o t he " pl" or " put line" pr ocedur e:
pl (l_date_published);
I also m ak e m any r efer ences t o PL/ Vision packages. PL/ Vision is a code libr ar y, consist ing of m or e t han 60 packages t hat offer 1,000- plus pr ocedu r es and funct ions t o per for m a m y r iad of useful t asks in PL/ SQL applicat ions. I have deposit ed m uch of w hat I have lear ned in t he last five y ear s about PL/ SQL int o PL/ Vision, so I nat ur ally r et ur n t o it for exam ples. Any package m ent ioned in t his book w hose nam e st ar t s w it h " PLV" is a PL/ Vision package.
A com plet ely fr ee, " lit e" ver sion of PL/ Vision is available fr om t he PL/ SQL Pipeline Ar chives at :
ht t p: / / w w w .r ev ealnet .com / Pipelines/ PLSQL/ ar chives.ht m
Select t he " Rev ealNet Act ive PL/ SQL Know ledge Base" fr om t he list . ( You m ight also like t o dow nload and t r y out t he ot her code y ou'll find t her e.) A com m er cial ver sion of PL/ Vision ( wit h m or e packages and funct ionalit y t han t he lit e ver sion) is cur r ent ly available inside t he Rev ealNet Act ive PL/ SQL Know ledge Base
(ht t p: / / w w w .r ev ealnet .com /) .
Whenev er possible, t he code I pr ovide for t he book can be used t o gen er at e best -pr act ice- based code and as -pr ebuilt , gener alized com ponent s in your applicat ions, code t hat y ou can use w it hout having t o m ake any m odificat ions.
" pr ot ot ypes" ; t h ey w or k as adv er t ised, but y ou w ill pr obably w ant t o m ake som e changes befor e you put t hem int o pr oduct ion applicat ions.
And you sh ould m ost cer t ainly t est ever y single pr ogr am y ou use fr om Or acle PL
/ SQL Best Pr act ices ! I have r un som e t est s, an d m y w onder ful t echnical r eview er s
have also ex er cised t he code. I n t h e end, how ev er , if t he code goes int o you r applicat ion, you ar e r esponsible for m aking sur e t hat it m eet s y our n eeds.
Ot h e r Re sou r ce s
This book is int ended t o com plem ent num er ous ot her r esour ces for PL/ SQL
dev eloper s. I t is, t o m y know ledge, t h e fir st collect ion of best pr act ices specifically for t he Or acle PL/ SQL language. On t he ot h er h and, it doesn't st and on it s ow n as a com pr eh ensive r esour ce, eit her for PL/ SQL, in par t icular , or for Or acle applicat ion dev elopm ent , in gener al.
What follow s is by no m eans an exhaust ive list of r esou r ces for dev eloper s. How ever , I find t hat a 15- page bibliogr aphy is m or e int im idat ing t han it is helpful. So I offer t his shor t list of t he r esour ces t hat I hav e r ecent ly found m ost useful and int er est ing:
Code Com plet e by St ev en McConnell ( Micr osoft Pr ess)
A classic t ext , t his " pr act ical handbook of soft w ar e cr it icism " should be on t he book shelf of ever y developer or at least in your t eam 's libr ar y. Chock- fu ll of pr act ical advice for const r uct ing code, it show s exam ples in m any languages, including Ada, w hich is enough like PL/ SQL t o m ake lear ning fr om McConnell a br eeze. Don't st ar t coding w it hout it ! The w eb sit e for St ev en McConnell's consult ing pr act ice, ht t p: / / w w w .con st r ux.com /, is also packed w it h lot s of good advice.
Refact or ing by Mar t in Fow ler ( Addison Wesley)
Accor ding t o t his book, " r efact or ing is t he pr ocess of changing a soft w ar e syst em in such a w ay t hat it doesn't alt er t h e ex t er nal of t he code, y et im pr oves it s int er nal st r uct ur e." Sound gr eat , or w hat ? This ex cellent book uses Java as it s exam ple language, but t he w r it ing is clear and t he Java st r aight for w ar d. Th er e is m uch t o apply her e t o PL/ SQL pr ogr am m ing.
Ext r em e Pr ogr am m ing Explained, by Kent Beck ( Addison Wesley)
This book is a highly r eadable and concise int r oduct ion t o Ext r em e
Pr ogr am m ing ( XP) , a light w eight soft w ar e dev elopm ent m et hodology. Visit ht t p: / / w w w .xpr ogr am m ing.com / or ht t p: / / w w w .ext r em epr ogr am m ing.or g/ for a glim pse int o t he w or ld of t his int er est ing appr oach t o dev elopm ent .
And t hen, of cour se, t her e is m y ow n oeuvr e, t he Or acle PL/ SQL Ser ies fr om O'Reilly & Associat es, w hich includes:
The com plet e language r efer en ce for Or acle PL/ SQL.
Or acle PL/ SQL Pr ogr am m ing: Guide t o Or acle8i Feat ur es
A com panion volum e descr ibing t he Or acle8i addit ions t o t he PL/ SQL language.
Or acle PL/ SQL Dev eloper 's Wor kbook, w it h Andr ew Odew ahn
A w or kbook cont aining pr oblem s ( and accom panying solut ions) t hat w ill t est your know ledge of Or acle PL/ SQL language feat ur es.
Or acle Built - in Packages, w it h Char les Dy e and John Ber esniew icz
A com plet e r efer ence t o t he m any built - in packages pr ovided by Or acle Cor por at ion.
Advanced Or acle PL/ SQL Pr ogr am m ing w it h Packages
A descr ipt ion of how t o w r it e you r ow n PL/ SQL packages, including a lar ge num ber of packages you can use in your ow n pr ogr am s.
Or acle PL/ SQL Language Pocket Refer ence, w it h Bill Pr ibyl and Chip Daw es
A quick r efer ence t o t he PL/ SQL language synt ax.
Or acle PL/ SQL Built - ins Pocket Refer ence, w it h John Ber esniew icz and Chip Daw es
A quick r efer ence t o t he calls t o t he Or acle built - in funct ions and packages.
Con v e n t ion s Use d in Th is Book
The following t ypogr aphical convent ions ar e used in t his book:
I t alic
I ndicat es filenam es, dir ect or y nam es, and URLs. I t 's also used for em phasis and for t he fir st use of a t echnical t er m .
Bold
Used w h en r efer r ing, by num ber , t o a best pr act ice descr ibed in t his book ( e.g., [BI P- 04: Handle expect ed and nam ed except ions w hen per for m ing file I / O.] ) .
Const ant w idt h
Constant width bold
I ndicat es code ent er ed by a user ( e.g., via SQL* Plus) or t o highlight code lines being discussed.
UPPERCASE
I n code exam ples, indicat es PL/ SQL k eyw or ds.
low er case
I n code exam ples, indicat es user - defined it em s ( e.g., var iables) .
This icon designat es a not e, w hich is an im por t ant
aside t o t he near by t ext . For exam ple, I 'll use t his icon
w hen suggest ing t he use of an alt er nat ive feat ur e.
This icon designat es a w ar ning r elat ing t o t he near by
t ext . For exam ple, I 'll use t his icon w hen a par t icular
feat ur e m ight affect per for m ance or pr eclude use of
som e ot her feat ur e.
Com m e n t s a n d Qu e st ion s
Please addr ess com m en t s and quest ions concer ning t his book t o t he publisher :
O'Reilly & Associat es, I n c. 101 Mor r is St r eet
Sebast opol, CA 95472
( 800) 998- 9938 ( in t he Unit ed St at es or Canada) ( 707) 829- 0515 ( int er nat ional/ local)
( 707) 829- 0104 ( fax)
Ther e is a w eb page for t his book, w hich list s er r at a, exam ples, or any addit ional infor m at ion. You can access t his page at :
ht t p: / / w w w .or eilly.com / cat alog/ or best pr ac
To com m ent or ask t ech nical quest ions about t his book, send em ail t o:
bookqu est ions@or eilly.com
For m or e infor m at ion about books, confer ences, soft w ar e, Resour ce Cent er s, and t he O'Reilly Net w or k , see t h e O'Reilly w eb sit e at :
ht t p: / / w w w .or eilly.com /
Thanks go, fir st of all, t o m y edit or of six year s at O'Reilly & Associat es, Debor ah Russell. She got m e off t he dim e on t his pr oj ect and helped m e t u r n it ar ound in r ecor d t im e ( I st ar t ed doing ser ious w r it ing on t his book in Oct ober 200 0 and finished it up in Januar y 2001) . I t w as, once again, a r eal pleasur e w or king w it h you, Debby!
Thanks as w ell t o t he ot her O'Reilly people w ho t ur ned t his book int o a finished pr oduct : Mar y Anne Weeks May o, t h e pr oduct ion edit or ; Ellie Volckhausen, w h o designed t he cov er ; and Car oline Senay, t h e edit or ial assist ant w ho helped in m any w ays t hr oughout t he pr oj ect .
Many out st anding Or acle developer s and DBAs cont r ibut ed t heir t im e and exper t ise, t hr ough t echnical r eview , code sam ples, or w r it ing. My deep- felt gr at it ude goes out t o: John Ber esniew icz, Rohan Bishop, Dick Bolz, Dan Clam age, Bill Caulkins, Dan Condon- Jones, Faw w ad- uz- Zafar Siddiqi, Ger ar d Har t ger s, Edw in van Hat t em , Dw ayne King, Dar r yl Hu r ley, Giovanni Jar am illo, Vadim Loev ski, Pav el Luzanov, Mat t hew MacFar land, Jeffr ey Meens, Jam es " Padder s" Padfield, Rakesh Pat el, Bill Pr ibyl, Andr e Ver gison ( t he br ains behind PL/ For m at t er ) , and Solom on Yakobson. This book benefit ed, in par t icular , fr om a r ew or king of best pr act ice t it les by John Ber esniew icz, close r eadings of m an y chapt er s by Dan Clam age ( w hose ex cellent com m ent s on cer t ain best pr act ices I 've included as sidebar s in t he t ext ) , and t he cont r ibut ion of t r igger best pr act ices by Dar r yl Hur ley.
Or acle PL/ SQL Best Pr act ices is a m u ch im pr ov ed t ext as a r esult of all of your
assist ance, m y fr iends. Any er r or s, on t he hand, ar e ent ir ely m y fault and r esponsibilit y.
I w ould also like t o t hank m y w ife, Veva, for volunt eer ing t o pick up Eli fr om Jor dan's house so t hat I could st ay behind and w r it e t hese acknow ledgm ent s ( oh, and also for adding layer upon layer of m eaning and happiness t o m y life) .
Ch a pt e r 1 . Th e D e v e lopm e n t Pr oce ss
To do y our j ob w ell, you need t o be aw ar e of, and t o follow , bot h " lit t le" best pr act ices—ver y focused t ips on a par t icular coding t echnique—and " big" best
pr act ices. This chapt er offer s som e suggest ions on t he big pict ur e: how t o w r it e you r code as par t of a high- qualit y dev elopm ent pr ocess.
My obj ect ive isn't t o " sell" you on any par t icular dev elopm ent m et hodology ( t hough I m ust adm it t hat I am m ost at t r act ed t o so- called " light w eight " m et hodologies such as Ext r em e Pr ogr am m ing and SCRUM) .[ 1] I n st ead, I 'll r em ind you of basic pr ocesses
you sh ould follow w it hin any big- pict ur e m et hodology.
I n ot her w or ds, if you ( or you r m et hodology) don't follow som e for m of t he best pr act ices in t his chapt er , y ou ar e less likely t o pr oduce high- qualit y, successful soft w ar e. I don't ( w it h per haps a single except ion) suggest a specific pat h or t ool. You j ust need t o m ak e sur e you've got t hese bases cov er ed.
D EV - 0 1 : Se t st a n da r ds a n d gu ide lin e s be for e
w r it in g a n y code .
These st andar ds and gu idelines w ould, if I had m y w ay , include m any or all of t he best pr act ices descr ibed in t his book. Of cour se, you n eed t o m ake you r ow n decisions about w hat is m ost im por t ant and pr act ical in your ow n par t icular envir onm ent .
Key ar eas of dev elopm ent for w hich you sh ould pr oact ively set st andar ds ar e:
• Select ion of dev elopm ent t ools : You should no longer be r elying on SQL* Plus
t o com pile, execut e, and t est code; on a basic edit or like Not epad t o w r it e t he code; or on EXPLAI N PLAN t o analyze applicat ion per for m ance. Soft w ar e com panies offer a m ult it ude of t ools ( w it h a w ide r ange of funct ionalit y and pr ice) t hat w ill help dr am at ically im pr ove y our dev elopm ent envir onm ent . Decide on t he t ools t o be used by all m em ber s of t he developm ent gr oup.
• How SQL is w r it t en in PL/ SQL code : The SQL in your applicat ion can be t he
Achilles' heel of y our code base. I f you ar en 't car eful about how y ou place SQL st at em ent s in your PL/ SQL code, y ou'll end up w it h applicat ions t hat ar e difficult t o opt im ize, debug, and m anage ov er t im e.
• An except ion handling ar chit ect u r e : User s hav e a har d t im e under st anding
how t o use an applicat ion cor r ect ly, and developer s hav e an ev en har der t im e debugging and fixing an applicat ion if er r or s ar e handled inconsist ent ly ( or n ot at all) . The best w ay t o im plem ent applicat ion- w ide, consist ent er r or h andling is t o use a st andar dized package accor ding t o specific guidelines.
• Pr ocesses for code r eview and t est ing : Th er e ar e som e basic t en et s of
pr ogr am m ing t hat m ust not be ignor ed. You sh ould never put code int o pr oduct ion w it hout having it r eview ed by on e or m or e ot her developer s, and w it hout per for m ing exhaust ive t est ing. Ast onishingly, m any ( if not m ost ) PL/ SQL developm ent shops hav e n eit her st andar d, m andat or y code r eview s nor a st r ict t est ing r egim en.
Best pr act ices t hr oughout t his chapt er and t he r est of t he book addr ess t hese cr ucial aspect s of soft w ar e dev elopm ent . You w ill also find m any r elevant exam ples
t hr oughout t he book.
Be n e fit s
Ch a lle n g e s
The deadline pr essur es of m ost applicat ions m it igat e against t aking t he t im e up fr ont t o est ablish st andar ds, ev en t hough w e all know t hat such st andar ds ar e likely t o save t im e dow n t he line.
D EV - 0 2 : Ask for h e lp a ft e r 3 0 m in u t e s on a
pr oble m .
Follow ing t his sim ple piece of advice w ill pr obably have m or e im pact on your code t han anyt hing else in t his book!
How m any t im es hav e y ou st ar ed at t he scr een for hour s, t r ying t his and t hat in a vain at t em pt t o fix a pr oblem in your code? Finally, exhaust ed and desper at e, you call over y our cubicle w all: " Hey, Melinda, could you com e ov er her e and look at t his?" Wh en Melinda r eaches you r cube sh e sees in an inst ant w hat you, aft er h our s, st ill could not see. Gosh , it 's like m agic!
Except it 's not m agic and it 's not m yst er ious at all. Rem em ber : hum ans w r it e
soft w ar e, so an under st anding of hum an psych ology is cr ucial t o set t ing up pr ocesses t hat encour age qualit y soft w ar e. We hum ans ( especially t he m ales of t he species) like t o get t hings r ight , like t o solve our ow n pr oblem s, and do n ot like t o adm it t hat w e don't kn ow w hat is going on. Consequent ly, w e t end t o w ant t o hide our
ignor ance and difficult ies. This t endency leads t o m any w ast ed hour s, h igh levels of fr ust r at ion, and, u sually, nast y, spaghet t i code.
Team leader s and developm ent m anager s need t o cult ivat e an envir onm ent in w hich w e ar e en cour aged t o adm it w hat w e do not kn ow , and ask for h elp ear lier r at her t han lat er . I gn or ance isn't a pr oblem unless it is hidden fr om view . And by asking for help, you validat e t he know ledge and exper ience of ot her s, building t he ov er all self-est eem and confidence of t he t eam .
Ther e is a good chance t hat if you spend 30 m inut es fr uit lessly analyzing your code, t w o m or e hou r s w ill not get y ou any fu r t her along t o a solut ion. I nst ead, get in t he habit of shar ing your difficult y w it h a cow or ker ( pr efer ably an assigned " buddy," so t he line of com m unicat ion bet w een t he t w o of y ou is officially acknow ledged and doesn't r epr esent in any w ay acknow ledgem ent of a failur e) .
Ex a m ple
Pr ogr am m er s ar e a pr oud and noble people. We don 't like t o ask for h elp; w e like t o bur y ou r noses in our scr een and cr eat e. So t he biggest challenge t o get t ing people t o ask for help is t o change behavior s. Her e ar e som e suggest ions:
exper t ise. Then convince her t o seek out t he advice of ot h er s. Once t he leader ( for m al or infor m al) show s t hat it is OK t o adm it ignor ance, ev er y one else w ill gladly j oin in.
• Post r em inder s in w or k ar eas, per haps ev en individual cubicles, such as " STUCK? ASK FOR HELP" and " I T'S OK NOT TO KNOW EVERYTHI NG." We need t o be r em inded about t hings t hat don't com e nat ur ally t o us.
Be n e fit s
Pr oblem s in code ar e ident ified and solved m or e r apidly. Few er h our s ar e w ast ed in a fut ile hunt for bugs.
Know ledge about t he applicat ion and about t he under lying soft w ar e t echnology is shar ed m or e evenly acr oss t he dev elopm ent t eam .
Ch a lle n g e s
The m ain challenge t o successful im plem ent at ion of t his best pr act ice is psych ological: don't be afr aid t o adm it you don 't know som et hing or ar e having t r ouble figur ing som et hing out .
Re sou r ce s
Peoplew ar e : Pr oduct iv e Pr oj ect s and Team s, by Tom DeMar co and Tim ot hy List er
( Dor set House) . This is a fant ast ic book t hat com bines deep exper ience in pr oj ect m anagem ent w it h hum or and com m on sense.
D EV - 0 3 : W a lk t h r ou gh e a ch ot h e r ' s code .
Soft w ar e is w r it t en t o be ex ecut ed by a m achine. These m achines ar e ver y, ver y fast , but t hey ar en't t er r ibly sm ar t . They sim ply do w hat t hey ar e t old, follow ing t he
inst r uct ions of t he soft w ar e w e w r it e, as w ell as t he m any ot her layer s of soft w ar e t hat cont r ol t he CPU, st or age, m em or y, et c.
I t is ext r em ely im por t ant , t her efor e, t hat w e m ake sur e t he code w e w r it e does t he r ight t hing. Our com put er s can 't t ell us if w e m issed t he m ar k ( " gar bage in, gar bage out " or , unfor t unat ely, " gar bage in, gospel out " ) . The usual w ay w e validat e code is by r unning t hat code an d checking t he out com es ( w ell, act ually, in m ost cases w e have our user s r un t he code and let us kn ow about failur es) . Su ch t est s ar e, of cour se, cr ucial and m ust be m ade. But t h ey ar en't enough.
A cr ucial com plem ent t o for m al t est ing of code is a for m alized pr ocess of code r eview or w alk- t hr ough. Code r eview involves having ot her dev eloper s act ually r ead and r eview you r sour ce code. This r eview pr ocess can t ake m any differ ent for m s, including:
• The buddy syst em : Each pr ogr am m er is assigned anot her pr ogr am m er t o be
r eady at any t im e t o look at his buddy's code an d t o offer feedback.
• For m al code w alkt hr oughs : On a r egular basis ( and cer t ainly as a " gat e"
befor e any pr ogr am m oves t o pr odu ct ion st at us) , a developer pr esent s or " w alks t hr ough" her code befor e a gr oup of pr ogr am m er s.
• Pair pr ogr am m ing : No one codes alone! When ev er you w r it e soft w ar e, y ou
do it in pair s, w her e one per son handles t he t act ical w or k ( t hinks about t he specific code t o be w r it t en and does t he t yping) , w hile t he second per son t akes t he st r at egic r ole ( keeps an ey e on t he ov er all ar chit ect ur e, looks out for possible bugs, and gener ally cr it iques—alw ays const r uct ively) . Pair
pr ogr am m ing is an int egr al par t of Ext r em e Pr ogr am m ing.
Be n e fit s
Ov er all qualit y of code incr eases dr am at ically. The ar chit ect ur e of t he applicat ion t ends t o be sounder , and t he num ber of bugs in pr oduct ion code goes w ay dow n. A fur t her advant age is t hat of st aff educat ion—not j ust aw ar eness of t he pr oj ect , but
also an incr ease in t ech nological pr oficiency due t o t he syner gist ic effect of w or king t oget her .
Ch a lle n g e s
The dev elopm ent m anager or t eam leader m ust t ake t h e init iat ive t o set up t he code r eview pr ocess and m ust give dev eloper s t he t im e ( and t r aining) t o do it right . Also, code r eview seem s t o be t he fir st casualt y of deadline cr unch. Fur t her , a new PL/ SQL pr oj ect m ight not have t he language exper t ise available on t he t eam t o do com plet e, m eaningful w alkt hr oughs.
Re sou r ce s
1. Handbook of Walkt hr ou ghs, I nspect ions, and Technical Review s, by Daniel
Fr eedm an and Ger ald M. Weinber g ( Dor set Hou se) . Now in it s t hir d edit ion, t his book uses a quest ion- and- answ er for m at t o show you exact ly how t o im plem ent r eview s for all sor t s of pr oduct and soft w ar e dev elopm ent . 2. Ext r em e Pr ogr am m ing Explained , by Kent Beck ( Addison Wesley) . The fir st
book on Ext r em e Pr ogr am m ing offer s m any insight s int o pair pr ogr am m ing. 3. Ext r em e Pr ogr am m ing I nst alled, by Ron Jeffr ies, Ann Ander son, and Ch et
Hendr ickson ( Addison Wesley) . Focuses on how t o im plem ent Ext r em e Pr ogr am m ing in your en vir onm ent .
This book is ch ock- full of r ecom m endat ions, st andar ds, guidelines, and so on. The usual im m ediat e, viscer al r espon se t o all of t hese shoulds is: how can I possibly r em em ber t h em ? And h ow can I m ak e sur e t hat any of ou r developer s act ually follow t hr ough on t heir " shoulds?"
PL/ SQL offer s on e big advant age in t his ar ea: all sour ce code is st or ed in t he dat abase and is m ade available t hr ough dat a dict ionar y view s ( ALL_SOURCE, USER_SOURCE, DBA_SOURCE) . Or acle also m aint ains addit ional infor m at ion about code, such as dependen cies, in ot her view s. You can—and sh ould—fairly easily
validat e at least som e of t he st andar ds t hat y ou set by r unning quer ies against t hese view s.
Her e ar e som e t hings y ou can do w it h t his infor m at ion:
• Set up a w eekly j ob ( via DBMS_ JOB) t o ident ify any pr ogr am s t hat hav e changed, hav e been cr eat ed, or have been r em ov ed in t he past w eek. Publish t his infor m at ion as HTML on an int r anet so dev eloper s can, at any t im e, be aw ar e of t hese changes. This appr oach can im pr ov e r euse w it hin your or ganizat ion, for exam ple.
• Pr ovide quer ies, pr efer ably or ganized w it hin pr ogr am s in a package, t hat dev eloper s can r un ( or , again, can be r un as scheduled, w eekly j obs) t o ch eck t o see how w ell t heir code com plies w it h st andar ds.
Execut ing, as w ell as w r it ing, quer ies against dat a
dict ionar y view s ( par t icular ly t he dependency- r elat ed
view s) can be t im e- consum ing. Be pat ient !
Ex a m ple
Suppose w e have agr eed t hat individual developer s sh ould never call
RAI SE_APPLI CATI ON_ ERROR dir ect ly. I nst ead t hey sh ould call t he r aise pr ocedu r e of t he st andar d er r or - handling package ( see [EXC- 04: Use you r ow n r aise pr ocedur e in place of explicit calls t o RAI SE_APPLI CATI ON_ ERROR.] ) .
Her e is a sim ple quer y t hat ident ifies all t hose pr ogr am unit s ( and lines of code) t hat cont ain t his " off lim it s" built - in:
SELECT name, line || ' - ' || text code FROM ALL_SOURCE
WHERE UPPER (text) LIKE '%RAISE_APPLICATION_ERROR%' ORDER BY name, line;
This answ er s a com m on quest ion: " does m y code hav e X in it ?" Rat her t han
ex ecut ing t hese st andalone qu er ies ov er and ov er again, you w ill find it w or t hw hile t o encapsulat e such a quer y inside a pack aged int er face, such as t his " st andar ds
CREATE OR REPLACE PACKAGE valstd IS
PROCEDURE progwith (str IN VARCHAR2); PROCEDURE pw_rae;
END valstd; /
You can n ow call valst d.pw _r ae t o show all t he " pr ogr am s w it h"
RAI SE_APPLI CATI ON_ ERROR ( as you can easily see fr om t h e valst d package body) . You can also call valst d.pr ogw it h t o sear ch for ot her st r ings. I f, t h er efor e, You've a st andar d t hat dev eloper s should nev er har d- code - 20,000 er r or num ber s, issue t his com m and:
SQL> exec valstd.progwith ('-20')
and view w hat is likely t o be a super set of all such inst ances.
Anot her kind of st andar d t hat m ight be set w it hin an or ganizat ion is t hat applicat ion code sh ould never r efer ence a t able or view dir ect ly but inst ead alw ays go t hr ough an encapsulat ion package ( [SQL- 01: Qualify PL/ SQL var iables w it h t heir scope nam es w hen r efer enced inside SQL st at em ent s.] ) . Her e is a quer y t hat ident ifies all pr ogr am unit s t hat violat e t his r ule:
SELECT owner || '.' || name refs_table, referenced_owner || '.' || referenced_name table_referenced FROM all_dependencies
WHERE owner LIKE UPPER ('&1') AND TYPE IN ('PACKAGE', 'PACKAGE BODY', 'PROCEDURE', 'FUNCTION')
AND referenced_type IN ('TABLE', 'VIEW') ORDER BY owner,
name,
referenced_owner, referenced_name;
Be n e fit s
You don 't have t o r ely solely on " m anual" w alkt hr oughs of code t o validat e com pliance w it h gr oup st andar ds.
Code analysis and code " m ining" ( ext r act ing infor m at ion fr om / about sour ce code) can be aut om at ed and t ight ly int egr at ed int o t he developm ent pr ocess.
Ch a lle n g e s
You need t o design and build t he analysis code and t hen int egr at e t hese ch eck s int o your ongoing dev elopm ent effor t .
1. r eft abs.sql : Qu er y ident ifying dir ect r efer ences t o t ables and view s.
2. valst d.pkg : Sim ple pr ot ot ype package offer ing an int er face t o ident ify t he
pr esence of unw ant ed t ext in sour ce code.
D EV - 0 5 : Ge n e r a t e code w h e n e ve r possible a n d
a ppr opr ia t e .
Life is shor t—and w ay t oo m uch of it is consum ed by t im e spent in fr on t of a
com put er scr een, m oving digit s wit h var ying accur acy ov er t he keyboar d. Seem s t o m e t hat w e sh ould be aggr essive about finding w ays t o build our applicat ions w it h an absolut e m inim um of t im e and effor t w hile st ill pr oducing qualit y goods. A k ey
com ponent of such a st r at egy is code gener at ion: r at her t han w r it e t he code you r self, you let som e ot her piece of soft w ar e w r it e t he code for you.
Code gen er at ion is par t icular ly useful w hen you have defined st andar ds you w ant ev er y one t o follow . You can t r y t o get dev eloper s t o confor m t o t hose st andar ds w it h a " st ick" appr oach: follow t he st andar ds, or else! But a m or e effect ive w ay t o get t he oft en anar chist ic, or at least highly individualist ic, pr ogr am m er t o follow st andar ds is t o m ak e it easier t o follow t han not follow t hose guidelines. See Exam ples for specific dem onst r at ions of t his " car r ot " appr oach.
I n addit ion t o helping t o im plem ent st andar ds, code gener at ion com es in handy w hen you hav e t o w r it e code t hat is r epet it ive in st r uct ur e ( i.e., it can be expr essed
gener ally by a pat t er n) . For exam ple, t he kind of code y ou w r it e t o det er m ine if t her e is at least one r ow in a t able for a given pr im ar y key is t he sam e r egar dless of t he t able ( and pr im ar y key) . Wouldn't it be nice t o be able t o call a pr ocedur e t hat quer ies t he t able st r uct ur e and key fr om t he dat a dict ionar y and gen er at es t he funct ion?
How do you gener at e code? You can pick fr om one of t hese t h r ee opt ions:
• Wr it e y our ow n cu st om quer y or pr ogr am t o m eet specific needs. Exam ples st eps you t h r ough a sim ple dem onst r at ion of how t o go about t his.
• Use a com m er cial t ool t hat focuses on code gen er at ion. Resour ces offer s a list of know n code- gener at ion t ools for PL/ SQL dev eloper s.
• Run r elat ively const r ained, funct ionally specific gener at ion ut ilit ies t hat ot her s have w r it t en ( noncom m er cial, fr eew ar e) . Resour ces offer s a list of gener at ion ut ilit ies available on t he Or acle PL/ SQL Best Pr act ices w eb sit e.
Ex a m ple s
Let 's explor e t hese t h r ee opt ions for gener at ion.
quer y against USER_TABLES w hose out put is, in fact , a ser ies of DROP st at em ent s, and t hen ex ecut e t hat out put as a spooled file in SQL* Plus:
SET PAGESIZE 0 SET FEEDBACK OFF
SELECT 'DROP TABLE ' || table_name || ';' FROM user_tables
WHERE table_name LIKE UPPER ('&1%')
SPOOL drop.cmd /
SPOOL OFF @drop.cmd
Now , let 's m ov e on t o PL/ SQL- based gener at ion. My t eam is about t o st ar t a lar ge-scale developm ent effor t . We w ill need t o per for m r et r ievals of ent ir e r ow s of dat a for m any differ ent t ables, based on t heir var ious ( but single) pr im ar y key colum ns. I w ant t o do t his in a w ay t hat confor m s t o all of our or ganizat ion's st andar ds ( except ion handling wit h logging, use, and encapsulat ion of t he im plicit quer y t hat offer s best per for m ance, et c.) . Rat h er t han w r it e a m em o t o t his effect , I build a pr ocedur e:
CREATE OR REPLACE PROCEDURE genlookup (tab IN VARCHAR2, col IN VARCHAR2) IS
l_ltab VARCHAR2 (100) := LOWER (tab); l_lcol VARCHAR2 (100) := LOWER (col); BEGIN
pl ('CREATE OR REPLACE FUNCTION ' || l_ltab || '_row_for ('); pl (' ' ||
l_lcol || '_in IN ' || l_ltab || '.' || l_lcol || '%TYPE)'); pl (' RETURN ' || l_ltab || '%ROWTYPE');
pl ('IS');
pl (' retval ' || l_ltab || '%ROWTYPE;'); pl ('BEGIN');
pl (' SELECT * INTO retval'); pl (' FROM ' || l_ltab);
pl (' WHERE ' || l_lcol || ' = ' || l_lcol || '_in;'); pl (' RETURN retval;');
pl ('EXCEPTION');
pl (' WHEN NO_DATA_FOUND THEN'); pl (' RETURN NULL;');
pl (' WHEN OTHERS THEN'); pl (' err.log;');
pl ('END ' || l_ltab || '_row_for;'); pl ('/');
END; /
And I can t hen use t his pr ocedur e as follow s:
SQL> exec genlookup ('book', 'isbn') CREATE OR REPLACE FUNCTION book_row_for ( isbn_in IN book.isbn%TYPE)
retval book%ROWTYPE; BEGIN
SELECT * INTO retval FROM book
WHERE isbn = isbn_in; RETURN retval;
EXCEPTION
WHEN NO_DATA_FOUND THEN RETURN NULL;
WHEN OTHERS THEN err.log; END book_row_for; /
You can get m uch m or e sophist icat ed in your gener at ion effor t s; y ou can, for exam ple, look up t he pr im ar y key colum n( s) in t he ALL_CONS_ COLUMNS dat a dict ionar y view , inst ead of having t o specify t he WHERE clause colum n. You hav e t o decide for you r self w her e t o dr aw t he line: do y ou r eally need t hat flexibilit y or does it j ust look like lot s of fu n t o build?
Be n e fit s
You can build your applicat ions fast er ; ut ilit ies can gener at e soft w ar e lot s fast er t han you can t ype it .
You w ill im pr ove t he qualit y of you r applicat ion code: assum ing t hat your gen er at or pr ogr am has been w ell- designed and t est ed, it w ill gener at e bug- fr ee code w it h each use.
As y our under lying dat a st r uct ur es change, y ou can r egen er at e pr ogr am unit s t hat w or k w it h t hose dat a st r uct ur es. Much less t im e is spent upgr ading exist ing code.
Ch a lle n g e s
Building anyt hing but t he m ost cr ude gen er at or s involves a lev el of abst r act ion and com plexit y higher t han t he usual t ask t ackled by m ost developer s.
Re sou r ce s
Com m e r cia l Code - Ge n e r a t ion Tools
1. ht t p: / / w w w .or acle.com / : Or acle Designer fr om Or acle Cor por at ion gener at es code in a var iet y of languages.
2. ht t p: / / w w w .r ev ealnet .com / : RevealNet 's PL/ Gener at or gener at es com pr eh ensive encapsu lat ion packages for t ables and view s.
3. PLVgen: RevealNet 's Act ive PL/ SQL Know ledge Base offer s PLVgen, a package
t hat gener at es funct ions, pr ocedur es, cur sor FOR loops and ot her code elem ent s. Visit t he PL/ SQL Pipeline ar chives as descr ibed in t he Pr eface. 4. Most CASE/ designer t ools offer som e lev el of code gen er at ion. Visit t he w eb
Code - Ge n e r a t ion Ut ilit ie s
1. genlookup.pr o : Gener at es a lookup pr ocedur e t hat r et ur ns a r ow in a t able.
2. m sginfo.pkg : Gen er at es a package w it h definit ions for all applicat ion- specific
except ions.
3. genm ods.pkg : Gener at es st andar d for m at t ed funct ions.
D EV - 0 6 : Se t u p a n d u se for m a l u n it t e st in g
pr oce du r e s.
A unit t est is a t est a developer cr eat es t o ensu r e t hat his or h er " unit ," usually a single pr ogr am , w or ks pr oper ly. A unit t est is ver y differ ent fr om a sy st em or funct ional t est ; t hese lat t er t ypes of t est s ar e or ient ed t o applicat ion feat ur es or ov er all t est ing of t he sy st em . You can't pr oper ly or effect ively per for m a sy st em t est unt il you know t hat t he individual pr ogr am s beh ave as expect ed.
So, of cou r se, you w ould t her efor e expect t hat pr ogr am m er s do lot s of unit t est ing and have a cor r espondingly high level of confidence in t heir pr ogr am s. Ah, if only t hat w er e t he case! The r ealit y is t hat pr ogr am m er s gener ally per for m an inadequat e num ber of inadequat e t est s and figur e t hat if t he user s don't find a bug, t her e is no bug. Why does t his happen? Let m e count t he w ays:
The psychology of success and failur e
We ar e so focused on get t ing our code t o w or k cor r ect ly t hat w e gener ally shy aw ay fr om bad new s, fr om ev en w ant ing t o t ake t he chance of get t ing bad new s. Bet t er t o do som e cu r sor y t est ing, confir m t hat it seem s t o be w or king OK, and t hen w ait for ot her s t o find bugs, if t her e ar e any ( as if t her e w er e any doubt ) .
Deadline pr essur es
Hey, it 's I nt er net t im e! Tim e t o m ar k et det er m ines all. We need ev er yt hing yest er day, so let 's be j ust like Micr osoft and Net scape: r elease pr e- bet a soft w ar e as pr oduct ion and let our user s t est / suffer t hr ough our applicat ions.
Managem ent 's lack of under st anding
I T m anagem ent is not or ious for not r eally under st anding t he soft w ar e
dev elopm ent pr ocess. I f w e ar en't given t he t im e and aut hor it y t o w r it e ( w r it e, t hat is, in t he br oadest sense, including t est ing, docum ent at ion, r efinem ent , et c.) our ow n code pr oper ly, w e w ill alw ays end up w it h buggy j unk t hat no one w ant s t o adm it ow ner ship of.
Over head of set t ing up and r unning t est s
is t hat m or e and m or e of t he t est ing is handed over t o t he QA depar t m ent , if t her e is one. That t r ansfer of r esponsibilit y is, on t he on e hand, posit ive. Pr ofessional qualit y assur ance pr ofessionals can have a t r em endou s im pact on applicat ion qualit y. Yet w e dev eloper s m ust t ak e and ex er cise r esponsibilit y for unit t est ing our ow n code, ot her w ise, t h e t est ing/ QA pr ocess is m uch m or e fr ust r at ing and ext ended.
Ego
I w r ot e it ; t her efor e it w or k s t he w ay I int ended it t o w or k.
The bot t om line is t hat our code alm ost univer sally needs m or e t est ing. And t he best w ay t o do unit t est ing is w it h a for m al pr ocedu r e built ar ound soft w ar e t hat m akes t est ing as easy and as aut om at ed as possible. I can't help w it h deadline pr essu r es, and m y abilit y t o im pr ove your m anager 's under st anding of t he need t o t ake m or e t im e t o t est is lim it ed. I can, on t h e ot her hand, offer y ou a " fr am ew or k"—a set of
pr ocesses and code elem ent s—t hat can gr eat ly im pr ove you r abilit y t o per for m high
qualit y unit t est ing.
I n t he spr ing of 2000, I st udied Ext r em e Pr ogr am m ing
(ht t p: / / w w w .xpr ogr am m ing.com /) and it s associat ed concept s on unit t est ing ( m ost w idely used in it s Java int er pr et at ion, t he open sour ce JUnit ) . I t hen adapt ed t hese ideas t o t he w or ld of PL/ SQL, cr eat ing ut PLSQL, t he unit t est ing fr am ew or k for Or acle PL/ SQL.
By t he t im e t his book is published, t her e m ay be ot her unit t est ing facilit ies available for PL/ SQL. As a st ar t ing point for explor ing t he im plem ent at ion of for m al unit t est s for y our code, h ow ev er , I encour age you t o visit ht t p: / / or acle.or eilly.com / ut plsql.
Ex a m ple
Wit h ut PLSQL, y ou build a t est package for y our st andalone or packaged pr ogr am s. You t hen ask ut PLSQL t o r un t he t est s in your t est package, and display t he r esult s. When y ou use ut PLSQL, you don't hav e t o analyze t he r esult s and det er m ine
w het her y our t est s succeeded or failed; t he ut ilit y aut om at ically figur es t hat out for you.
Suppose, for exam ple, t hat I hav e built a sim ple alt er nat ive t o t h e SUBSTR funct ion called bet w nst r : it r et ur ns t he subst r ing found bet w een t he specified st ar t and end locat ions in t he st r ing. Her e it is:
CREATE OR REPLACE FUNCTION betwnstr ( string_in IN VARCHAR2,
start_in IN INTEGER, end_in IN INTEGER )
RETURN VARCHAR2 IS
BEGIN
start_in,
end_in - start_in + 1 )
);
END betwnstr; /
To t est t his funct ion, I w ant t o pass in a var iet y of input s, as show n in t his t able:
St r i ng St ar t End Expect ed Resul t
abcdefg 3 ( posit ive num ber ) 5 ( bigger posit ive num ber ) cde
abcdefg NULL Any NULL
abcdefg Any NULL NULL
abcdefg 5 2 ( end sm aller t han st ar t NULL abcdefg 3 200 ( end lar ger t han st r ing lengt h) cdefg
Fr om t his t able ( w hich, of cour se, doesn't y et cov er all t he var iat ions needed for a com pr eh ensive t est ) , I build t est cases for each ent r y in m y t est package's unit t est pr ocedur e:
CREATE OR REPLACE PACKAGE BODY ut_betwnstr IS
PROCEDURE ut_betwnstr IS BEGIN
utassert.eq ('Typical valid usage',
betwnstr (string_in => 'abcdefg', start_in => 3, end_in => 5), 'cde');
utassert.isnull ('NULL start', betwnstr (string_in=> 'abcdefg', start_in => NULL,
end_in => 5));
utassert.isnull ('NULL end',
betwnstr (string_in=> 'abcdefg', start_in => 2,
end_in => NULL));
utassert.isnull ('End smaller than start',
betwnstr (string_in => 'abcdefg', start_in => 5, end_in => 2));
utassert.eq ('End larger than string length', betwnstr (string_in=> 'abcdefg',
start_in => 3, end_in => 200), 'cdefg');
END ut_betwnstr; END ut_betwnstr; /
Then I can r un t he t est and view t he r esult s. Her e is a r un t hat ident ifies no er r or s:
SQL> exec utplsql.test ('betwnstr') .
> SSSS U U CCC CCC EEEEEEE SSSS SSSS > S S U U C C C C E S S S S > S U U C C C C E S S
> S U U C C E S S > SSSS U U C C EEEE SSSS SSSS > S U U C C E S S > S U U C C C C E S S > S S U U C C C C E S S S S > SSSS UUU CCC CCC EEEEEEE SSSS SSSS .
SUCCESS: "betwnstr"
And her e is t he out put show n w hen pr oblem s ar ise:
SQL> exec utplsql.test ('betwnstr') .
> FFFFFFF AA III L U U RRRRR EEEEEEE > F A A I L U U R R E
> F A A I L U U R R E > F A A I L U U R R E > FFFF A A I L U U RRRRRR EEEE > F AAAAAAAA I L U U R R E > F A A I L U U R R E > F A A I L U U R R E
> F A A III LLLLLLL UUU R R EEEEEEE .
FAILURE: "betwnstr" .
UT_BETWNSTR: Typical valid usage; expected "cde", got "cd" UT_BETWNSTR: IS NULL: NULL start
UT_BETWNSTR: IS NULL: End smaller than start
Be n e fit s
You develop applicat ions fast er , w it h a higher degr ee of confidence and w it h few er bugs.
I t is m uch easier for ot her dev eloper s t o m aint ain and enhance your code, because aft er t hey m ak e a change, t hey can r un t he full suit e of t est s and confir m t hat t he pr ogr am st ill passes all t est s.
Ch a lle n g e s
The only challenge t o per for m ing com pr ehensive unit t est ing is you! You know y ou have t o t est y our code, and you hav e t o t est it r epeat edly. So t ake t h e t im e t o define your t est s w it hin a t est package, and use a t est ing facilit y t o r un y our t est s for you.
t he per son w ho w r ot e ( or is about t o w r it e) t he code t o be obj ect ive about it . You'll find m or e about t his t opic in [DEV- 07: Get independent t est er s for funct ional sign-off.] .
Re sou r ce s
1. ht t p: / / or acle.or eilly.com / ut plsql : To dow nload ut PLSQL and t o obt ain m or e infor m at ion about it s appr oach t o unit t est ing.
2. ht t p: / / w w w .xpr ogr am m ing.com / : For m or e gener al infor m at ion about
Ext r em e Pr ogr am m ing's appr oach t o and under lying pr inciples for unit t est ing. 3. ht t p: / / w w w .ext r em epr ogr am m ing.or g/ : For a w onder fully accessible, w
eb-based int r oduct ion t o Ex t r em e Pr ogr am m ing.
D EV - 0 7 : Ge t in de pe n de n t t e st e r s for fu n ct ion a l
sign - off.
I ndividual developer s sh ould and m ust be r esponsible for defining and execut ing unit t est s on t he pr ogr am s t hey w r it e ( see [DEV- 06: Set up and use for m al unit t est ing pr ocedur es.] ) . Dev eloper s should not , on t he ot her hand, be r esponsible for over all funct ional t est ing of t heir applicat ions. Ther e ar e sev er al r easons for t his:
• We don't ow n t he r equir em ent s. We don't decide w h en and if t he sy st em w or ks pr oper ly. Our user s or cust om er s have t his r esponsibilit y. They n eed t o be int im at ely connect ed w it h, and dr ive, t he fun ct ional t est s.
• Whenev er w e t est our code, w e follow t he " pat hw ays t o su ccess" w it hout ev er know ing it . I n ot her w or ds, t he m indset w e had w hen w e w r ot e t he code is t he sam e m indset w e h ave w hen t est ing t he code. Ot her people, ot her ey es, need t o r un t he soft w ar e in com plet e ignor ance of t h ose pat hw ay s. I t is no w onder t hat unit t est ing w as so successful and yet int egr at ion t est ing has such pr oblem s.
To im pr ove t he qualit y of code t hat is handed over t o cust om er s for t est ing, your t eam leader or dev elopm ent m anager sh ould:
• Wor k w it h t he cust om er t o define t he set of t est s t hat m ust be r un
successfully befor e an applicat ion is consider ed t o be r eady for pr oduct ion.
• Est ablish a dist inct t est ing gr oup—eit her a devot ed Qualit y Assur ance
or ganizat ion or sim ply a bunch of dev eloper s w ho haven't w r it e any of t he soft w ar e t o be t est ed.
This ext r a layer of t est ing, based on t he cust om er 's ow n r equir em ent s and per for m ed befor e t h e h andoff t o cust om er s for t heir " sign off" t est , w ill gr eat ly im pr ove code qualit y and cust om er confidence in t he dev elopm ent t eam .
I spend sever al days bu ilding a r eally slick applicat ion in Or acle Dev eloper ( or Visual Basic or Java or ...) . I t allow s user s t o m anage dat a in a few differ ent t ables, r equest r epor t s, and so on. I t hen devot e m ost of a day t o r unning t he applicat ion t hr ough it s paces. I click her e, click t her e, ent er good dat a, ent er bad dat a, find a bunch of bugs, fix t hem , and finally hand it over t o m y m ain cust om er , Johanna. I feel confident in m y applicat ion. I can n o longer br eak it .
I m agine how cr u shed I feel ( and I bet y ou can im agine it , because undoubt edly t he sam e t hing has happened t o you) w hen Johann a sit s dow n in fr ont of t he com put er , st ar t s up t h e applicat ion, and in no m or e t han t hr ee clicks of t he m ouse causes an er r or w indow t o pop up on t he scr een. The look she sends m y w ay ( " Why ar e you w ast ing m y t im e?" ) w ill st ay w it h m e for y ear s.
Ther e is no w ay for m e t o convince Johanna t hat I r eally, t r uly did spend hour s t est ing t he applicat ion. Why sh ould she believe such a t hing? She is t hen left t o believe I am a t ot ally incom pet ent t est er .
Be n e fit s
Qualit y of code handed t o user s for t est ing is higher , w hich m eans t he end r esult m ov ed t o pr oduct ion is of cor r espondingly higher qualit y.
Cust om er confidence in t he dev elopm ent or ganizat ion r em ains high. This
confidence—and t he r espect t hat com es w it h it—m akes it easier for developer s t o
negot iat e w it h cust om er s over t he t im e- ver sus- qualit y dilem m a so m an y of us face in soft w ar e developm en t .
Ch a lle n g e s
Many sm all developm en t gr oups can't affor d ( i.e., can't convince m anagem ent t o spend t he m on ey) t o st aff a separ at e QA or ganizat ion. At a m inim um , you m ust m ake sur e t hat cust om er s hav e defined a clear set of t est s. Then dist r ibut e t he funct ional t est ing load t o t he dev eloper s so t hat t hey do not t est t h eir ow n code.
Re sou r ce s
ht t p: / / w w w .w ell.com / ~ vision/ sqa.ht m l : A gat her ing place for r efer en ces r elat ed t o t he t heor y and pr act ice of Soft w ar e Qualit y Assur ance. This sit e is gr ow ing t o include infor m at ion on St andar ds and Developm ent Pr ocedur es, Pr oduct Evaluat ion and Pr ocess Monit or ing, Con figur at ion Managem ent Monit or ing, t he r ole of SQA in t he Pr oduct Developm ent Cycle, and Aut om at ed Test ing Tools.
Ch a pt e r 2 . Codin g St y le a n d Con v e n t ion s
Soft w ar e dev eloper s ar e a v er y pr ivileged bunch. We don 't have t o w or k in
Given t his sit uat ion, I believe w e all have a r esponsibilit y t o w r it e code t hat can be easily under st ood and m aint ained ( and, c'm on, let 's adm it our secr et desir es, adm ir ed) by developer s w ho follow in our foot st eps.
St eve McConnell's
ht t p: / / w w w .const r ux.com /
sit e,
along w it h his book, Code Com plet e ( Micr osoft Pr ess) ,
offer s checklist s on coding st yle, nam ing convent ions
and r ules, and m odule definit ions.
STYL- 0 1 : Adopt a con sist e n t , r e a da ble for m a t
t h a t is e a sy t o m a in t a in .
Your code should have a " signat ur e," a st yle t h at is consist ent ( all your pr ogr am s look t he sam e) , r eadable ( anyon e can pick up y our code and m ake sense of it ) , and m aint ainable ( a m inor change in t he code shouldn't r equir e 15 m inut es of
r efor m at t ing) .
I deally, ev er yon e in you r or ganizat ion w ould adopt a sim ilar st yle, so t h at ev er yon e can easily under st and ever yon e else's code. This can be t r icky, as pr ogr am m er s som et im es t ak e a dogm at ic appr oach t o such issues as size of indent at ion and use of w hit espace.
You hav e t w o opt ions r egar ding coding st yle:
• Find or w r it e a set of gu idelines, and t hen t r y as har d as y ou can t o follow ( and get you r gr oup t o follow ) t hose guidelines. See Resour ces for a sam ple docum ent .
• Use a t ool t o aut om at ically for m at y our code for y ou. Th e dom inant code for m at t er for PL/ SQL is cur r ent ly PL/ For m at t er fr om Rev ealNet ( see Resour ces) . This pr oduct is not only available st andalone, but is also
int egr at ed int o m any popular int egr at ed developm ent envir onm ent s ( I DEs) .
I st r ongly r ecom m end t hat you use PL/ For m at t er or som e ot her " pr et t y pr int " t ool. I t is quit e liber at ing t o w r it e code w it hout any con cer n w hat soev er for how it looks: I focus com plet ely on t he logical flow and t hen pr ess a but t on a m om ent lat er t o t ur n it int o r eadable, at t r act ive code.
Ex a m ple
Her e is a package specificat ion t hat has som e clear pr oblem s: all upper case, no indent at ion, no w hit espace:
CREATE OR REPLACE PACKAGE OVERDUE_PKG IS PROCEDURE SET_DAILY_FINE (FINE_IN IN NUMBER); FUNCTION DAILY_FINE RETURN NUMBER;
FUNCTION DAYS_OVERDUE
FUNCTION FINE (ISBN_IN IN BOOK.ISBN%TYPE) RETURN INTEGER;
END OVERDUE_PKG; /
I r an it t hr ough PL/ For m at t er and cam e up w it h t his:
CREATE OR REPLACE PACKAGE overdue_pkg IS
PROCEDURE set_daily_fine (fine_in IN NUMBER);
FUNCTION daily_fine RETURN NUMBER;
FUNCTION days_overdue (
isbn_in IN book.isbn%TYPE) RETURN INTEGER;
FUNCTION fine (isbn_in IN book.isbn%TYPE) RETURN INTEGER;
END overdue_pkg; /
Which of t hese specificat ions w ould you pr efer t o r ead and m aint ain?
D
é
j
à
v u Code
I w r ot e and enact ed a PL/ SQL Coding St andar d at a for m er
client 's. Aft er t w o year s t her e as a consult ant , I m oved on t o
ot her assignm ent s. A year lat er , I r et ur ned t o t he pr evious
client . I w as t asked w it h m aint aining a par t icular package.
Looking at it , I got a st r ange sense of d
é
j
à
vu; t he code looked
like som et hing I w ould have w r it t en, but I could not r em em ber
having w r it t en it . Since it w as laid out accor ding t o t he
pr escr ibed st andar d, it w as easy t o locat e sect ions and m ake
t he needed changes. I checked t he docum ent header t o
discover w ho w r ot e it , w hich t ur ned out t o be anot her fellow
t her e. I asked him about it , and he said t hat he sim ply follow ed
t he st andar d. He liked how so m any packages w er e all
consist ent ly or ganized, m aking it a br eeze t o r ead and m aint ain
t hem .
—
Dan Clam age
Be n e fit s
Ch a lle n g e s
I t 's har d t o enfor ce a coding st yle am ong pr ogr am m er s, w ho can be fier cely liber t ar ian.
I t t ak es t im e t o pr oduce a com pr ehensive st yle docum ent for PL/ SQL.
Re sou r ce s
1. Recom m endat ions for coding st yle fr om Chapt er 3 of Or acle PL/ SQL
Pr ogr am m ing, available online at ht t p: / / w w w .or eilly.com / cat alog/ or aclep2/. 2. ht t p: / / w w w .r ev ealnet .com / pr oduct s/ for m at t er / for m at t er .ht m: For infor m at ion
about PL/ For m at t er .
STYL- 0 2 : Adopt logica l, con sist e n t n a m in g
con v e n t ion s for m odu le s a n d da t a st r u ct u r e s.
Adopt and pr om ot e st an dar d w ay s t o define nam es of pr ogr am elem en t s. Choose a level of " for m alit y" of n am ing convent ions based on y our n eeds. I f, for exam ple, y ou have a t eam of t w o dev eloper s w or king on a sm all code base, y ou can pr obably get aw ay w it h nam ing conv ent ions t hat don't go far bey ond " use m eaningful nam es." I f you ar e building a m assive applicat ion involving dozens of developer s, y ou pr obably need t o define m or e com pr eh ensive r ules.
Her e ar e som e gener al r ecom m endat ions for convent ions:
• I dent ify t he scope of a var iable in it s nam e. A global var iable can be pr efaced w it h g_ , for exam ple.
• Use a pr efix or suffix t o ident ify t he t ypes of st r uct ur es being defined.
Consider , for exam ple, declar at ions of TYPEs: of collect ions, obj ect s, r ecor ds, r ef cu r sor s, et c. A st andar d appr oach t o declar ing such a st r uct ur e is
<name>_t. Types ar e qu it e differ ent fr om var iables; you sh ould be able t o ident ify t he differ ence w it h a glance.
• Use t h e sam e case conv ent ion for u ser - defined t ypes as t he st andar d
dat at ypes in or der t o help t hem st and out . Dat at ypes ( built - in or user - defined) should follow a differ ent casing r ule fr om var iables ( such as all upper case for t ypes, low er case for var iables) .
• Or ganize like it em s t oget her . For exam ple, declar e r ecor d var iables t oget her in t he sam e sect ion. Declar e all const ant s t oget her in anot her sect ion, separ at ed fr om t he pr ev ious sect ion by w hit espace.
I t isn't possible t o pr ovide a com pr eh ensive list of nam ing conv ent ions in t his book. The par t icular conv ent ions you choose, fur t her m or e, ar en't near ly as im por t ant as t he fact t hat you set som e st andar d for nam ing conv ent ions. See Resour ces for dow nloadable st yle guides.
Ex a m ple
Her e is a block of code t hat r eflect s no st andar dizat ion of nam ing convent ions:
CREATE OR REPLACE PROCEDURE showborrowedbooks ( date_borrowed IN DATE)
IS
date_returned DATE := SYSDATE; mindaysborrowed INTEGER := 10;
TYPE book_borrowed IS RECORD ( dateborrowed DATE,
daysborrowed INTEGER,
isbn book.isbn%TYPE, datedue DATE);
borrowedbook book_borrowed;
CURSOR allborrowed IS
SELECT * FROM borrowed_book WHERE returned = 'N'; BEGIN
IF dateborrowed < datereturned THEN
FOR rec IN allborrowed LOOP
borrowedbook:= rec;
IF borrowedbook.daysborrowed > mindaysborrowed THEN
pl (borrowedbook.isbn); END IF;
END LOOP; END IF;
END showborrowedbooks;
Her e's t hat sam e block of code based on st andar ds. I use under scor es in nam es; suffixes on par am et er s, r ecor ds, and cur sor s; pr efixes t o show scope (l_ for local) and t ype (c_ for const ant ) . Com par e car efully t he follow ing it em nam es w it h t hose in t he pr evious exam ple:
CREATE OR REPLACE PROCEDURE show_borrowed_books ( date_borrowed_in IN DATE)
IS
l_min_days_borrowed INTEGER := 10;
TYPE book_borrowed_rt IS RECORD ( date_borrowed DATE,
days_borrowed INTEGER,
isbn book.isbn%TYPE, date_due DATE);
borrowed_book_rec book_borrowed_rt;
CURSOR all_borrowed_cur IS SELECT * FROM borrowed_book WHERE returned = 'N'; BEGIN
IF date_borrowed_in < c_date_returned THEN
FOR book_rec IN all_borrowed_cur LOOP
borrowed_book_rec := book_rec;
IF borrowed_book_rec.days_borrowed > l_min_days_borrowed
THEN
pl (borrowed_book_rec.isbn); END IF;
END LOOP; END IF;
END show_borrowed_books;
Now it 's possible t o look at any individual par t of show _bor r ow ed_books and m ake sense of t h e differ ent kin