Explicit Cursor Oracle new

download Explicit Cursor Oracle new

of 57

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&not 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