Tải bản đầy đủ
Lab 3.2: Transaction Control in PL/SQL

Lab 3.2: Transaction Control in PL/SQL

Tải bản đầy đủ

UsingCOMMIT,ROLLBACK,andSAVEPOINT
Transactionsareameanstobreakprogrammingcodeintomanageableunits.Grouping
transactionsintosmallerelementsisastandardpracticethatensuresanapplicationwill
saveonlycorrectdata.Initially,anyapplicationwillhavetoconnecttothedatabaseto
accessthedata.WhenauserisissuingDMLstatementsinanapplication,however,these
changesarenotvisibletootherusersuntilaCOMMITorROLLBACKhasbeenissued.The
Oracleplatformguaranteesaread-consistentviewofthedata.Untilthatpoint,alldatathat
havebeeninsertedorupdatedwillbeheldinmemoryandwillbeavailableonlytothe
currentuser.Therowsthathavebeenchangedwillbelockedbythecurrentuserandwill
notbeavailableforupdatingtootherusersuntilthelockshavebeenreleased.ACOMMIT
orROLLBACKstatementwillreleasetheselocks.Transactionscanbecontrolledmore
readilybymarkingpointsofthetransactionwiththeSAVEPOINTcommand.
COMMIT:Makeseventswithinatransactionpermanent.
ROLLBACK:Eraseseventswithinatransaction.
Additionally,youcanuseaSAVEPOINTtocontroltransactions.Transactionsare
definedinthePL/SQLblockfromoneSAVEPOINTtoanother.Theuseofthe
SAVEPOINTcommandallowsyoutobreakyourSQLstatementsintounitssothatina
givenPL/SQLblock,someunitscanbecommitted(savedtothedatabase),otherscanbe
rolledback(undone),andsoforth.
BytheWay
TheOracleplatformmakesadistinctionbetweenatransactionandaPL/SQL
block.ThestartandendofaPL/SQLblockdonotnecessarilymeanthestart
andendofatransaction.
Todemonstratetheneedfortransactioncontrol,wewillexamineatwo-stepdata
manipulationprocess.SupposethatthefeesforallcoursesintheCTAdatabasethathavea
prerequisitecourseneedtobeincreasedby10percent;atthesametime,allcoursesthat
donothaveaprerequisiteneedtobedecreasedby10percent.Thisisatwo-stepprocess.
Ifthefirststepissuccessfulbutthesecondstepisnot,thenthedataconcerningcourse
costwouldbeinconsistentinthedatabase.Becausethisadjustmentisbasedonachange
inpercentage,therewouldbenowaytotrackwhichpartofthiscourseadjustmentwas
successfulandwhichpartwasnot.
Inthefollowingexample,onePL/SQLblockperformstwoupdatesonthecostitemin
thecoursetable.Inthefirststep(thiscodeiscommentedforthepurposeof
emphasizingeachupdate),thecostisupdatedwithacostthatis10percentlesswhenever
thecoursedoesnothaveaprerequisite.Inthesecondstep,thecostisincreasedby10
percentwheneverthecoursehasaprerequisite.
ForExamplech03_7a.sql
Clickheretoviewcodeimage
BEGIN
—STEP1

UPDATEcourse
SETcost=cost-(cost*0.10)
WHEREprerequisiteISNULL;
—STEP2
UPDATEcourse
SETcost=cost+(cost*0.10)
WHEREprerequisiteISNOTNULL;
END;

Let’sassumethatthefirstupdatestatementsucceeds,butthesecondupdatestatement
failsbecausethenetworkwentdown.Thedatainthecoursetableisnowinconsistent
becausecourseswithnoprerequisitehavehadtheircostreducedbutcourseswith
prerequisiteshavenotbeenadjusted.Topreventthissortofsituation,statementsmustbe
combinedintoatransaction.Thuseitherbothstatementswillsucceedorbothstatements
willfail.
AtransactionusuallycombinesSQLstatementsthatrepresentalogicalunitofwork.
ThetransactionbeginswiththefirstSQLstatementissuedaftertheprevioustransaction,
orwiththefirstSQLstatementissuedafterconnectingtothedatabase.Thetransaction
endswiththeCOMMITorROLLBACKstatement.
COMMIT
WhenaCOMMITstatementisissuedtothedatabase,thetransactionhasended,andthe
followingresultsaretrue:
Allworkdonebythetransactionbecomespermanent.
Otheruserscanseechangesindatamadebythetransaction.
Anylocksacquiredbythetransactionarereleased.
ACOMMITstatementhasthefollowingsyntax:
COMMIT[WORK];

