Explicit Cursor Oracle new
-
Upload
emiliavardarova -
Category
Documents
-
view
249 -
download
0
Transcript of Explicit Cursor Oracle new
-
8/13/2019 Explicit Cursor Oracle new
1/57
6.2 Cursors in PL/SQL
When you execute a SQL statement from PL/SQL, the Oracle RDBMS assigns apriate !or" area for that statement# $his !or" area contains information a%out theSQL statement an& the set of &ata returne& or affecte& %y that statement# $he PL/SQL
cursor is a mechanism %y !hich you can name that !or" area an& manipulate theinformation !ithin it#
'n its simplest form, you can thin" of a cursor as a pointer into a ta%le in the &ata%ase#(or example, the follo!ing cursor &eclaration associates the entire employee ta%le!ith the cursor name& employee)cur*
+RSOR employee)cur 'S S-L-+$ . (ROM employee
Once ' hae &eclare& the cursor, ' can open it*
OP-0 employee)cur
1n& then ' can fetch ro!s from it*
(-$+2 employee)cur '0$O employee)rec
an&, finally, ' can close the cursor*
+LOS- employee)cur
'n this case, each recor& fetche& from this cursor represents an entire recor& in the
employee ta%le# 3ou can, ho!eer, associate any ali& S-L-+$ statement !ith acursor# 'n the next example ' hae a 4oin of three ta%les in my cursor &eclaration*
D-+L1R- +RSOR 4o"e)fee&%ac")cur 'S S-L-+$ 5#name, R#laugh)olume, +#name (ROM 4o"e 5, response R, come&ian + W2-R- 5#4o"e)i& 6 R#4o"e)i& 10D 5#4o"er)i& 6 +#4o"er)i&B-7'0 ###-0D
2ere, the cursor &oes not act as a pointer into any actual ta%le in the &ata%ase# 'nstea&,the cursor is a pointer into the irtual ta%le represente& %y the S-L-+$ statement8S-L-+$ is calle& a irtual ta%le %ecause the &ata it pro&uces has the same structureas a ta%le 99 ro!s an& columns 99 %ut it exists only for the &uration of the execution ofthe SQL statement:# 'f the triple94oin returns ;< ro!s, each ro! containing the threecolumns in the prece&ing example, then the cursor functions as a pointer into those ;#;#= $ypes of +ursors
3ou hae lots of options in PL/SQL for executing SQL, an& all of them occur as sometype of cursor# 7enerally, there are t!o types of SQL that you can execute in PL/SQL*static an& &ynamic# SQL is static if the content of the SQL statement is &etermine& atcompile time# 1 SQL statement is &ynamic if it is constructe& at runtime an& then
executeDynamic SQL is ma&e possi%le in PL/SQL only through the use of the DBMS)SQL
%uilt9in pac"age 8see 1ppen&ix +, Built9'n Pac"ages:# 1ll other forms of SQL execute&insi&e a PL/SQL program represent static SQL these forms of cursors are the focus ofthe remain&er of this chapter#
-en !ithin the category of static SQL, !e hae further &ifferentiation# With thea&ent of PL/SQL Release ;#?, you can choose %et!een t!o &istinct types of cursoro%4ects*
Static cursor o%4ects
$hese are the really static cursors of PL/SQL# $he SQL is &etermine& at compiletime, an& the cursor al!ays refers to one SQL statement, !hich is "no!n atcompile time# $he examples sho!n earlier in this chapter are static cursors#
nless other!ise note&, any reference to @static cursor@ refers to this su%9category of static 8as oppose& to &ynamic: cursors#
+ursor aria%les
3ou can &eclare a aria%le !hich references a cursor o%4ect in the &ata%ase# 3ouraria%le may refer to &ifferent SQL statements at &ifferent times 8%ut that SQL is&efine& at compile time, not run time:#
$he cursor aria%le is one of the ne!est enhancements to PL/SQL an& !ill %eunfamiliar to most programmers# +ursor aria%les act as references to cursor o%4ects#1s a true aria%le, a cursor aria%le can change its alue as your program executes#$he aria%le can refer to &ifferent cursor o%4ects 8Aueries: at &ifferent times# 3ou canalso pass a cursor aria%le as a parameter to a proce&ure or function# +ursor aria%lesare &iscusse& later in this chapter#
Static PL/SQL cursors hae %een aaila%le since PL/SQL ersion =# $he static ersionof cursors @har&co&es@ a lin" %et!een the cursor name an& a S-L-+$ statement# $hestatic cursor itself comes in t!o flaors* implicit an& explicit#
PL/SQL &eclares an& manages an implicit cursor eery time you execute a SQL DMLstatement, such as an '0S-R$ or a S-L-+$ that returns a single ro!#
3ou, the programmer, &efine your o!n explicit cursors in your co&e# 3ou must use anexplicit cursor !hen you nee& to retriee more than one ro! of &ata at a time througha S-L-+$ statement# 3ou can then use the cursor to fetch these ro!s one at a time#$he set of ro!s returne& %y the Auery associate& !ith an explicit cursor is calle&
the actie set or result set of the cursor# $he ro! to !hich the explicit cursor points iscalle& the current ro! of the result set#
;
-
8/13/2019 Explicit Cursor Oracle new
3/57
$he %ul" of this chapter is &eote& to the management of static, explicit cursors# 1llinformation a%out cursor aria%les is localiCe& in Section >#=;, @+ursor aria%les@# 1nyreferences to PL/SQL cursors an& cursor characteristics outsi&e of that section !ill
pertain to static cursors#
>#;#; +ursor OperationsRegar&less of the type of cursor, PL/SQL performs the same operations to execute aSQL statement from !ithin your program*
P1RS-
$he first step in processing an SQL statement is to parse it to ma"e sure it is ali&an& to &etermine the execution plan 8using either the rule9%ase& or cost9%ase&optimiCer:#
B'0D
When you %in&, you associate alues from your program 8host aria%les: !ithplacehol&ers insi&e your SQL statement# (or static SQL, the SQL engine itselfperforms these %in&s# When you use &ynamic SQL, you explicitly reAuest a%in&ing of aria%le alues#
OP-0
When you open a cursor, the %in& aria%les are use& to &etermine the result setfor the SQL statement# $he pointer to the actie or current ro! is set to the first
ro!# Sometimes you !ill not explicitly open a cursor instea& the PL/SQL engine!ill perform this operation for you 8as !ith implicit cursors:#
--+$-
'n the execute phase, the statement is run !ithin the SQL engine#
(-$+2
'f you are performing a Auery, the (-$+2 comman& retriees the next ro! fromthe cursorEs result set# -ach time you fetch, PL/SQL moes the pointer for!ar& in
the result set# When !or"ing !ith explicit cursors, remem%er that if there are nomore ro!s to retriee, then (-$+2 &oes nothing 8it &oes not raise an error:#
+LOS-
$he +LOS- statement closes the cursor an& releases all memory use& %y thecursor# Once close&, the cursor no longer has a result set# Sometimes you !ill notexplicitly close a cursor instea& the PL/SQL engine !ill perform this operationfor you 8as !ith implicit cursors:#
(igure >#=sho!s ho! some of these &ifferent operations are use& to fetch information
from the &ata%ase into your PL/SQL program#
?
-
8/13/2019 Explicit Cursor Oracle new
4/57
(igure >#=* sing cursor operations to fetch &ata%ase information into your program
6.3 Implicit and Explicit CursorsLetEs ta"e a closer loo" at implicit an& explicit cursors an& the !ays you can put themin your programs#
>#?#= 'mplicit +ursors
PL/SQL issues an implicit cursor !heneer you execute a SQL statement &irectly inyour co&e, as long as that co&e &oes not employ an explicit cursor# 't is calle& an@implicit@ cursor %ecause you, the &eeloper, &o not explicitly &eclare a cursor for theSQL statement#
'f you use an implicit cursor, Oracle performs the open, fetches, an& close for youautomatically these actions are outsi&e of your programmatic control# 3ou can,ho!eer, o%tain information a%out the most recently execute& SQL statement %yexamining the alues in the implicit SQL cursor attri%utes, as explaine& later in thischapter#
PL/SQL employs an implicit cursor for each PD1$-, D-L-$-, or '0S-R$statement you execute in a program# 3ou cannot, in other !or&s, execute thesestatements !ithin an explicit cursor, een if you !ant to# 3ou hae a choice %et!eenusing an implicit or explicit cursor only !hen you execute a single9ro! S-L-+$
statement 8a S-L-+$ that returns only one ro!:#'n the follo!ing PD1$- statement, !hich gies eeryone in the company a =
-
8/13/2019 Explicit Cursor Oracle new
5/57
cursor# $he implicit cursor has the follo!ing &ra!%ac"s*
't is less efficient than an explicit cursor 8in PL/SQL Release ;#; an& earlier:
't is more ulnera%le to &ata errors
't gies you less programmatic control
$he follo!ing sections explore each of these limitations to the implicit cursor#
>#?#;#= 'nefficiencies of implicit cursors
1n explicit cursor is, at least theoretically, more efficient than an implicit cursor 8inPL/SQL Release ;#; an& earlier:# 1n implicit cursor executes as a SQL statement an&OracleEs SQL is 10S'9stan&ar 10S' &ictates that a single9ro! Auery must not onlyfetch the first recor&, %ut must also perform a secon& fetch to &etermine if too manyro!s !ill %e returne& %y that Auery 8such a situation !ill R1'S- the
$OO)M103)ROWS PL/SQL exception:# $hus, an implicit Auery al!ays performs aminimum of t!o fetches, !hile an explicit cursor only nee&s to perform a single fetch#
$his a&&itional fetch is usually not noticea%le, an& you shoul&nEt %e neurotic a%outusing an implicit cursor for a single9ro! Auery 8it ta"es less co&ing, so the temptationis al!ays there:# Loo" out for in&iscriminate use of the implicit cursor in the parts ofyour application !here that cursor !ill %e execute& repeate&ly# 1 goo& example isthe Post9Query trigger in the Oracle (orms#
Post9Query fires once for each recor& retriee& %y the Auery 8create& from the %aseta%le %loc" an& the criteria entere& %y the user:# 'f a Auery retriees ten ro!s, then an
a&&itional ten fetches are nee&e& !ith an implicit Auery# 'f you hae ;H users on yoursystem all performing a similar Auery, your serer must process ;H< a&&itional8unnecessary: fetches against the &ata%ase# So, !hile it might %e easier to !rite animplicit Auery, there are some places in your co&e !here you !ill !ant to ma"e thatextra effort an& go !ith the explicit cursor#
0O$-* 'n PL/SQL Release ;#? an& a%oe, the implicit cursor has %eenoptimiCe& so that it may, in isolation, run faster than the correspon&ingexplicit cursor# 7enerally, the &ifferences %et!een these t!o approachesfrom a performance stan&point are negligi%le# On the other han&, if you use
an explicit cursor, you are more li"ely 8or at least a%le: to reuse that cursor,!hich increases the chance that it !ill %e pre9parse& in share& memory !hennee&e& 99 there%y improing the performance of your application as a !hole#
>#?#;#; ulnera%ility to &ata errors
'f an implicit S-L-+$ statement returns more than one ro!, it raises the$OO)M103)ROWS exception# When this happens, execution in the current %loc"terminates an& control is passe& to the exception section# nless you &eli%erately planto han&le this scenario, use of the implicit cursor is a &eclaration of faith# 3ou are
saying, @' trust that Auery to al!ays return a single ro!I@'t may !ell %e that to&ay, !ith the current &ata, the Auery !ill only return a single ro!#
H
-
8/13/2019 Explicit Cursor Oracle new
6/57
'f the nature of the &ata eer changes, ho!eer, you may fin& that the S-L-+$statement !hich formerly i&entifie& a single ro! no! returns seeral# 3our program!ill raise an exception# Perhaps this is !hat you !ill !ant# On the other han&, perhapsthe presence of a&&itional recor&s is inconseAuential an& shoul& %e ignore
With the implicit Auery, you cannot easily han&le these &ifferent possi%ilities# With an
explicit Auery, your program !ill %e protecte& against changes in &ata an& !illcontinue to fetch ro!s !ithout raising exceptions#
>#?#;#? Diminishe& programmatic control
$he implicit cursor ersion of a S-L-+$ statement is a %lac" %ox# 3ou pass the SQLstatement to the SQL layer in the &ata%ase an& it returns 8you hope: a single ro!# 3oucanEt get insi&e the separate operations of the cursor, such as the open an& close stages#3ou canEt examine the attri%utes of the cursor 99 to see !hether a ro! !as foun&, forexample, or if the cursor has alrea&y %een opene 3ou canEt easily apply tra&itional
programming control constructs, such as an '( statement, to your &ata access#Sometimes you &onEt nee& this leel of control# Sometimes you 4ust thin" you &onEtnee& this leel of control# ' hae foun& that if ' am going to %uil& programs in PL/SQL,' !ant as much control as ' can possi%ly get#
1l!ays se -xplicit +ursorsI
My rule of thum% is al!ays to use an explicit cursor for all S-L-+$ statements in myapplications, een if an implicit cursor might run a little %it faster an& een if, %y
co&ing an explicit cursor, ' hae to !rite more co&e 8&eclaration, open, fetch, close:#By setting an& follo!ing this clear9cut rule, ' gie myself one less thing to thin" a%out#' &o not hae to &etermine if a particular S-L-+$ statement !ill return only one ro!an& therefore %e a can&i&ate for an implicit cursor# ' &o not hae to !on&er a%out thecon&itions un&er !hich a single9ro! Auery might su&&enly return more than one ro!,thus reAuiring a $OO)M103)ROWS exception han&ler# ' am guarantee& to getastly improe& programmatic control oer that &ata access an& more finely9tune&exception han&ling for the cursor#
>#?#? -xplicit +ursors1n explicit cursor is a S-L-+$ statement that is explicitly &efine& in the &eclarationsection of your co&e an&, in the process, assigne& a name# $here is no such thing as anexplicit cursor for PD1$-, D-L-$-, an& '0S-R$ statements#
With explicit cursors, you hae complete control oer ho! to access information in the&ata%ase# 3ou &eci&e !hen to OP-0 the cursor, !hen to (-$+2 recor&s from thecursor 8an& therefore from the ta%le or ta%les in the S-L-+$ statement of the cursor:ho! many recor&s to fetch, an& !hen to +LOS- the cursor# 'nformation a%out thecurrent state of your cursor is aaila%le through examination of the cursor attri%utes#
$his granularity of control ma"es the explicit cursor an inalua%le tool for your&eelopment effort#
>
-
8/13/2019 Explicit Cursor Oracle new
7/57
LetEs loo" at an example# $he follo!ing anonymous %loc" loo"s up the employee type&escription for an employee type co&e*
= D-+L1R-; /. -xplicit &eclaration of a cursor ./? +RSOR emptyp)cur 'S
G S-L-+$ emptyp#type)&escH (ROM employees emp, employee)type emptyp> W2-R- emp#type)co&e 6 emptyp#type)co&eJ B-7'0K /. +hec" to see if cursor is alrea&y open# 'f not, open it# ./ '( 0O$ emptyp)curF'SOP-0=< $2-0== OP-0 emptyp)cur=; -0D '(=?=G /. (etch ro! from cursor &irectly into an Oracle (orms item ./=H (-$+2 emptyp)cur '0$O *emp#type)&esc=>=J /. +lose the cursor ./=K +LOS- emptyp)cur= -0D
$his PL/SQL %loc" performs the follo!ing cursor actions*
1ctionLine8s:Declare the cursor?Open the cursor 8if not alrea&y open:, ==(etch one or more ro!s
from the cursor=H+lose the cursor=K$he next fe! sections examine each of these steps inmore &etail# (or the remain&er of this chapter, unless note& other!ise, the !or&@cursor@ refers to the explicit cursor#
6.4 Declaring Cursors$o use an explicit cursor, you must first &eclare it in the &eclaration section of yourPL/SQL %loc" or in a pac"age, as sho!n here*
+RSOR cursor)name 8 parameter , parameter ###N : N R-$R0 return)specification N 'S S-L-+$)statement
!here cursor)name is the name of the cursor, return)specification is an optionalR-$R0 clause for the cursor, an& S-L-+$)statement is any ali& SQL S-L-+$statement# 3ou can also pass arguments into a cursor through the optional parameterlist &escri%e& in Section >#=
-
8/13/2019 Explicit Cursor Oracle new
8/57
1 cursor !ithout parameters# $he result set of this cursor is the set of company
'D num%ers for each recor& in the ta%le*
+RSOR company)cur 'S
S-L-+$ company)i& (ROM company
1 cursor !ith parameters# $he result set of this cursor is the name of thecompany !hich matches the company 'D passe& to the cursor ia the parameter*
+RSOR name)cur 8company)i&)in '0 0MB-R:
'S
S-L-+$ name (ROM company W2-R- company)i& 6 company)i&)in
1 cursor !ith a R-$R0 clause# $he result set of this cursor is all columns
8same structure as the un&erlying ta%le: from all employee recor&s in &epartment=
-
8/13/2019 Explicit Cursor Oracle new
9/57
reference at least one ta%le from the &ata%ase an& &etermine from that 8an& from theW2-R- clause: !hich ro!s !ill %e returne& in the actie set# $his &oes not mean,ho!eer, that a cursorEs S-L-+$ may only return &ata%ase information# $he list ofexpressions that appears after the S-L-+$ "ey!or& an& %efore the (ROM "ey!or& iscalle& the select list#
'n natie SQL, this select list may contain %oth columns an& expressions 8SQLfunctions on those columns, constants, etc#:# 'n PL/SQL, the select list of a S-L-+$may contain PL/SQL aria%les, expressions, an& een functions 8PL/SQL Release ;#=an& a%oe:#
'n the follo!ing cursor, the S-L-+$ statement retriees ro!s %ase& on the employeeta%le, %ut the information returne& in the select list contains a com%ination of ta%lecolumns, a PL/SQL aria%le, an& a %in& aria%le from the host enironment 8such asan Oracle (orms item:*
D-+L1R- /. 1 local PL/SQL aria%le ./ pro4ecte&)%onus 0MB-R *6 =
-
8/13/2019 Explicit Cursor Oracle new
10/57
aria%le of the same name to achiee its en&s# 1lthough this co&e !ill compile !ithouterror, it !ill not pro&uce the &esire& result*
PRO+-DR- improe)QOL'S /. Local aria%le !ith same name as column* ./
salary 0MB-R *6 =
-
8/13/2019 Explicit Cursor Oracle new
11/57
&etails#
With ersion ; of PL/SQL you can accomplish the same o%4ectie !ith cursors %yusing the cursor R-$R0 clause# $he R-$R0 clause allo!s you to create aspecification for a cursor !hich is separate from its %o&y 8the S-L-+$ statement:#3ou may then place cursors in pac"ages an& hi&e the implementation &etails from
&eelopers#+onsi&er the follo!ing cursor &eclaration !ith R-$R0 clause*
+RSOR caller)cur 8i&)in '0 0MB-R: R-$R0 callerF'S S-L-+$ . (ROM caller W2-R- caller)i& 6 i&)in
$he specification of the caller)cur cursor is*
+RSOR caller)cur 8i&)in '0 0MB-R: R-$R0 callerF
!hile the %o&y of the caller)cur cursor is*
S-L-+$ . (ROM caller W2-R- caller)i& 6 i&)in
-erything up to %ut not inclu&ing the 'S "ey!or& is the specification, !hileeerything follo!ing the 'S "ey!or& is the %o&y#
3ou can inclu&e a R-$R0 clause for any cursor you !rite in PL/SQL ersion ;, %utit is reAuire& only for cursors !hich are containe& in a pac"age specification#
$he R-$R0 clause may %e ma&e up of any of the follo!ing &atatype structures*
1 recor& &efine& from a &ata%ase ta%le, using the F attri%ute
1 recor& &efine& from a programmer9&efine& recor&
2ere is an example of a cursor &efine& in a pac"age# (irst, the pac"age specificationproi&es the name of the cursor an& the R-$R0 &atatype 8an entire ro! from thecompany ta%le:*
P1+17- company'S +RSOR company)cur 8i&)in 0MB-R: R-$R0 companyF-0D company
$hen the follo!ing pac"age %o&y repeats the cursor specification an& a&&s the SQLstatement*
P1+17- BOD3 company'S +RSOR company)cur 8i&)in 0MB-R: R-$R0 companyF 'S S-L-+$ . (ROM company W2-R- company)i& 6 i&)in
-0D company==
-
8/13/2019 Explicit Cursor Oracle new
12/57
$he num%er of expressions in the cursorEs select list must match the num%er ofcolumns in the recor& i&entifie& %y ta%le)nameF or PLSQL)recor&F# $he &atatypesof the elements must also %e compati%le# 'f the secon& element in the select list is type
0MB-R, then the secon& column in the R-$R0 recor& cannot %e type1R+21R; or BOOL-10#
Why place cursors in a pac"ageT (or the same reasons you !oul& place a proce&ure ora function in a pac"age* a pac"age is a collection of logically relate& o%4ects# Bygrouping the co&e into a pac"age you ma"e it easier for a &eeloper to i&entify an& usethe co&e 8see+hapter =>, Pac"ages, for more &etails:# Pac"age& cursors are essentially
%lac" %oxes# $his is a&antageous to &eelopers %ecause they neer hae to co&e oreen see the S-L-+$ statement# $hey only nee& to "no! !hat recor&s the cursorreturns, in !hat or&er it returns them, an& !hich columns are in the column list#
When cursor information is limite& on this "in& of @nee& to "no!@ %asis, it protects&eelopers an& the oerall application from change# Suppose that a year from no! the
W2-R- clause of a Auery has to change# 'f a pac"age& cursor is not use&, then eachprogram that has a har&co&e& or local cursor !ill hae to %e mo&ifie& to meet the ne!specification# 'f, on the other han&, all &eelopers simply access the same cursor, thenchanges !ill only nee& to %e ma&e to that pac"age& &eclaration of the cursor# $he
programs can then %e recompile& to automatically support this change#
6.# "pening Cursors
$he first step in using a cursor is to &efine it in the &eclaration section# $he next stepyou must perform %efore you try to extract or fetch recor&s from a cursor is to openthat cursor#
$he syntax for the OP-0 statement is simplicity itself*
OP-0 cursor)nameU 8 argument , argument ###N : N
!here cursor)nameU is the name of the cursor you &eclare& an& the arguments arethe alues to %e passe& if the cursor !as &eclare& !ith a parameter list#
When you open a cursor, PL/SQL executes the Auery for that cursor# 't also i&entifiesthe actie set of &ata 99 that is, the ro!s from all inole& ta%les that meet the criteriain the W2-R- clause an& 4oin con&itions# $he OP-0 &oes not itself actually retrieeany of these ro!s 99 that action is performe& %y the (-$+2 statement#
Regar&less of !hen you perform the first fetch, ho!eer, the rea& consistency mo&elin the Oracle RDBMS guarantees that all fetches !ill reflect the &ata as it existe&!hen the cursor !as opene 'n other !or&s, from the moment you open your cursoruntil the moment that cursor is close&, all &ata fetche& through the cursor !ill ignoreany inserts, up&ates, an& &eletes performe& after the cursor !as opene
(urthermore, if the S-L-+$ statement in your cursor uses a (OR PD1$- clause,then, !hen the cursor is opene&, all the ro!s i&entifie& %y the Auery are loc"e 8$his
=;
-
8/13/2019 Explicit Cursor Oracle new
13/57
topic is coere& in Section >#==, @S-L-+$ (OR PD1$- in +ursors@later in this chapter#:
3ou shoul& open a cursor only if it has %een close& or !as neer opene 'f you try toopen a cursor that is alrea&y open you !ill get the follo!ing error*
OR19H==* PL/SQL* cursor alrea&y open
3ou can %e sure of a cursorEs status %y chec"ing the F'SOP-0 cursor attri%ute %eforeyou try to open the cursor*
'( 0O$ company)curF'SOP-0$2-0 OP-0 company)cur-0D '(
Section >#, @+ursor 1ttri%utes@later in the chapter, explains the &ifferent cursor attri%utesan& ho! to ma"e %est use of them in your programs#
6.6 $etc%ing &'()*'+,- 0rom Cursors
1 S-L-+$ statement creates a irtual ta%le in SQL* its return set is a series of ro!s&etermine& %y the W2-R- clause 8or lac" thereof: an& !ith columns &etermine& %ythe column list of the S-L-+$# So a cursor represents that irtual ta%le !ithin your
PL/SQL program# 'n almost eery situation, the point of &eclaring an& opening acursor is to return, or fetch, the ro!s of &ata from the cursor an& then manipulate theinformation retriee PL/SQL proi&es a (-$+2 statement for this action#
$he general syntax for a (-$+2 is sho!n %elo!*
(-$+2 cursor)nameU '0$O recor&)or)aria%le)listU
!here cursor)nameU is the name of the cursor from !hich the recor& is fetche& an&recor&)or)aria%le)listU is the PL/SQL &ata structure into !hich the next ro! of theactie set of recor&s is copie 3ou can fetch into a recor& structure 8&eclare& !ith theF attri%ute or $3P- &eclaration statement: or you can fetch into a list of one or morearia%les 8PL/SQL aria%les or application9specific %in& aria%les such as Oracle(orms items:#
$he follo!ing examples illustrate the ariety of possi%le fetches*
(etch into a PL/SQL recor&*
(-$+2 company)cursor '0$O company)rec
(etch into a aria%le*
(-$+2 ne!)%alance)cursor '0$O ne!)%alance)&ollars
=?
-
8/13/2019 Explicit Cursor Oracle new
14/57
(etch into the ro! of a PL/SQL ta%le ro!, a aria%le, an& an Oracle (orms
%in& aria%le*
(-$+2 emp)name)cur '0$O emp)name 8=:, hire&ate,
*&ept#min)salary
>#>#= Matching +olumn List !ith '0$O +lause
When you fetch into a list of aria%les, the num%er of aria%les must match the num%erof expressions in the S-L-+$ list of the cursor# When you fetch into a recor&, thenum%er of columns in the recor& must match the num%er of expressions in theS-L-+$ list of the cursor#
'f you &o not match up the column list in the cursorEs Auery !ith the '0$O elements inthe (-$+2, you !ill receie the follo!ing compile error*
PLS9
-
8/13/2019 Explicit Cursor Oracle new
15/57
Programmer9&efine& recor& type !hich contains only t!o of the three cursor
columns, follo!ing %y &eclaration of recor&*
$3P- partial)green)eggs)rectype 'S R-+ORD
8hamV &r)seuss#ham)AuantityF$3P- sai&noV &r)seuss#times)refuse&F$3P-:
partial)rec partial)green)eggs)rectype
1 set of local PL/SQL aria%les*
ham)amount 0MB-R
refuse&)count '0$-7-R
lousy)excuse 1R+21R;8>
-
8/13/2019 Explicit Cursor Oracle new
16/57
the actie set# 1t this point the F0O$(O0D cursor attri%ute for the cursor is set to$R-#
1ctually, you can een (-$+2 past the last recor&I 'n this case, PL/SQL !ill not raiseany exceptions# 't 4ust !onEt &o anything for you# Because there is nothing left to fetch,though, it also !ill not mo&ify the alues in the '0$O list of the (-$+2# $he fetch
!ill not set those alues to 0LL#3ou shoul&, therefore, neer test the alues of '0$O aria%les to &etermine if the(-$+2 against the cursor succee&e 'nstea&, you shoul& chec" the alue of theF0O$(O0D attri%ute, as explaine& in Section >##
>#J +olumn 1liases in +ursors
$he S-L-+$ statement of the cursor inclu&es the list of columns that are returne& %ythat cursor# 5ust as !ith any S-L-+$ statement, this column list may contain eitheractual column names or column expressions, !hich are also referre& to as calculate&or irtual columns#
1 column alias is an alternatie name you proi&e to a column or column expression ina Auery# 3ou may hae use& column aliases in SQL.Plus in or&er to improe therea&a%ility of a& hoc report output# 'n that situation, such aliases are completelyoptional# 'n an explicit cursor, on the other han&, column aliases are reAuire& forcalculate& columns !hen*
3ou (-$+2 into a recor& &eclare& !ith a F &eclaration against that cursor#
3ou !ant to reference the calculate& column in your program#
+onsi&er the follo!ing Auery# (or all companies !ith sales actiity &uring =G, theS-L-+$ statement retriees the company name an& the total amount inoice& to thatcompany 8assume that the &efault &ate format mas" for this instance is DD9MO093333E:*
S-L-+$ company)name, SM 8in)amt: (ROM company +, inoice 'W2-R- +#company)i& 6 '#company)i& 10D '#inoice)&ate B-$W--0 E
-
8/13/2019 Explicit Cursor Oracle new
17/57
%ut it !or"s !ell enough for a Auic" &ip into the &ata as an a& hoc Auery# LetEs no!use this same Auery in an explicit cursor an& a&& a column alias*
D-+L1R- +RSOR comp)cur 'S S-L-+$ company)name, SM 8in)amt: total)sales
(ROM company +, inoice ' W2-R- +#company)i& 6 '#company)i& 10D '#inoice)&ate B-$W--0 E
-
8/13/2019 Explicit Cursor Oracle new
18/57
OP-0)+RSORS specifies the maximum num%er of open cursors that a single9userprocess can hae at once# $his parameter &oes not control a system9!i&e feature, %utrather the maximum a&&ress/memory space use& %y each process# 'f you are sloppyan& &o not close your cursors, you an& all other users might encounter the &rea&e&error message*
OR19#K#; +losing Local +ursors
'f you &eclare a cursor in a PL/SQL %loc" 8an anonymous %loc", proce&ure, orfunction:, the cursor is only &efine& !ithin 8is @local to@: that %loc"# When executionof the %loc" terminates, PL/SQL !ill automatically close any local cursors !hich !ereleft open !ithout raising an exception#
' recommen&, ho!eer, that you still inclu&e +LOS- statements for any cursor you
opene& in your programs# DonEt &epen& on the runtime engine to &o your cleaning upfor you#
'n a&&ition, if your cursor is &efine& in a pac"age, then its scope is not limite& to anyparticular PL/SQL %loc"# 'f you open such a cursor, it !ill stay open until you +LOS-it explicitly or you &isconnect your Oracle session#
># +ursor 1ttri%utes
3ou can manipulate cursors using the OP-0, (-$+2, an& +LOS- statements# Whenyou nee& to get information a%out the current status of your cursor, or the result of thelast fetch from a cursor, you !ill access cursor attri%utes#
=K
-
8/13/2019 Explicit Cursor Oracle new
19/57
Both explicit an& implicit cursors hae four attri%utes, as sho!n in $a%le >#=#
$a%le >#=* +ursor 1ttri%utes0ameDescriptionF(O0DReturns $R- if recor& !as fetche& successfully, (1LS- other!ise#F0O$(O0DReturns $R- if recor& !as not fetche& successfully, (1LS- other!ise#FROW+O0$Returns num%er of recor&s fetche& from cursor at that point in time#
F'SOP-0Returns $R- if cursor is open, (1LS- other!ise#$o o%tain information a%out theexecution of the cursor, you appen& the cursor attri%ute name to the name of yourcursor# (or example, if you &eclare a cursor as follo!s*
+RSOR caller)cur 'S S-L-+$ caller)i&, company)i& (ROM caller
then the four attri%utes associate& !ith the cursor are*
caller)curF(O0D
caller)curF0O$(O0Dcaller)curFROW+O0$caller)curF'SOP-0
Some of the !ays you can access the attri%utes of an explicit cursor are sho!n %elo!in %ol&*
D-+L1R- +RSOR caller)cur 'S S-L-+$ caller)i&, company)i& (ROM caller
caller)rec caller)curFB-7'0 /. Only open the cursor if it is not yet open ./ '( 0O$ caller!cur1IS"PE $2-0 OP-0 caller)cur -0D '( (-$+2 caller)cur '0$O caller)rec
/. eep fetching until no more recor&s are (O0D ./
W2'L- caller!cur1$"D LOOP DBMS)O$P$#P$)L'0- 8E5ust fetche& recor& num%er E $O)+21R &caller!cur1"5C"7 (-$+2 caller)cur '0$O caller)rec -0D LOOP CL"SE caller!cur7
-0D
PL/SQL &oes proi&e these same attri%utes for an implicit cursor# Because an implicitcursor has no name, PL/SQL assigns the generic name SQL to it# sing this name, you
=
-
8/13/2019 Explicit Cursor Oracle new
20/57
can access the attri%utes of an implicit cursor# (or more information on this topic,see Section >##H, @'mplicit SQL +ursor 1ttri%utes@later in the chapter#
3ou can reference cursor attri%utes in your PL/SQL co&e, as sho!n in the prece&ingexample, %ut you cannot use those attri%utes insi&e a SQL statement# 'f you try to usethe FROW+O0$ attri%ute in the W2-R- clause of a S-L-+$, for example*
S-L-+$ caller)i&, company)i& (ROM callerW2-R- company)i& 6 company)curFROW+O0$
then you !ill get a compile error*
PLS9
-
8/13/2019 Explicit Cursor Oracle new
21/57
&o)other)stuff)then)"eep)count *or&er#count)or&ers *6 *or&er#count)or&ers =-0D LOOP+LOS- or&er)cur
'( *or&er#count)or&ers U =$2-0 DBMS)O$P$#P$)L'0- 8E1 total of E $O)+21R 8*or&er#count)or&ers: E or&ers hae %een founE:-LS- /. ' hate to co&e messages li"e E1 total of = or&ers !as founE 't ma"es me soun& illiterate# So ' !ill inclu&e a special9case message !hen 4ust one or&er is foun
./ DBMS)O$P$#P$)L'0-8E5ust one or&er !as founE:-0D '(
>##; $he F0O$(O0D 1ttri%ute
$he F0O$(O0D attri%ute is the opposite of F(O0D# 't returns $R- if theexplicit cursor is una%le to fetch another ro! %ecause the last ro! !as fetche 'f thecursor is una%le to return a ro! %ecause of an error, the appropriate exception israise 'f the cursor has not yet %een opene&, a reference to the F0O$(O0Dattri%ute raises the '01L'D)+RSOR exception# 3ou can ealuate theF0O$(O0D attri%ute of any open cursor, %ecause you reference the cursor %yname#
When shoul& you use F(O0D an& !hen shoul& you use F0O$(O0DT $he t!oattri%utes are &irectly, logically oppose&, so !hateer you can &o !ith one you canalso &o !ith a 0O$ of the other# 'n other !or&s, once a fetch has %een performe&against the open cursor cursor)nameU, the follo!ing expressions are eAuialent*
cursor)nameUF(O0D 6 0O$
cursor)nameUF0O$(O0Dcursor)nameUF0O$(O0D 6 0O$cursor)nameUF(O0D
se !hicheer formulation fits most naturally in your co&e# 'n a preious example, 'issue& the follo!ing statement*
-'$ W2-0 0O$ caller)curF(O0D
to terminate the loop# 1 simpler an& more &irect statement !oul& use theF0O$(O0D instea& of F(O0D, as follo!s*
-'$ W2-0 caller)recF0O$(O0D
;=
-
8/13/2019 Explicit Cursor Oracle new
22/57
>##? $he FROW+O0$ 1ttri%ute
$he FROW+O0$ attri%ute returns the num%er of recor&s fetche& from a cursor atthe time that the attri%ute is Auerie When you first open a cursor, its FROW+O0$is set to Cero# 'f you reference the FROW+O0$ attri%ute of a cursor that is notopen, you !ill raise the '01L'D)+RSOR exception# 1fter each recor& is fetche&,
FROW+O0$ is increase& %y one# $his attri%ute can %e reference& in a PL/SQLstatement, %ut not in a SQL statement#
3ou can use FROW+O0$ to limit the num%er of recor&s fetche& from a cursor# $hefollo!ing example retriees only the first ten recor&s from the cursor, proi&ing the topten companies placing or&ers in =?*
D-+L1R- +RSOR company)cur 'S S-L-+$ company)name, company)i&, total)or&er (ROM company)reenue)ie! W2-R- $O)0MB-R 8$O)+21R 8or&er)&ate:: 6 =? ORD-R B3 total)or&er D-S+ company)rec company)curFB-7'0OP-0 company)curLOOP (-$+2 company)cur '0$O company)rec -'$ W2-0 company)curFROW+O0$ U =< OR company)curF0O$(O0D
DBMS)O$P$#P$)L'0- 8E+ompany E company)rec#company)name E ran"e& num%er E $O)+21R 8company)curFROW+O0$: E#E:-0D LOOP+LOS- company)cur
>##G $he F'SOP-0 1ttri%ute
$he F'SOP-0 attri%ute returns $R- if the cursor is open other!ise, it returns
(1LS-# 'n most cases !hen you use a cursor, you open it, fetch from it, an& close it,all !ithin one routine# Most of the time it is easy to "no! !hether your cursor is openor close 'n some cases, ho!eer, you !ill sprea& your cursor actions out oer a!i&er area of co&e, perhaps across &ifferent routines 8possi%le if the cursor is &eclare&in a pac"age:# 'f so, it !ill ma"e sense to use the F'SOP-0 attri%ute to ma"e sure thata cursor is open %efore you perform a fetch*
'( 0O$ caller)curF'SOP-0$2-0 OP-0 caller)cur
-0D '((-$+2 caller)cur '0$O caller)rec###
;;
-
8/13/2019 Explicit Cursor Oracle new
23/57
0O$-* Remem%er that if you try to open a cursor that has alrea&y %eenopene&, you !ill receie a runtime error*
OR19H==* PL/SQL* cursor alrea&y open
>##H 'mplicit SQL +ursor 1ttri%utes
When the RDBMS opens an implicit cursor to process your reAuest 8!hether it is aAuery or an '0S-R$ or an PD1$-:, it ma"es cursor attri%utes aaila%le to you !iththe SQL cursor# $his is not a cursor in the !ay of an explicit cursor# 3ou cannot open,fetch from, or close the SQL cursor, %ut you can access information a%out the mostrecently execute& SQL statement through SQL cursor attri%utes#
$he SQL cursor has the same four attri%utes as an explicit cursor*
SQLF(O0D
SQLF0O$(O0DSQLFROW+O0$SQLF'SOP-0
>##> Differences Bet!een 'mplicit an& -xplicit +ursor 1ttri%utes
$he alues returne& %y implicit cursor attri%utes &iffer from those of explicit cursorattri%utes in the follo!ing !ays*
'f the RDBMS has not opene& an implicit SQL cursor in the session, then the
SQLFROW+O0$ attri%ute returns 0LL instea& of raising the'01L'D)+RSOR error# References to the other attri%utes 8'SOP-0,(O0D, 0O$(O0D: all return (1LS-# 3ou !ill neer raise the'01L'D)+RSOR error !ith an implicit cursor attri%ute reference#
$he F'SOP-0 attri%ute !ill al!ays return (1LS- 99 %efore an& after the
SQL statement# 1fter the statement is execute& 8!hether it is S-L-+$,PD1$-, D-L-$-, or '0S-R$:, the implicit cursor !ill alrea&y hae %eenopene& an& close& implicitly# 1n implicit cursor can neer %e open outsi&e ofthe statement itself#
SQL cursor attri%utes are al!ays set accor&ing to the results of the mostrecently execute& SQL statement# $hat SQL statement might hae %eenexecute& in a store& proce&ure !hich your program calle& you might noteen %e a!are of that SQL statement execution# 'f you plan to ma"e use of aSQL cursor attri%ute, ma"e sure that you reference that attri%ute imme&iatelyafter you execute the SQL statement#
$he F(O0D attri%ute returns $R- if an PD1$-, D-L-$-, or '0S-R$
affecte& at least one recor 't !ill return (1LS- if those statements faile& toaffect any recor&s# 't returns $R- if an implicit S-L-+$ returns one ro!#
$he %ehaior of the F0O$(O0D attri%ute for PD1$-, D-L-$-, or
;?
-
8/13/2019 Explicit Cursor Oracle new
24/57
'0S-R$ statements is the opposite of F(O0D# $he situation for an implicitS-L-+$ is a %it &ifferent* !hen you use an implicit S-L-+$ statement,neer rely on the F0O$(O0D an& F(O0D attri%utes#
When an implicit S-L-+$ statement &oes not return any ro!s, PL/SQL
imme&iately raises the 0O)D1$1)(O0D exception# When an implicit
S-L-+$ statement returns more than one ro!, PL/SQL imme&iately raisesthe $OO)M103)ROWS exception# 'n either case, once the exception israise&, control shifts to the exception section of the PL/SQL %loc"#
6.89 Cursor Parameters
3ou are pro%a%ly familiar !ith parameters for proce&ures an& functions# Parameters
proi&e a !ay to pass information into an& out of a mo&ule# se& properly, parametersimproe the usefulness an& flexi%ility of mo&ules#
PL/SQL also allo!s you to pass parameters into cursors# $he same rationale for usingparameters in mo&ules applies to parameters for cursors*
1 parameter ma"es the cursor more reusa%le# 'nstea& of har&co&ing a alueinto the W2-R- clause of a Auery to select particular information, you canuse a parameter an& then pass &ifferent alues to the W2-R- clause eachtime a cursor is opene
1 parameter aoi&s scoping pro%lems# When you pass parameters instea& ofhar&co&ing alues, the result set for that cursor is not tie& to a specific aria%lein a program or %loc"# 'f your program has neste& %loc"s, you can &efine thecursor at a higher9leel 8enclosing: %loc" an& use it in any of the su%%loc"s !itharia%les &efine& in those local %loc"s#
3ou can specify as many cursor parameters as you !ant an& nee When you OP-0the parameter, you nee& to inclu&e an argument in the parameter list for each
parameter, except for trailing parameters that hae &efault alues#
When shoul& you parameteriCe your cursorT ' apply the same rule of thum% to cursors
as to mo&ules* if ' am going to use the cursor in more than one place, !ith &ifferentalues for the same W2-R- clause, then ' shoul& create a parameter for the cursor#
LetEs ta"e a loo" at the &ifference %et!een parameteriCe& an& unparameteriCe& cursors#(irst, a cursor !ithout any parameters*
+RSOR 4o"e)cur 'S S-L-+$ name, category, last)use&)&ate (ROM 4o"e
$he result set of this cursor is all the ro!s in the 4o"e ta%le# 'f ' 4ust !ante& to retriee
all 4o"es in the 2SB10D category, ' !oul& nee& to a&& a W2-R- clause asfollo!s*
;G
-
8/13/2019 Explicit Cursor Oracle new
25/57
+RSOR 4o"e)cur 'S S-L-+$ name, category, last)use&)&ate (ROM 4o"e W2-R- category 6 E2SB10DE
' &i&nEt use a cursor parameter to accomplish this tas", nor &i& ' nee& to# $he 4o"e)curcursor no! retriees only those 4o"es a%out hus%an&s# $hatEs all !ell an& goo&, %ut!hat if ' also !oul& li"e to see light%ul% 4o"es an& then chic"en9an&9egg 4o"es an&finally, as my ten9year9ol& !oul& certainly &eman&, all my "noc"9"noc" 4o"esT
>#=
-
8/13/2019 Explicit Cursor Oracle new
26/57
separate cursor to accommo&ate this reAuirement*
OP-0 4o"e)cur 8*4o"e#category:OP-0 4o"e)cur 8Ehus%an&E:OP-0 4o"e)cur 8EpoliticianE:OP-0 4o"e)cur 8*4o"e#relation E '09L1WE:
$he most common place to use a parameter in a cursor is in the W2-R- clause, %utyou can ma"e reference to it any!here in the S-L-+$ statement, as sho!n here*
D-+L1R- +RSOR 4o"e)cur 8category)in 1R+21R;: 'S S-L-+$ name, category)in, last)use&)&ate (ROM 4o"e W2-R- category 6 PP-R 8category)in:
'nstea& of returning the category from the ta%le, ' simply pass %ac" the category)inparameter in the select list# $he result !ill %e the same either !ay, %ecause myW2-R- clause restricts categories to the parameter alue#
>#=
-
8/13/2019 Explicit Cursor Oracle new
27/57
cursor through the parameter list# 'nformation is retriee& from a cursor only %yfetching a recor& an& copying alues from the column list !ith an '0$O clause#
>#=
-
8/13/2019 Explicit Cursor Oracle new
28/57
W2-R- hours)use& 6 < (OR PD1$-
+RSOR fall)4o%s)cur 'S S-L-+$ tas", expecte&)hours, tools)reAuire&, &o)it)yourself)flag (ROM !interiCe W2-R- year 6 $O)+21R 8S3SD1$-, E3333E: (OR PD1$- O( tas"
$he first cursor uses the unAualifie& (OR PD1$- clause, !hile the secon& cursorAualifies the (OR PD1$- !ith a column name from the Auery#
3ou can use the (OR PD1$- clause in a S-L-+$ against multiple ta%les# 'n thiscase, ro!s in a ta%le are loc"e& only if the (OR PD1$- clause references a columnin that ta%le# 'n the follo!ing example the (OR PD1$- clause &oes not result in anyloc"e& ro!s in the !interiCe ta%le*
+RSOR fall)4o%s)cur 'S S-L-+$ !#tas", !#expecte&)hours, !#tools)reAuire&, !#&o)it)yourself)flag (ROM !interiCe !, hus%an&)config hc W2-R- year 6 $O)+21R 8S3SD1$-, E3333E: (OR PD1$- O( hus%an&)config#max)procrastination)allo!e&
$he (OR PD1$- O( clause only mentions the max)procrastination)allo!e&column no columns in the !interiCe ta%le are liste
$he O( list of the (OR PD1$- clause &oes not restrict you to changing only thosecolumns liste Loc"s are still place& on all ro!s the O( list 4ust gies you a !ay to&ocument more clearly !hat you inten& to change# 'f you simply state (OR PD1$-in the Auery an& &o not inclu&e one or more columns after the O( "ey!or&, then the&ata%ase !ill then loc" all i&entifie& ro!s across all ta%les liste& in the (ROM clause#
(urthermore, you &o not hae to actually PD1$- or D-L-$- any recor&s 4ust%ecause you issue& a S-L-+$###(OR PD1$- 99 that act simply states your intentionto %e a%le to &o so#
(inally, you can appen& the optional "ey!or& 0OW1'$ to the (OR PD1$- clauseto tell Oracle not to !ait if the ta%le has %een loc"e& %y another user# 'n this case,control !ill %e returne& imme&iately to your program so that you can perform other!or" or simply !ait for a perio& of time %efore trying again# Without the 0OW1'$clause, your process !ill %loc" until the ta%le is aaila%le# $here is no limit to the !aittime unless the ta%le is remote# (or remote o%4ects, the Oracle initialiCation parameter,D'S$R'B$-D)LO+)$'M-O$, is use& to set the limit#
>#==#= Releasing Loc"s !ith +OMM'$
1s soon as a cursor !ith a (OR PD1$- clause is OP-0e&, all ro!s i&entifie& in theresult set of the cursor are loc"e& an& remain loc"e& until your session issues either a+OMM'$ statement to sae any changes or a ROLLB1+ statement to cancel those
;K
-
8/13/2019 Explicit Cursor Oracle new
29/57
changes# When either of these actions occurs, the loc"s on the ro!s are release 1s aresult, you cannot execute another (-$+2 against a (OR PD1$- cursor after you+OMM'$ or ROLLB1+# 3ou !ill hae lost your position in the cursor#
+onsi&er the follo!ing program, !hich assigns !interiCation chores*=N
=N +aeat* ' &onEt !ant to set false expectations !ith anyone, especially my!ife# $he co&e in this %loc" is purely an example# 'n reality, ' set themax)procrastination)allo!e& to fie years an& let my house &ecay until 'can affor& to pay someone to &o something, or my !ife &oes it, or she giesme an ultimatum# 0o! you "no! !hy ' &eci&e& to !rite a %oo"###
D-+L1R- /. 1ll the 4o%s in the (all to prepare for the Winter ./ +RSOR fall)4o%s)cur 'S S-L-+$ tas", expecte&)hours, tools)reAuire&, &o)it)yourself)flag (ROM !interiCe W2-R- year 6 $O)+21R 8S3SD1$-, E3333E: 10D complete&)flag 6 E0O$3-$E (OR PD1$- O( tas"B-7'0 /. (or each 4o% fetche& %y the cursor### ./ (OR 4o%)rec '0 fall)4o%s)cur LOOP '( 4o%)rec#&o)it)yourself)flag 6 E3O+10DO'$E
$2-0 /. ' hae foun& my next 4o%# 1ssign it to myself 8li"e someone is going to &o itI: an& then commit the changes# ./ PD1$- !interiCe S-$ responsi%le 6 ES$--0E W2-R- tas" 6 4o%)rec#tas" 10D year 6 $O)+21R 8S3SD1$-, E3333E: +OMM'$ -0D '( -0D LOOP-0D
Suppose this loop fin&s its first 3O+10DO'$ 4o%# 't then commits an assignment ofa 4o% to S$--0# When it tries to (-$+2 the next recor&, the program raises thefollo!ing exception*
OR19
-
8/13/2019 Explicit Cursor Oracle new
30/57
>#==#; $he W2-R- +RR-0$ O( +lause
PL/SQL proi&es the W2-R- +RR-0$ O( clause for %oth PD1$- an& D-L-$-statements insi&e a cursor in or&er to allo! you to easily ma"e changes to the mostrecently fetche& ro! of &ata#
$he general format for the W2-R- +RR-0$ O( clause is as follo!s*
PD1$- ta%le)name S-$ set)clauseW2-R- +RR-0$ O( cursor)name
D-L-$- (ROM ta%le)nameW2-R- +RR-0$ O( cursor)name
0otice that the W2-R- +RR-0$ O( clause references the cursor an& not the
recor& into !hich the next fetche& ro! is &eposite$he most important a&antage to using W2-R- +RR-0$ O( !here you nee& tochange the ro! fetche& last is that you &o not hae to co&e in t!o 8or more: places thecriteria use& to uniAuely i&entify a ro! in a ta%le# Without W2-R- +RR-0$ O(,you !oul& nee& to repeat the W2-R- clause of your cursor in the W2-R- clause ofthe associate& PD1$-s an& D-L-$-s# 1s a result, if the ta%le structure changes in a!ay that affects the construction of the primary "ey, you hae to ma"e sure that eachSQL statement is upgra&e& to support this change# 'f you use W2-R- +RR-0$ O(,on the other han&, you only hae to mo&ify the W2-R- clause of the S-L-+$
statement#$his might seem li"e a relatiely minor issue, %ut it is one of many areas in your co&e!here you can leerage su%tle features in PL/SQL to minimiCe co&e re&un&ancies#tiliCation of W2-R- +RR-0$ O(, F$3P-, an& F &eclaration attri%utes, cursor(OR loops, local mo&ulariCation, an& other PL/SQL language constructs can hae a
%ig impact on re&ucing the pain you may experience !hen you maintain your Oracle9%ase& applications#
LetEs see ho! this clause !oul& improe the preious example# 'n the 4o%s cursor (ORloop a%oe, ' !ant to PD1$- the recor& that !as currently (-$+2e& %y the cursor#
' &o this in the PD1$- statement %y repeating the same W2-R- use& in the cursor%ecause 8tas", year: ma"es up the primary "ey of this ta%le*
W2-R- tas" 6 4o%)rec#tas" 10D year 6 $O)+21R 8S3SD1$-, E3333E:
$his is a less than i&eal situation, as explaine& a%oe* ' hae co&e& the same logic int!o places, an& this co&e must %e "ept synchroniCe 't !oul& %e so much moreconenient an& natural to %e a%le to co&e the eAuialent of the follo!ing statements*
Delete the record I just fetched.or*
Update these columns in that row I just fetched.1 perfect fit for W2-R- +RR-0$ O(I
?
-
8/13/2019 Explicit Cursor Oracle new
31/57
$he next ersion of my !interiCation program %elo! uses this clause# ' hae alsos!itche& to a simple loop from (OR loop %ecause ' !ant to exit con&itionally from theloop*
D-+L1R-
+RSOR fall)4o%s)cur 'S S-L-+$ ### same as %efore ### 4o%)rec fall)4o%s)curFB-7'0 OP-0 fall)4o%s)cur LOOP (-$+2 fall)4o%s)cur '0$O 4o%)rec
'( fall)4o%s)curF0O$(O0D $2-0 -'$
-LS'( 4o%)rec#&o)it)yourself)flag 6 E3O+10DO'$E $2-0 PD1$- !interiCe S-$ responsi%le 6 ES$--0E W2-R- +RR-0$ O( fall)4o%s)cur +OMM'$ -'$ -0D '( -0D LOOP +LOS- fall)4o%s)cur
-0D
6.82 Cursor ;aria
-
8/13/2019 Explicit Cursor Oracle new
32/57
then continue fetching an& pass control %ac" to the client program to close the cursor#3ou can also perform the same steps %et!een &ifferent store& programs, on the sameor &ifferent &ata%ase instances#
+ursor aria%les in PL/SQL Release ;#;
+ursor aria%les first %ecame aaila%le in PL/SQL Release ;#;# $his first ersion ofcursor aria%les allo!e& you to open an& close the cursor o%4ects !ithin PL/SQL, %utyou coul& fetch through these cursor aria%les only !ithin a host language 8using theOracle +all 'nterface 99 O+' 99 or a precompiler li"e Pro.+:# 't !as not until Release;#? that the PL/SQL language ma&e cursor aria%les aaila%le for @self9containe&@execution, in&epen&ent of any host language#
Because the focus of this %oo" is on stan&alone PL/SQL &eelopment, ' present cursoraria%les as a PL/SQL Release ;#? enhancement# 'f you &o hae PL/SQL Release ;#;an& !or" !ith PL/SQL in a host language enironment, you can still use cursor
aria%les# 5ust &onEt try to (-$+2 !ithin PL/SQL an& &onEt expect any of the cursorattri%utes to %e aaila%le for your cursor aria%les#
0O$-* $he client9serer aspect of this sharing !ill only really come intoplay !hen the Oracle Deeloper/;
-
8/13/2019 Explicit Cursor Oracle new
33/57
+LOS- company)curar-0D
$hat loo"s an a!ful lot li"e explicit cursor operations, except for the follo!ing*
$he R-( +RSOR type &eclaration
$he OP-0 (OR syntax !hich specifie& the Auery at the time of the open
While the syntax is ery similar, the fact that the cursor aria%le is a aria%le opens upmany ne! opportunities in your programs# $hese are explore& in the remain&er of thissection#
>#=;#= (eatures of +ursor aria%les
+ursor aria%les let you*
1ssociate a cursor aria%le !ith &ifferent Aueries at &ifferent times in yourprogram execution# 'n other !or&s, a single cursor aria%le can %e use& tofetch from &ifferent result sets#
Pass a cursor aria%le as an argument to a proce&ure or function# 3ou can, in
essence, share the results of a cursor %y passing the reference to that resultset#
-mploy the full functionality of static PL/SQL cursors for cursor aria%les#
3ou can OP-0, +LOS-, an& (-$+2 !ith cursor aria%les !ithin yourPL/SQL programs# 3ou can reference the stan&ar& cursor attri%utes 99
F'SOP-0, F(O0D, F0O$(O0D, an& FROW+O0$ 99 for cursoraria%les#
1ssign the contents of one cursor 8an& its result set: to another cursor aria%le#
Because the cursor aria%le is a aria%le, it can %e use& in assignmentoperations# $here are, ho!eer, restrictions on referencing this "in& of aria%le,a&&resse& later in this chapter#
>#=;#; Similarities to Static +ursors
One of the "ey &esign reAuirements for cursor aria%les !as that as much as possi%lethe semantics use& to manage cursor o%4ects !oul& %e the same as that of staticcursors# While the &eclaration of a cursor aria%le an& the syntax for opening it areenhance&, the follo!ing cursor operations are unchange& for cursor aria%les*
$he +LOS- statement# 'n the follo!ing example ' &eclare a R-( +RSOR
type an& a cursor aria%le %ase& on that type# $hen ' close the cursor aria%leusing the same syntax as for that of a static cursor*
D-+L1R-
$3P- ar)cur)type 'S R-( +RSOR ar)cur ar)cur)type
B-7'0
??
-
8/13/2019 Explicit Cursor Oracle new
34/57
+LOS- ar)cur
-0D
+ursor attri%utes# 3ou can use any of the four cursor attri%utes !ith exactlythe same syntax as for that of a static cursor# $he rules goerning the use an&
alues returne& %y those attri%utes match that of explicit cursors# 'f ' hae&eclare& a aria%le cursor as in the preious example, ' coul& use all thecursor attri%utes as follo!s*
ar)curF'SOOP-0
ar)curF(O0D
ar)curF0O$(O0D
ar)curFROW+O0$
(etching from the cursor aria%le# 3ou use the same (-$+2 syntax !hen
fetching from a cursor aria%le into local PL/SQL &ata structures# $here are,ho!eer, a&&itional rules applie& %y PL/SQL to ma"e sure that the &atastructures of the cursor aria%leEs ro! 8the set of alues returne& %y the cursoro%4ect: match that of the &ata structures to the right of the '0$O "ey!or$hese rules are &iscusse& in Section >#=;#>, @Rules for +ursor aria%les@#
Because the syntax for these aspects of cursor aria%les remain unchange&, ' !onEtcoer them again in the remain&er of this section# 'nstea& ' !ill focus on the ne!capa%ilities aaila%le an& the change& syntax reAuire& for cursor aria%les#
>#=;#? Declaring R-( +RSOR $ypes an& +ursor aria%les
5ust as !ith a PL/SQL ta%le or a programmer9&efine& recor&, you must perform t!o&istinct &eclaration steps in or&er to create a cursor aria%le*
= +reate a reference& cursor $3P-#
; Declare the actual cursor aria%le %ase& on that type#
$he syntax for creating a reference& cursor type is as follo!s*
$3P- cursor)type)name 'S R-( +RSOR R-$R0 return)type N
!here cursor)type)name is the name of the type of cursor an& return)type is theR-$R0 &ata specification for the cursor type# $he return)type can %e any of the&ata structures ali& for a normal cursor R-$R0 clause, &efine& using the Fattri%ute or %y referencing a preiously9&efine& recor& $3P-#
0otice that the R-$R0 clause is optional !ith the R-( +RSOR type statement#Both of the follo!ing &eclarations are ali&*
$3P- company)curtype 'S R-( +RSOR R-$R0 companyF$3P- generic)curtype 'S R-( +RSOR
$he first form of the R-( +RSOR statement is calle& a strong type %ecause itattaches a recor& type 8or ro! type: to the cursor aria%le type at the moment of
?G
-
8/13/2019 Explicit Cursor Oracle new
35/57
&eclaration# 1ny cursor aria%le &eclare& using that type can only %e use& !ith SQLstatement an& (-$+2 '0$O &ata structures !hich match the specifie& recor& type#$he a&antage of a strong R-( $3P- is that the compiler can &etermine !hether ornot the &eeloper has properly matche& up the cursor aria%leEs (-$+2 statements!ith its cursor o%4ectEs Auery list#
$he secon& form of the R-( +RSOR statement, in !hich the R-$R0 clause ismissing, is calle& a !ea" type# $his cursor aria%le type is not associate& !ith anyrecor& &ata structure# +ursor aria%les &eclare& !ithout the R-$R0 clause can %euse& in much more flexi%le !ays than the strong type# $hey can %e use& !ith anyAuery, !ith any ro!type structure 99 arying een !ithin the course of a single
program#
>#=;#?#= Declaring cursor aria%les
$he syntax for &eclaring a cursor aria%le is*
cursor)name cursor)type)name
!here cursor)name is the name of the cursor an& cursor)type)name is the name of thetype of cursor preiously &efine& !ith a $3P- statement#
2ere is an example of the creation of a cursor aria%le*
D-+L1R- /. +reate a cursor type for sports cars# ./ $3P- sports)car)cur)type 'S R-( +RSOR R-$R0 carF
/. +reate a cursor aria%le for sports cars# ./ sports)car)cur sports)car)cur)typeB-7'0 ###-0D
't is ery important to &istinguish %et!een &eclaring a cursor aria%le an& creating anactual cursor o%4ect 99 the result set i&entifie& %y the cursor SQL statement# $he cursoraria%le is nothing more than a reference or pointer# 1 constant is nothing more than a
alue, !hereas a aria%le points to its alue# Similarly, a static cursor acts as aconstant, !hereas a cursor aria%le points to a cursor o%4ect# $hese &istinctions aresho!n in (igure >#?# 0otice that t!o &ifferent cursor aria%les in &ifferent programs
%oth refer to the same cursor o%4ect#
(igure >#?* $he referencing character of cursor aria%les
Declaration of a cursor aria%le &oes not create a cursor o%4ect# $o &o that, you mustinstea& use the OP-0 (OR syntax to create a ne! cursor o%4ect an& assign it to the
aria%le#
?H
-
8/13/2019 Explicit Cursor Oracle new
36/57
>#=;#G Opening +ursor aria%les
3ou assign a alue 8the cursor o%4ect: to a cursor !hen you OP-0 the cursor# So thesyntax for the OP-0 statement is no! mo&ifie& in PL/SQL Release ;#? to accept aS-L-+$ statement after the (OR clause, as sho!n %elo!*
OP-0 cursor)name (OR select)statement
!here cursor)name is the name of a cursor or cursor aria%le an& select)statement is aSQL S-L-+$ statement#
(or strong R-( +RSOR type cursor aria%les, the structure of the S-L-+$statement 8the num%er an& &atatypes of the columns: must match or %e compati%le!ith the structure specifie& in the R-$R0 clause of the type statement# (igure>#Goffers an example of the "in& of compati%ility reAuire (igure >#G@ contains the fullset of compati%ility rules#
(igure >#G* +ompati%le R-( +RSOR ro!type an& S-L-+$ list
'f cursor)name is a cursor aria%le &efine& !ith a !ea" R-( +RSOR type, you canOP-0 it for any Auery, !ith any structure# 'n the follo!ing example, ' open 8assign aalue to: the cursor aria%le t!ice, !ith t!o &ifferent Aueries*
D-+L1R- $3P- emp)curtype 'S R-( +RSOR emp)curar emp)curtype
B-7'0 OP-0 emp)curar (OR S-L-+$ . (ROM emp OP-0 emp)curar (OR S-L-+$ employee)i& (ROM emp OP-0 emp)curar (OR S-L-+$ company)i&, name (ROM company-0D
$hat last open &i&nEt een hae anything to &o !ith the employee ta%leI
'f the cursor aria%le has not yet %een assigne& to any cursor o%4ect, the OP-0 (ORstatement implicitly creates an o%4ect for the aria%le#
'f at the time of the OP-0 the cursor aria%le alrea&y is pointing to a cursor o%4ect,then OP-0 (OR &oes not create a ne! o%4ect# 'nstea&, it reuses the existing o%4ectan& attaches a ne! Auery to that o%4ect# $he cursor o%4ect is maintaine& separatelyfrom the cursor or Auery itself#
>#=;#H (etching from +ursor aria%les
1s mentione& earlier, the syntax for a (-$+2 statement using a cursor aria%le is thesame as that for static cursors*
(-$+2 cursor aria%le nameU '0$O recor& nameU(-$+2 cursor aria%le nameU '0$O aria%le nameU, aria%lenameU ###
?>
-
8/13/2019 Explicit Cursor Oracle new
37/57
When the cursor aria%le !as &eclare& !ith a strong R-( +RSOR type, the PL/SQLcompiler ma"es sure that the &ata structure8s: liste& after the '0$O "ey!or& arecompati%le !ith the structure of the Auery associate& !ith cursor aria%le#
>#=;#H#= Strong an& !ea" R-( +RSOR types
'f the cursor aria%le is of the !ea" R-( +RSOR type, the PL/SQL compiler cannotperform the same "in& of chec"# Such a cursor aria%le can (-$+2 into any &atastructures, %ecause the R-( +RSOR type it is not i&entifie& !ith a ro!type at thetime of &eclaration# 1t compile time, there is no !ay to "no! !hich cursor o%4ect 8an&associate& SQL statement: !ill %e assigne& to that aria%le#
+onseAuently, the chec" for compati%ility must happen at run time, !hen the (-$+2is a%out to %e execute 1t this point, if the Auery an& the '0$O clause &o notstructurally match 8an& PL/SQL !ill use implicit conersions if necessary an&
possi%le:, then the PL/SQL runtime engine !ill raise the pre&efine& )M'SM1$+2
exception#
>#=;#H#; 2an&ling the )M'SM1$+2 exception
Before PL/SQL actually performs its (-$+2, it chec"s for compati%ility# 1s a result,you can trap the )M'SM1$+2 exception an& attempt to (-$+2 from the cursoraria%le using a &ifferent '0$O clause 99 an& you !ill not hae s"ippe& any ro!s inthe result set#
-en though you are executing a secon& (-$+2 statement in your program, you !illstill retriee the first ro! in the result set of the cursor o%4ectEs Auery# $his functionalitycomes in especially han&y for !ea" R-( +RSOR types#
'n the follo!ing example, a centraliCe& real estate &ata%ase stores information a%outproperties in a ariety of ta%les, one for homes, another for commercial properties, etc#$here is also a single, central ta%le !hich stores an a&&ress an& a %uil&ing type 8home,commercial, etc#:# ' use a single proce&ure to open a !ea" R-( +RSOR aria%le forthe appropriate ta%le, %ase& on the street a&&ress# -ach in&ii&ual real estate office canthen call that proce&ure to scan through the matching properties*
= Define my !ea" R-( +RSOR type*
; $3P- %uil&ing)curtype 'S R-( +RSOR
? +reate the proce&ure# 0otice that the mo&e of the cursor aria%le parameter is'0 O$*
G PRO+-DR- open)site)list5 8a&&ress)in '0 1R+21R;,6 site)cur)inout '0 O$ %uil&ing)curtype:J 'S8 home)type +O0S$10$ '0$-7-R *6 =
9 commercial)type +O0S$10$ '0$-7-R *6 ;1011 /. 1 static cursor to get %uil&ing type# ./
?J
-
8/13/2019 Explicit Cursor Oracle new
38/57
12 +RSOR site)type)cur 'S13 S-L-+$ site)type (ROM property)master14 W2-R- a&&ress 6 a&&ress)in15 site)type)rec site)type)curF16
=JB-7'018 /. 7et the %uil&ing type for this a&&ress# ./19 OP-0 site)type)cur20 (-$+2 site)type)cur '0$O site)type)rec21 +LOS- site)type)cur22
23 /. 0o! use the site type to select from the right ta%le#./24 '( site)type)rec#site)type 6 home)type25 $2-026 /. se the home properties ta%le# ./27
OP-0 site)cur)inout (OR28 S-L-+$ . (ROM home)properties29 W2-R- a&&ress L'- EFE a&&ress)in EFE30
31 -LS'( site)type)rec#site)type 6 commercial)type32 $2-033 /. se the commercial properties ta%le# ./34 OP-0 site)cur)inout (OR35 S-L-+$ . (ROM commercial)properties36 W2-R- a&&ress L'- EFE a&&ress)in EFE
37 -0D '(?K-0D open)site)list
?0o! that ' hae my open proce&ure, ' can use it to scan properties#
'n the follo!ing example, ' pass in the a&&ress an& then try to fetch from the cursor,assuming a home property# 'f the a&&ress actually i&entifies a commercial property,PL/SQL !ill raise the )M'SM1$+2 exception 8incompati%le recor& structures:# $heexception section then fetches again, this time into a commercial %uil&ing recor&, an&the scan is complete#;N
;N $he @prompt@ an& @sho!@ programs reference& in the example interact!ith users an& are not &ocumente& here#
D-+L1R- /. Declare a cursor aria%le# ./ %uil&ing)curar %uil&ing)curtype
/. Define recor& structures for t!o &ifferent ta%les# ./ home)rec home)propertiesF commercial)rec commercial)propertiesF
B-7'0 /. 7et the a&&ress from the user# ./ prompt)for)a&&ress 8a&&ress)string:
?K
-
8/13/2019 Explicit Cursor Oracle new
39/57
/. 1ssign a Auery to the cursor aria%le %ase& on the a&&ress# ./ open)site)list 8a&&ress)string, %uil&ing)curar:
/. 7ie it a tryI (etch a ro! into the home recor ./ (-$+2 %uil&ing)curar '0$O home)rec
/. 'f ' got here, the site !as a home, so &isplay it# ./ sho!)home)site 8home)rec:-+-P$'O0 /. 'f the first recor& !as not a home### ./ W2-0 )M'SM1$+2 $2-0 /. (etch that same =st ro! into the commercial recor ./ (-$+2 %uil&ing)curar '0$O commercial)rec
/. Sho! the commercial site info# ./ sho!)commercial)site 8commercial)rec:-0D
>#=;#> Rules for +ursor aria%les
$his section examines in more &etail the rules an& issues regar&ing the use of cursoraria%les in your programs# $his inclu&es ro!type matching rules, cursor aria%le
aliases, an& scoping issues#
Remem%er that the cursor aria%le is a reference to a cursor o%4ect or Auery in the&ata%ase# 't is not the o%4ect itself# 1 cursor aria%le is sai& to @refer to a gien Auery@if either of the follo!ing is true*
1n OP-0 statement (OR that Auery !as execute& !ith the cursor aria%le#
1 cursor aria%le !as assigne& a alue from another cursor aria%le that refers
to that Auery#
3ou can perform assignment operations !ith cursor aria%les an& also pass thesearia%les as arguments to proce&ures an& functions# 'n or&er to perform such actions
%et!een cursor aria%les 8an& to %in& a cursor aria%le to a parameter:, the &ifferentcursor aria%les must follo! a set of compile9time an& runtime ro!type matchingrules#
>#=;#>#= +ompile9time ro!type matching rules
$hese are the rules that PL/SQL follo!s at compile9time*
$!o cursor aria%les 8inclu&ing proce&ure parameters: are compati%le for
assignments an& argument passing if any of the follo!ing are true*
Both aria%les 8or parameters: are of a strong R-( +RSOR type !ith
?
-
8/13/2019 Explicit Cursor Oracle new
40/57
the same ro!type)nameU#
Both aria%les 8or parameters: are of some !ea" R-( +RSOR type,
regar&less of the ro!type)nameU#
One aria%le 8parameter: is of any strong R-( +RSOR type, an& the
other is of any !ea" R-( +RSOR type# 1 cursor aria%le 8parameter: of a strong R-( +RSOR type may %e OP-0
(OR a Auery that returns a ro!type !hich is structurally eAual to thero!type)nameU in the original type &eclaration#
1 cursor aria%le 8parameter: of a !ea" R-( +RSOR type may %e OP-0
(OR any Auery# $he (-$+2 from such a aria%le is allo!e& '0$O any list ofaria%les or recor& structure#
'n other !or&s, if either of the cursor aria%les are of the !ea" R-( +RSOR type,
then the PL/SQL compiler cannot really ali&ate !hether the t!o &ifferent cursoraria%les !ill %e compati%le# $hat !ill happen at runtime the rules are coere& in thenext section#
>#=;#>#; Run9time ro!type matching rules
$hese are the rules that PL/SQL follo!s at run time*
1 cursor aria%le 8parameter: of a !ea" R-( +RSOR type may %e ma&e to
refer to a Auery of any ro!type regar&less of the Auery or cursor o%4ect to!hich it may hae referre& earlier#
1 cursor aria%le 8parameter: of a strong R-( +RSOR type may %e ma&e
to refer only to a Auery !hich matches structurally the ro!type)nameU ofthe R-$R0 clause of the R-( +RSOR type &eclaration#
$!o recor&s 8or lists of aria%les: are consi&ere& structurally matching !ith
implicit conersions if %oth of the follo!ing are true*
$he num%er of fiel&s is the same in %oth recor&s 8lists:#
(or each fiel& in one recor& 8or aria%le on one list:, a correspon&ing
fiel& in the secon& list 8or aria%le in secon& list: has the same PL/SQL&atatype, or one !hich can %e conerte& implicitly %y PL/SQL to matchthe first#
(or a cursor aria%le 8parameter: use& in a (-$+2 statement, the Auery
associate& !ith the cursor aria%le must structurally match !ith implicitconersions the recor& or list of aria%les of the '0$O clause of the (-$+2statement# $his is, %y the !ay, the same rule use& for static cursors#
>#=;#>#? +ursor aria%le aliases
'f you assign one cursor aria%le to another cursor aria%le, those t!o cursor aria%les%ecome aliases for the same cursor o%4ect# $hey share the reference to the cursor
G
-
8/13/2019 Explicit Cursor Oracle new
41/57
o%4ect 8result set of the cursorEs Auery:# 1n action ta"en against the cursor o%4ectthrough one aria%le is also aaila%le to an& reflecte& in the other aria%le#
$he follo!ing anonymous %loc" illustrates the !ay cursor aliases !or"*
= D-+L1R-; $3P- curar)type 'S R-( +RSOR? curar= curar)typeG curar; curar)typeH story fairy)talesF> B-7'0J /. 1ssign cursor o%4ect to curar=# ./K OP-0 curar= (OR S-L-+$ . (ROM fairy)tales=< /. 1ssign same cursor o%4ect to curar;# ./== curar; *6 curar=
=;=? /. (etch first recor& from curar=# ./=G (-$+2 curar= '0$O story=H=> /. (etch secon& recor& from curar;# ./=J (-$+2 curar; '0$O story=K= /. +lose the cursor o%4ect %y referencing curar;# ./;< +LOS- curar;;=;; /. $his statement raises '01L'D)+RSOR exceptionI ./;? (-$+2 curar= '0$O story;G -0D
$he follo!ing ta%le is an explanation of cursor aria%le actions#
Lines1ction=9HDeclare my !ea" R-( +RSOR type an& cursor aria%le through line H#K+reates acursor o%4ect an& assigns it to curar=#==1ssigns that same cursor o%4ect to the secon& cursoraria%le, curar;#=G(etches the first recor& using the curar= aria%le#=J(etches the secon& recor&using the curar; aria%le# 80otice that it &oesnEt matter !hich of the t!o aria%les you use# $he
pointer to the current recor& resi&es !ith the cursor o%4ect, not any particular aria%le#:;#=;#>#G Scope of cursor o%4ect
$he scope of a cursor aria%le is the same as that of a static cursor* the PL/SQL %loc"in !hich the aria%le is &eclare& 8unless &eclare& in a pac"age, !hich ma"es the
aria%le glo%ally accessi%le:# $he scope of the cursor o%4ect to !hich a cursor aria%leis assigne&, ho!eer, is a &ifferent matter#
G=
-
8/13/2019 Explicit Cursor Oracle new
42/57
Once an OP-0 (OR creates a cursor o%4ect, that cursor o%4ect remains accessi%le aslong as at least one actie cursor aria%le refers to that cursor o%4ect# $his means thatyou can create a cursor o%4ect in one scope 8PL/SQL %loc": an& assign it to a cursoraria%le# $hen, %y assigning that cursor aria%le to another cursor aria%le !ith a&ifferent scope, the cursor o%4ect remains accessi%le een if the original cursor aria%le
has gone out of scope#'n the follo!ing example ' use neste& %loc"s to &emonstrate ho! the cursor o%4ect can
persist outsi&e of the scope in !hich it !as originally create&*
D-+L1R- /. Define !ea" R-( +RSOR type, cursor aria%le an& local aria%le ./ $3P- curar)type 'S R-( +RSOR curar= curar)type &o)you)get)it 1R+21R;8=
-
8/13/2019 Explicit Cursor Oracle new
43/57
'f you are creating a local mo&ule !ithin another program 8see +hapter =Hfor moreinformation a%out local mo&ules:, then you can also &efine the cursor type in the same
program# 't !ill then %e aaila%le for the parameter# $his approach is sho!n %elo!*
D-+L1R- /. Define the R-( +RSOR type# ./
$3P- curar)type 'S R-( +RSOR R-$R0 companyF
/. Reference it in the parameter list# ./ PRO+-DR- open)Auery 8curar)out O$ curar)type: 'S local)cur curar)type B-7'0 OP-0 local)cur (OR S-L-+$ . (ROM company curar)out *6 local)cur -0D
B-7'0 ###-0D
'f you are creating a stan&alone proce&ure or function, then the only !ay you canreference a pre9existing R-( +RSOR type is %y placing that type statement in a
pac"age# 1ll aria%les &eclare& in the specification of a pac"age act as glo%als !ithinyour session, so you can then reference this cursor type using the &ot notation assho!n %elo!*
= +reate the pac"age !ith a R-( +RSOR type &eclaration*; P1+17- company? 'S4 /. Define the R-( +RSOR type# ./5 $3P- curar)type 'S R-( +RSOR R-$R0 companyF> -0D pac"age
J 'n a stan&alone proce&ure, reference the R-( +RSOR type %y prefacing thename of the cursor type !ith the name of the pac"age*
K PRO+-DR- open)company 8curar)out O$company#curar)type: 'S
B-7'010 ###==-0D
See +hapter =>for more information on this feature#
>#=;#J#; Setting the parameter mo&e
5ust li"e other parameters, a cursor aria%le argument can hae one of the follo!ingthree mo&es*
G?
-
8/13/2019 Explicit Cursor Oracle new
44/57
'0
+an only %e rea& %y program
O$
+an only %e !ritten to %y program'0 O$
Rea&/!rite in program
Remem%er that the alue of a cursor aria%le is the reference to the cursor o%4ect an¬ the state of the cursor o%4ect# 'n other !or&s, the alue of a cursor aria%le &oesnot change after you fetch from or close a cursor#
Only t!o operations, in fact, may change the alue of a cursor aria%le change, that is,the cursor o%4ect to !hich the aria%le points*
1n assignment to the cursor aria%le
1n OP-0 (OR statement
'f the cursor aria%le alrea&y pointe& to a cursor o%4ect, then the OP-0 (OR !oul&nEtactually change the reference# 't !oul& simply change the Auery associate& !ith theo%4ect#
$he (-$+2 an& +LOS- operations affect the state of the cursor o%4ect, %ut not thereference to the cursor o%4ect itself, !hich is the alue of the cursor aria%le#
2ere is an example of a program !hich has cursor aria%les as parameters*
PRO+-DR- assign)curar 8ol&)curar)in '0 company#curar)type, ne!)curar)out O$ company#curar)type:'SB-7'0 ne!)curar)out *6 ol&)curar)in-0D
$his proce&ure copies the ol& company cursor aria%le to the ne! aria%le# $he firstparameter is an '0 parameter %ecause it appears only on the right9han& si&e of theassignment# $he secon& parameter must %e an O$ 8or '0 O$: parameter, %ecauseits alue is change& insi&e the proce&ure# 0otice that the curar)type is &efine& !ithinthe company pac"age#
>#=;#K +ursor aria%le Restrictions
+ursor aria%les are su%4ect to the follo!ing restrictions Oracle may remoe some ofthese in future releases#
+ursor aria%les cannot %e &eclare& in a pac"age since they &o not hae a
persistent state#
GG
-
8/13/2019 Explicit Cursor Oracle new
45/57
3ou cannot use RP+s 8Remote Proce&ure +alls: to pass cursor aria%les from
one serer to another#
'f you pass a cursor aria%le as a %in& or host aria%le to PL/SQL, you !ill
not %e a%le to fetch from it from !ithin the serer unless you also open it inthat same serer call#
$he Auery you associate !ith a cursor aria%le in an OP-09(OR statement
cannot use the (OR PD1$- clause#
3ou cannot test for cursor aria%le eAuality, ineAuality, or nullity using
comparison operators#
3ou cannot assign 0LLs to a cursor aria%le#
Data%ase columns cannot store cursor aria%le alues# 3ou !ill not %e a%le to
use R-( +RSOR types to specify column types in statements to +R-1$-
$1BL-s or +R-1$- '-Ws#
$he elements in a neste& ta%le, in&ex9%y ta%le, or aria%le array 81RR13:
cannot store the alues of cursor aria%les# 3ou !ill not %e a%le to use R-(+RSOR types to specify the element type of a collection#
+ursor aria%les cannot %e use& !ith &ynamic SQL 8through use of the
DBMS)SQL pac"age:#
>#=? Wor"ing !ith +ursors
$he follo!ing sections offer some practical applications of cursors# $hey are also&esigne& to %e programs you can put to use in your o!n enironments !ith a fe!changes# $he follo!ing files on the companion &is" offer a&&itional examples*
arcurs#&oc
-xplanation of ho! to emulate a cursor aria%le !ith local mo&ules
unAuein#&oc
-xplanation of ho! to guarantee uniAue entry !ith cursors
unAuein#ff
+o&e reAuire& to guarantee uniAue entry !ith cursors
>#=?#= ali&ating (oreign ey -ntry !ith +ursors
1 hefty percentage of our co&e can %e ta"en up !ith ali&ating the entry or selection offoreign "eys# +onsi&er the example of an application !hich maintains companies an&employees of that company# On the employee maintenance screen, ' !ant to let my
user enter the name or partial name of the company that employs a person# 'f the userhas i&entifie& a uniAue company, the form &isplays that name an& stores the company'D on the null canas# 'f the userEs entry fin&s more than one match, a message is
GH
-
8/13/2019 Explicit Cursor Oracle new
46/57
&isplaye 'f no matches are foun&, the entry is re4ecte
2o! shoul& ' implement this reAuirementT Well, the first thing that comes to the min&sof many programmers is the follo!ing*
se a cursor !hich, !ith a single fetch, employs the +O0$ %uilt9in tocompute the total num%er of companies that match the enemy#
$his is, perhaps, the most o%ious an& &irect solution to the reAuirement 99 !hen it isphrase& as follo!s*
$o fin& out if the userEs entry has more than one match, count up 4ust ho!many matches there are#
>#=?#=#= 'nefficiency of group functions in cursors
$here are, ho!eer, t!o serious pro%lems !ith using the +O0$ group function inmy cursor*
$he cursor &oes far too much !or" on my %ehalf# By using +O0$, thecursor must scan through all recor&s 8or, ' hope, those i&entifie& %y the in&ex:an& count up the total num%er of matching recor&s# 3et, all ' really nee& to"no! is !hether more than one company matche& the entry# $he performance
penalty on this +O0$ coul& %e seere if the Auery goes out oer a net!or"or if the userEs entry matches many of the recor&s# What if a user entere& a
percent sign 8F:T 1ll recor&s !oul& then match# 1n application shoul& neerpunish a user for poorly thought9out &ata entry#
$he cursor &oes not &o enough for me# 'f the +O0$9%ase& Auery &i& return aalue of =, ' !oul& still hae to go %ac" to the company ta%le an& S-L-+$ the'D for that company !ith another cursor# 1s a result, ' !oul& hae co&e& thesame Auery t!ice# $his re&un&ancy intro&uces maintenance an& performanceissues#
3ou shoul& use +O0$ only !hen you nee& to "no! or &isplay the total num%er ofmatches for the userEs entry# 'n this scenario, ' &onEt really nee& that total ' nee& onlyto "no! if the total is greater than one 8i#e#, if there is more than one match:# ' cano%tain this "no!le&ge in a much more efficient an& straightfor!ar& manner#
>#=?#=#; sing multiple fetches more efficiently
se a cursor that, !ith multiple fetches, &etermines if there are at least t!o companiesthat match the entry# $his approach ta"es a %it more sophistication an& thought, %ut isal!ays a %etter performer an& offers more flexi%ility to programmers#
$o employ the multiple9fetch techniAue, ta"e the follo!ing steps*
= Declare a cursor !hich returns the company)i& of all companies that matchthe alue in the item*
; +RSOR company)cur? 'S4 S-L-+$ company)i&
G>
-
8/13/2019 Explicit Cursor Oracle new
47/57
5 (ROM company6 W2-R- company)name L'- *company#company)name EFE
J (etch t!ice against this cursor# 'f ' can fetch t!ice successfully 8company)curF0O$(O0D is (1LS- %oth times:, that means that there is more than one
match for the company name# 'f ' can fetch only once %efore theF0O$(O0D cursor attri%ute returns (1LS-, then ' hae foun& a uniAuematch# 'f the ery first fetch fails, then there is no match for the name#
K Because my cursor returns the company)i&, ' &o not hae to perform anotherselect once ' hae &etermine& that ' hae a uniAue match# ' simply use the 'Dthat !as proi&e& in the first fetch#
$he proce&ure in the follo!ing example supports the foreign "ey ali&ationreAuirements !ith a &ou%le fetch against the cursor 8it is co&e& for Oracle (orms, %utcan %e a&apte& easily to other tool enironments:*
/. (ilename on companion &is"* f"al#fp ./PRO+-DR- ali&ate)company 8comp)name)inout '0 O$ company#company)nameF$3P-, comp)i&)out O$ company#company)i&F$3P-:'S /. +ursor as explaine& a%oe ./ +RSOR company)cur 'S S-L-+$ company)i&, company)name (ROM company
W2-R- company)name L'- comp)name)inout EFE /. Declare t!o recor&s against the same cursor# ./ company)rec company)curF &uplicate)rec company)curFB-7'0 /. Open an& perform the first fetch against cursor# ./ OP-0 company)cur (-$+2 company)cur '0$O company)rec '( company)curF0O$(O0D
$2-0 /. 0ot een one match for this name# Display message an& re4ect# ./ M-SS17- 8E 0o company foun& !ith name li"e @E comp)name)inout E@#E: +LOS- company)cur R1'S- (ORM)$R'77-R)(1'LR- -LS- /. (oun& one match# 0o! (-$+2 again, %ut this time (-$+2 into the &uplicate)rec recor $his is 4ust a @place hol&er@# ' &onEt nee& to see the contents of the recor ' 4ust nee& to "no! if
GJ
-
8/13/2019 Explicit Cursor Oracle new
48/57
' can successfully retriee another recor& from the cursor# ./ (-$+2 company)cur '0$O &uplicate)rec '( company)curF0O$(O0D $2-0
/. (oun& = match, %ut not secon niAueI 1ssign alues to the O$ parameters an& close the cursor# ./ comp)i&)out *6 company)rec#company)i& comp)name)inout *6 company)rec#company)name +LOS- company)cur -LS- /. 1t least t!o matches foun& for this name# ' &onEt "no! ho! many more an& ' &o not care# Re4ect !ith message# ./ M-SS17- 8E More than one company matches name li"e @E comp)name)inout E@#E: +LOS- company)cur R1'S- (ORM)$R'77-R)(1'LR- -0D '( -0D '(-0D
+all this proce&ure in the When9ali&ate9'tem trigger so that any changes to thecompany name can %e ali&ate 2ere is an example of an actual call toali&ate)company*
ali&ate)company 8*employee#company)name, *employee#company)i&:
0otice that the first parameter 8the company name: is an '0 O$ parameter# ' !ant tolet the user enter 4ust a part of the name an& let the application figure out if that entry isenough to uniAuely i&entify a company# 'f a single match is foun&, the form replacesthe partial entry !ith the full name#
' %eliee strongly that !e shoul& &esign our applications to allo! the user to enter theminimal amount of information necessary to get the 4o% &one# Our applications shoul&
%e smart enough to ta"e a&antage of the &um%, %rute strength of our +Ps in or&er tolift some of the %ur&en off the user#
>#=?#; Managing a Wor" Queue !ith S-L-+$ (OR PD1$-
1s &iscusse& earlier, a cursor !ith a S-L-+$###(OR PD1$- syntax issues a ro!9leel loc" on each ro! i&entifie& %y the Auery# ' encountere& a ery interesting
application of this feature !hile helping a client resole a pro%lem#$he client offers a &istri%ution pac"age !hich trac"s !arehouse inentory# $he !or"
GK
-
8/13/2019 Explicit Cursor Oracle new
49/57
Aueue screen assigns !arehouse floor pac"ers their next tas"s# $he pac"er opens thescreen an& reAuests a tas"# $he screen fin&s the next unassigne& tas" an& assigns it tothe pac"er# 1 tas" might inole collecting arious pro&ucts together for shipment orreturning pro&ucts to the shelf# +ompletion of this tas" can ta"e any!here %et!eenone an& ten minutes# When the tas" is complete&, the pac"er !ill commit the changes
or close the screen, performing an implicit commit#(or the amount of time it ta"es a pac"er to finish the tas", that recor& must %e tagge&as @assigne&@ so that no other pac"er is gien the same 4o% to &o# $he first attempt atimplementing this feature inole& the use of a status flag# Wheneer a pac"er !asassigne& a tas", the flag on that tas" !as set to 1SS'70-D an& the tas" recor&committe $he screen then exclu&es that tas" from the !or" Aueue# $he pro%lem !iththis approach is that the status ha& to %e committe& to the &ata%ase so that other userscoul& see the ne! status# $his commit not only interrupte& the actual transaction in thescreen, %ut also create& a num%er of hea&aches*
What if the user neer completes the tas" an& exits the screenT $he form!oul& hae to &etect this scenario 8an& there are generally many !ays tocancel/exit: an& up&ate the status flag to 11'L1BL-, !hich inoles yetanother commit#
Worse yet, !hat if the &ata%ase goes &o!n !hile the user is performing the
tas"T $hat tas" !ill &isappear from the !or" Aueue until manual interentionresets the status#
My client nee&e& a mechanism %y !hich the tas" coul& %e flagge& as 011'L1BL-!ithout haing to perform commits, %uil& complex chec"s into the form, an& &eelopcrash9recoery gui&elines# $hey nee&e& a program that !oul& step through