ThewordWORKisoptionalandisusedtoimprovereadability.Untilatransactionis
committed,onlytheuserexecutingthattransactioncanseechangesinthedatamadeby
hisorhersession.
SupposeUserAissuesthefollowingcommandonastudenttablethatexistsin
anotherschemabuthasapublicsynonymofstudent:
ForExamplech03_8a.sql
Clickheretoviewcodeimage
BEGIN
INSERTINTOstudent
(student_id,last_name,zip,registration_date,
created_by,created_date,modified_by,
modified_date
)
VALUES(student_id_seq.nextval,‘Tashi’,10015,
‘01-JAN-99’,‘STUDENTA’,‘01-JAN-99’,
‘STUDENTA’,‘01-JAN-99’
);
END;

ThenUserBentersthefollowingcommandtoquerythetableknownbyitspublic
synonymstudent,whileloggedontohissession.
SELECT*
FROMstudent
WHERElast_name=‘Tashi’;

ThenUserAissuesthefollowingcommand:
COMMIT;

NowifUserBentersthesamequeryagain,hewillnotseethesameresults.
Inthisexample,therearetwosessions:UserAandUserB.UserAinsertsarecordinto
thestudenttable.UserBqueriesthestudenttable,butdoesnotgettherecordthat
wasinsertedbyUserA.UserBcannotseetheinformationbecauseUserAhasnot
committedthework.WhenUserAcommitsthetransaction,UserB,uponresubmitting
thequery,seestherecordsinsertedbyUserA.
ROLLBACK
WhenaROLLBACKstatementisissuedtothedatabase,thetransactionhasended,andthe
followingresultsaretrue:
Allworkdonebythetransactionisundone,asifithadn’tbeenissued.
Anylocksacquiredbythetransactionarereleased.
AROLLBACKstatementhasthefollowingsyntax:
ROLLBACK[WORK];

TheWORKkeywordisoptionalandprovidesforincreasedreadability.
SAVEPOINT
TheROLLBACKstatementundoesallworkdonebytheuserinaspecifictransaction.With
theSAVEPOINTcommand,however,onlypartofthetransactioncanbeundone.A
SAVEPOINTcommandhasthefollowingsyntax:
SAVEPOINTname;

ThewordnameistheSAVEPOINTstatement’sname.OnceaSAVEPOINTisdefined,
theprogramcanrollbacktothatSAVEPOINT.AROLLBACKstatement,then,hasthe
followingsyntax:
Clickheretoviewcodeimage
ROLLBACK[WORK]toSAVEPOINTname;

WhenaROLLBACKtoSAVEPOINTstatementisissuedtothedatabase,thefollowing
resultsaretrue:
AnyworkdonesincetheSAVEPOINTisundone.TheSAVEPOINTremainsactive,
however,untilafullCOMMITorROLLBACKisissued.Itcanberolledbackagain,if
desired.
AnylocksandresourcesacquiredbytheSQLstatementssincetheSAVEPOINT

willbereleased.
Thetransactionisnotfinished,becauseSQLstatementsarestillpending.

PuttingTogetherDMLandTransactionControl
Thissectioncombinesalltheelementsoftransactioncontrolthathavebeencoveredin
thischapter.ThefollowingpieceofcodeisanexampleofaPL/SQLblockwiththree
SAVEPOINTs.
ForExamplech03_9a.sql
Clickheretoviewcodeimage
BEGIN
INSERTINTOstudent
(student_id,Last_name,zip,registration_date,
created_by,created_date,modified_by,
modified_date
)
VALUES(student_id_seq.nextval,‘Tashi’,10015,
‘01-JAN-99’,‘STUDENTA’,‘01-JAN-99’,
‘STUDENTA’,‘01-JAN-99’
);
SAVEPOINTA;
INSERTINTOstudent
(student_id,Last_name,zip,registration_date,
created_by,created_date,modified_by,
modified_date
)
VALUES(student_id_seq.nextval,‘Sonam’,10015,
‘01-JAN-99’,‘STUDENTB’,‘01-JAN-99’,
‘STUDENTB’,‘01-JAN-99’
);
SAVEPOINTB;
INSERTINTOstudent
(student_id,Last_name,zip,registration_date,
created_by,created_date,modified_by,
modified_date
)
VALUES(student_id_seq.nextval,‘Norbu’,10015,
‘01-JAN-99’,‘STUDENTB’,‘01-JAN-99’,
‘STUDENTB’,‘01-JAN-99’
);
SAVEPOINTC;
ROLLBACKTOB;
END;

IfyouweretorunthefollowingSELECTstatementimmediatelyafterrunningthe
precedingexample,youwouldnotbeabletoseeanydatabecausetheROLLBACKto
(SAVEPOINT)BhasundonethelastinsertstatementwherethestudentNorbuwas
inserted.
SELECT*
FROMstudent
WHERElast_name=‘Norbu’;

Theresultwouldbe“norowsselected.”

ThreestudentswereinsertedinthisPL/SQLblock:firstTashiinSAVEPOINTA,then
SonaminSAVEPOINTB,andfinallyNorbuinSAVEPOINTC.Whenthecommandto
rollbacktoBwasissued,theinsertofNorbuwasundone.
Ifthefollowingcommandwasenteredafterthescriptch03_9a.sql,thentheinsert
inSAVEPOINTBwouldbeundone—thatis,theinsertofSonam:
ROLLBACKtoSAVEPOINTA;

Tashiwastheonlystudentthatwassuccessfullyenteredintothedatabase.The
ROLLBACKtoSAVEPOINTAundidtheinsertstatementsforNorbuandSonam.
BytheWay
SAVEPOINTisoftenusedbeforeacomplicatedsectionofthetransaction.If
thispartofthetransactionfails,itcanberolledback,allowingtheearlierpart
tocontinue.
DidYouKnow?
ItisimportanttonotethedistinctionbetweentransactionsandPL/SQL
blocks.Whenablockstarts,itdoesnotmeanthatthetransactionstarts.
Likewise,thestartofthetransactionneednotcoincidewiththestartofa
block.
HereisanexampleofasinglePL/SQLblockwithmultipletransactions.
ForExamplech03_10a.sql
Clickheretoviewcodeimage
DECLARE
v_CounterNUMBER;
BEGIN
v_counter:=0;
FORiIN1..100
LOOP
v_counter:=v_counter+1;
IFv_counter=10
THEN
COMMIT;
v_counter:=0;
ENDIF;
ENDLOOP;
END;

Inthisexample,assoonasthevalueofv_counterbecomesequalto10,theworkis
committed.Thustherewillbeatotalof10transactionscontainedinthisonePL/SQL
block.

Summary
Inthischapter,youlearnedhowtomakeuseofvariablesandthevariouswaystopopulate
variables.UseofDML(DataManipulationLanguage)withinaPL/SQLblockwas
illustratedinexampleswithinsertstatements.Theseexamplesalsomadeuseofsequences
togenerateuniquenumbers.
ThelastsectionofthechaptercoveredtransactionalcontrolinPL/SQLbyexplaining
whatitmeanstocommitdataaswellashowSAVEPOINTsareused.Thefinalexamples
demonstratedhowcommitteddatacouldbereversedbyusingROLLBACKsinconjunction
withSAVEPOINTs.
BytheWay
Thecompanionwebsiteprovidesadditionalexercisesandsuggestedanswers
forthischapter,withdiscussionrelatedtohowthoseanswersresulted.The
mainpurposeoftheseexercisesistohelpyoutestthedepthofyour
understandingbyutilizingalloftheskillsthatyouhaveacquiredthroughout
thischapter.

4.ConditionalControl:IFStatements
Inthischapter,youwilllearnabout
IFStatements
ELSIFStatements
NestedIFStatements
Inalmosteveryprogramthatyouwrite,youneedtomakedecisions.Forexample,ifitis
theendofthefiscalyear,bonusesmustbedistributedtotheemployeesbasedontheir
salaries.Tocomputeemployeebonuses,aprogramneedstohaveaconditionalcontrol.In
otherwords,itneedstoemployaselectionstructure.
Conditionalcontrolallowsyoutocontroltheflowoftheexecutionoftheprogram
basedonacondition.Inprogrammingterms,itmeansthatthestatementsintheprogram
arenotexecutedsequentially.Rather,onegroupofstatementsoranotherwillbeexecuted
dependingonhowtheconditionisevaluated.
InPL/SQL,therearethreetypesofconditionalcontrol:IF,ELSIF,andCASE
statements.Inthischapter,youwillexploretwotypesofconditionalcontrol—IFand
ELSIF—andlearnhowthesetypescanbenestedinsideofeachother.CASEstatements
arediscussedinChapter5.

Lab4.1:IFStatements
Afterthislab,youwillbeableto
UseIF-THENStatements
UseIF-THEN-ELSEStatements
AnIFstatementhastwoforms:IF-THENandIF-THEN-ELSE.AnIF-THENstatement
allowsyoutospecifyonlyonegroupofactionstotake.Inotherwords,thisgroupof
actionsistakenonlywhenaconditionevaluatestoTRUE.AnIF-THEN-ELSEstatement
allowsyoutospecifytwogroupsofactions,andthesecondgroupofactionsistakenwhen
aconditionevaluatestoFALSEorNULL.

IF-THENStatements
AnIF-THENstatementisthemostbasickindofaconditionalcontrolandhasthe
structureshowninListing4.1.
Listing4.1IF-THENStatementStructure
IFCONDITION
THEN
STATEMENT1;


STATEMENTN;
ENDIF;

ThereservedwordIFmarksthebeginningoftheIFstatement.Statements1through
Nareasequenceofexecutablestatementsthatconsistofoneormoreofthestandard
programmingstructures.TheCONDITIONbetweenthekeywordsIFandTHEN
determineswhetherthesestatementsareexecuted.ENDIFisareservedphrasethat
indicatestheendoftheIF-THENconstruct.ThisflowofthelogicisillustratedinFigure
4.1.

Figure4.1IF-THENStatement
WhenanIF-THENstatementisexecuted,aconditionisevaluatedtoeitherTRUEor
FALSE.IftheconditionevaluatestoTRUE,controlpassestothefirstexecutable
statementoftheIF-THENconstruct.IftheconditionevaluatestoFALSE,controlpasses
tothefirstexecutablestatementaftertheENDIFstatement.
Considerthefollowingexample.Youhavetwonumericvaluesstoredinthevariables
v_num1andv_num2.Youneedtoarrangethesevaluessothatthesmallervalueis
alwaysstoredinv_num1,andthelargervalueisalwaysstoredinthev_num2.
ForExamplech04_1a.sql
Clickheretoviewcodeimage

DECLARE
v_num1NUMBER:=5;
v_num2NUMBER:=3;
v_tempNUMBER;
BEGIN
—ifv_num1isgreaterthanv_num2rearrangetheirvalues
IFv_num1>v_num2
THEN
v_temp:=v_num1;
v_num1:=v_num2;
v_num2:=v_temp;
ENDIF;
—displaythevaluesofv_num1andv_num2
DBMS_OUTPUT.PUT_LINE(‘v_num1=‘||v_num1);
DBMS_OUTPUT.PUT_LINE(‘v_num2=‘||v_num2);
END;

Inthisexample,condition
v_num1>v_num2

evaluatestoTRUEbecause5isgreaterthan3.Next,thevaluesarerearrangedsothat3is
assignedtov_num1and5isassignedtov_num2.Thisstepisdonewiththehelpofthe
thirdvariable,v_temp,whichisusedfortemporarystorage.
Thisexampleproducesthefollowingoutput:
v_num1=3
v_num2=5

IF-THEN-ELSEStatement
AnIF-THENstatementspecifiesthesequenceofstatementstoexecuteonlyifthe
conditionevaluatestoTRUE.WhenthisconditionevaluatestoFALSEorNULL,thereis
nospecialactiontotakeexcepttoproceedwithexecutionoftheprogram.
AnIF-THEN-ELSEstatementenablesyoutospecifytwogroupsofstatements.One
groupofstatementsisexecutedwhentheconditionevaluatestoTRUE.Anothergroupof
statementsisexecutedwhentheconditionevaluatestoFALSEorNULL.Thisstructureis
showninListing4.2.
Listing4.2IF-THEN-ELSEStatementStructure
IFCONDITION
THEN
STATEMENT1;
ELSE
STATEMENT2;
ENDIF;
STATEMENT3;

WhenCONDITIONevaluatestoTRUE,controlispassedtoSTATEMENT1;when
CONDITIONevaluatestoFALSEorNULL,controlispassedtoSTATEMENT2.Afterthe
IF-THEN-ELSEconstructhascompleted,STATEMENT3isexecuted.Thisflowofthe
logicisillustratedinFigure4.2.

Figure4.2IF-THEN-ELSEStatement
DidYouKnow?
TheIF-THEN-ELSEconstructshouldbeusedwhentryingtochoosebetween
twomutuallyexclusiveactions.Considerthefollowingexample:
Clickheretoviewcodeimage
DECLARE
v_numNUMBER:=&sv_user_num;
BEGIN
—testifthenumberprovidedbytheuseriseven
IFMOD(v_num,2)=0
THEN
DBMS_OUTPUT.PUT_LINE(v_num||’isevennumber’);
ELSE
DBMS_OUTPUT.PUT_LINE(v_num||’isoddnumber’);
ENDIF;
END;

ForanygivennumberofDBMS_OUTPUT.PUT_LINEstatements,onlyone
isexecuted.Hence,theIF-THEN-ELSEconstructenablesyoutospecifytwo
andonlytwomutuallyexclusiveactions.
Whenrun,thisexampleproducesthefollowingoutput:
24isevennumber

NullCondition
Insomecases,aconditionusedinanIFstatementmayevaluatetoNULLinsteadof
TRUEorFALSE.FortheIF-THENconstruct,thestatementsassociatedwiththeconstruct
willnotbeexecutedifanassociatedconditionevaluatestoNULL.Instead,controlofthe
executionwillpasstothefirstexecutablestatementafterENDIF.FortheIF-THENELSEconstruct,thestatementsspecifiedafterthekeywordELSEwillbeexecutedifan
associatedconditionevaluatestoNULL.
ForExamplech04_2a.sql
Clickheretoviewcodeimage
DECLARE
v_num1NUMBER:=0;
v_num2NUMBER;
BEGIN
DBMS_OUTPUT.PUT_LINE(‘BeforeIFstatement…’);
IFv_num1=v_num2
THEN
DBMS_OUTPUT.PUT_LINE(‘v_num1=v_num2’);
ENDIF;
DBMS_OUTPUT.PUT_LINE(‘AfterIFstatement…’);
END;

Thisexampleproducesthefollowingoutput:
BeforeIFstatement…
AfterIFstatement…

Thecondition
v_num1=v_num2

evaluatestoNULLbecausevariablev_num2isnotassignedavalue;therefore,itremains
NULL.NoticethattheIF-THENconstructbehavesasiftheconditionevaluatedto
FALSE.Inotherwords,theDBMS_OUTPUT.PUT_LINEstatementassociatedwiththe
IF-THENconstructdoesnotexecute.
Next,considerasimilarexamplethatemploystheIF-THEN-ELSEconstruct(the
newlyaddedstatementsareshowninbold).
ForExamplech04_2b.sql
Clickheretoviewcodeimage
DECLARE
v_num1NUMBER:=0;
v_num2NUMBER;
BEGIN
DBMS_OUTPUT.PUT_LINE(‘BeforeIFstatement…’);
IFv_num1=v_num2
THEN
DBMS_OUTPUT.PUT_LINE(‘v_num1=v_num2’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘v_num1!=v_num2’);
ENDIF;
DBMS_OUTPUT.PUT_LINE(‘AfterIFstatement…’);
END;