About This eBook - irantuto.comirantuto.com/upload/Oracle/books/oracle_pl_sql_in_10_minutes.pdfAbout...

Post on 26-May-2018

220 views 0 download

Transcript of About This eBook - irantuto.comirantuto.com/upload/Oracle/books/oracle_pl_sql_in_10_minutes.pdfAbout...

AboutThiseBook

ePUBisanopen,industry-standardformatforeBooks.However,supportofePUBanditsmanyfeaturesvariesacrossreadingdevicesandapplications.Useyourdeviceorappsettingstocustomizethepresentationtoyourliking.Settingsthatyoucancustomizeoftenincludefont,fontsize,singleordoublecolumn,landscapeorportraitmode,andfiguresthatyoucanclickortaptoenlarge.Foradditionalinformationaboutthesettingsandfeaturesonyourreadingdeviceorapp,visitthedevicemanufacturer’sWebsite.

Manytitlesincludeprogrammingcodeorconfigurationexamples.Tooptimizethepresentationoftheseelements,viewtheeBookinsingle-column,landscapemodeandadjustthefontsizetothesmallestsetting.Inadditiontopresentingcodeandconfigurationsinthereflowabletextformat,wehaveincludedimagesofthecodethatmimicthepresentationfoundintheprintbook;therefore,wherethereflowableformatmaycompromisethepresentationofthecodelisting,youwillseea“Clickheretoviewcodeimage”link.Clickthelinktoviewtheprint-fidelitycodeimage.Toreturntothepreviouspageviewed,clicktheBackbuttononyourdeviceorapp.

SamsTeachYourselfOracle®PL/SQL

in10MinutesBenForta

800East96thStreet,Indianapolis,Indiana46240

SamsTeachYourselfOracle®PL/SQLin10Minutes

Copyright©2016byPearsonEducation,Inc.

Allrightsreserved.Nopartofthisbookshallbereproduced,storedinaretrievalsystem,ortransmittedbyanymeans,electronic,mechanical,photocopying,recording,orotherwise,withoutwrittenpermissionfromthepublisher.Nopatentliabilityisassumedwithrespecttotheuseoftheinformationcontainedherein.Althougheveryprecautionhasbeentakeninthepreparationofthisbook,thepublisherandauthorassumenoresponsibilityforerrorsoromissions.Norisanyliabilityassumedfordamagesresultingfromtheuseoftheinformationcontainedherein.

ISBN-13:978-0-672-32866-4ISBN-10:0-672-32866-6

LibraryofCongressControlNumber:2015910491

PrintedintheUnitedStatesofAmerica

FirstPrintingSeptember2015

AcquisitionsEditorMarkTaber

ManagingEditorKristyHart

SeniorProjectEditorBetsyGratner

CopyEditorPaulaLowell

IndexerLisaStumpf

ProofreaderSarahKearns

EditorialAssistantVanessaEvans

CoverDesignerMarkShirar

SeniorCompositorGloriaSchurick

Trademarks

Alltermsmentionedinthisbookthatareknowntobetrademarksorservicemarkshavebeenappropriatelycapitalized.SamsPublishingcannotattesttotheaccuracyofthisinformation.Useofaterminthisbookshouldnotberegardedasaffectingthevalidityofanytrademarkorservicemark.

WarningandDisclaimer

Everyefforthasbeenmadetomakethisbookascompleteandasaccurateaspossible,butnowarrantyorfitnessisimplied.Theinformationprovidedisonan“asis”basis.Theauthorandthepublishershallhaveneitherliabilitynorresponsibilitytoanypersonorentitywithrespecttoanylossordamagesarisingfromtheinformationcontainedinthisbookorfromtheuseoftheprogramsaccompanyingit.

SpecialSales

Forinformationaboutbuyingthistitleinbulkquantities,orforspecialsalesopportunities(whichmayincludeelectronicversions;customcoverdesigns;andcontentparticulartoyourbusiness,traininggoals,marketingfocus,orbrandinginterests),pleasecontactourcorporatesalesdepartmentatcorpsales@pearsoned.comor(800)382-3419.

Forgovernmentsalesinquiries,pleasecontactgovernmentsales@pearsoned.com.

ForquestionsaboutsalesoutsidetheU.S.,pleasecontactinternational@pearsoned.com.

Contents

Introduction

WhatIsThisBook?

WhoIsThisBookFor?

CompanionWebsite

ConventionsUsedinThisBook

1UnderstandingSQL

DatabaseBasics

WhatIsSQL?

TryItYourself

Summary

2GettingStartedwithOracleandPL/SQL

WhatIsOracle?

GettingSetUp

Summary

3WorkingwithOracle

CreatingaWorkingEnvironment

MakingtheConnection

AQuickIntroductiontoOracleSQLDeveloper

CreatingandPopulatingtheExampleTables

OneMoreLookatOracleSQLDeveloper

Summary

4RetrievingData

TheSELECTStatement

RetrievingIndividualColumns

RetrievingMultipleColumns

RetrievingAllColumns

RetrievingDistinctRows

UsingFullyQualifiedTableNames

UsingComments

Summary

5SortingRetrievedData

SortingData

SortingbyMultipleColumns

SpecifyingSortDirection

Summary

6FilteringData

UsingtheWHEREClause

TheWHEREClauseOperators

Summary

7AdvancedDataFiltering

CombiningWHEREClauses

UsingtheINOperator

UsingtheNOTOperator

Summary

8UsingWildcardFiltering

UsingtheLIKEOperator

TipsforUsingWildcards

Summary

9SearchingUsingRegularExpressions

UnderstandingRegularExpressions

UsingOraclePL/SQLRegularExpressions

Summary

10CreatingCalculatedFields

UnderstandingCalculatedFields

ConcatenatingFields

PerformingMathematicalCalculations

Summary

11UsingDataManipulationFunctions

UnderstandingFunctions

UsingFunctions

Summary

12SummarizingData

UsingAggregateFunctions

AggregatesonDistinctValues

CombiningAggregateFunctions

Summary

13GroupingData

UnderstandingDataGrouping

CreatingGroups

FilteringGroups

GroupingandSorting

SELECTClauseOrdering

Summary

14WorkingwithSubqueries

UnderstandingSubqueries

FilteringbySubquery

UsingSubqueriesasCalculatedFields

Summary

15JoiningTables

UnderstandingJoins

CreatingaJoin

Summary

16CreatingAdvancedJoins

UsingTableAliases

UsingDifferentJoinTypes

UsingJoinswithAggregateFunctions

UsingJoinsandJoinConditions

Summary

17CombiningQueries

UnderstandingCombinedQueries

CreatingCombinedQueries

Summary

18InsertingData

UnderstandingDataInsertion

InsertingCompleteRows

InsertingRetrievedData

Summary

19UpdatingandDeletingData

UpdatingData

DeletingData

GuidelinesforUpdatingandDeletingData

Summary

20CreatingandManipulatingTables

CreatingTables

UpdatingTables

DeletingTables

RenamingTables

Summary

21UsingViews

UnderstandingViews

UsingViews

Summary

22WorkingwithStoredProcedures

UnderstandingStoredProcedures

WhyUseStoredProcedures

UsingStoredProcedures

Summary

23UsingCursors

UnderstandingCursors

WorkingwithCursors

Summary

24UsingTriggers

UnderstandingTriggers

CreatingTriggers

DroppingTriggers

UsingTriggers

Summary

25ManagingTransactionProcessing

UnderstandingTransactionProcessing

ControllingTransactions

Summary

26ManagingSecurity

UnderstandingAccessControl

ManagingUsers

Summary

ATheExampleTables

UnderstandingtheSampleTables

BOraclePL/SQLDatatypes

StringDatatypes

NumericDatatypes

COraclePL/SQLReservedWordsandKeywords

Index

AbouttheAuthor

BenFortahasthreedecadesofexperienceinthecomputerindustryinproductdesignanddevelopment,support,training,andmarketing.AsAdobeInc.’sSeniorDirectorofEducationInitiatives,hespendsaconsiderableamountoftimeteaching,talking,andwritingaboutAdobeproducts,codingandapplicationdevelopment,creativity,anddigitalliteracyandprovidesfeedbacktohelpshapethefuturedirectionofAdobeproducts.

Benistheauthorofmorethan40books,includingtheworld’sbestsellingtitleonSQL,aswellastitlesontopicsasdiverseasRegularExpressions,mobiledevelopment,andAdobeColdFusion.Morethan750,000copiesofhisbooksareinprintinEnglish,andtitleshavebeentranslatedintofifteenlanguages.Manyofthesetitlesareusedastextbooksincollegesanduniversitiesworldwide.

EducationisBen’spassion.Betweenwriting,lecturing,andin-classroomexperience,Benhasdedicatedhisprofessionalandpersonallivestoteaching,inspiring,andsharinghislovefortechnologyandcreativity.Heisimmenselygratefultohavehadtheopportunitytosharewithmillionsworldwide.

Benisalsoasuccessfulentrepreneurwithexperiencecreating,building,andsellingstart-ups.Heisasought-afterpublicspeaker,awriter,andablogger,andhepresentsoneducationanddevelopmenttopicsworldwide.

Acknowledgments

It’sbeensixteenyearssincethepublicationofmyfirstbookonSQL,SamsTeachYourselfSQLin10Minutes.Thatbookwasmetwithsuchpositivefeedbackthatithasbeenupdatedthreetimes,hasspawnedfourspin-offtitles(themostrecentbeingthebookyouarereadingrightnow),andhasbeentranslatedmorethanadozentimes.Inallofitsvariousflavorsanditerations,thislittlebookhashelpedhundredsofthousandslearnthebasicsofSQL.So,firstandforemost,thankstoallofyouwhohavetrustedmeandthisbookovertheyears;yoursupportisbothincrediblyhumblingandasourceofgreatpride.

Iamblessedwithsomeveryvocalandopinionatedreaderswhoregularlyshareideas,comments,suggestions,andoccasionallycriticism.Thesebookscontinuetoimprovedirectlyinresponsetothatfeedback,sothanks,andpleasekeepitcoming.

Thankstothenumerousschoolsandcollegestheworldoverwhohavemadethisseriespartoftheircurriculum.Seeingstudentsusemywritingaspartoftheirstudiesneverceasestothrill.

Andfinally,thankstomypartnersatPearsonwithwhomI’venowpublishedmorethan40titles,andwithoutwhosesupportnonewouldhaveseenthelightofday.Inparticular,thankstoBetsyGratnerforshepherdingthisbookthroughtheprocess,PaulaLowellforhereditinghelp,andMarkTaberforonceagainpatientlyandencouraginglysupportingwhateverItosshisway.

BenForta

WeWanttoHearfromYou!

Asthereaderofthisbook,youareourmostimportantcriticandcommentator.Wevalueyouropinionandwanttoknowwhatwe’redoingright,whatwecoulddobetter,whatareasyou’dliketoseeuspublishin,andanyotherwordsofwisdomyou’rewillingtopassourway.

Wewelcomeyourcomments.Youcanemailorwritetoletusknowwhatyoudidordidn’tlikeaboutthisbook—aswellaswhatwecandotomakeourbooksbetter.

Pleasenotethatwecannothelpyouwithtechnicalproblemsrelatedtothetopicofthisbook.

Whenyouwrite,pleasebesuretoincludethisbook’stitleandauthoraswellasyournameandemailaddress.Wewillcarefullyreviewyourcommentsandsharethemwiththeauthorandeditorswhoworkedonthebook.

Email:feedback@samspublishing.com

Mail:SamsPublishingATTN:ReaderFeedback800East96thStreetIndianapolis,IN46240USA

ReaderServices

Visitourwebsiteandregisterthisbookatinformit.com/registerforconvenientaccesstoanyupdates,downloads,orerratathatmightbeavailableforthisbook.

Introduction

OracleDatabase(orOracleRDBMS)issoprevalentandwellestablishedthatmostuserssimplerefertoitas“Oracle”(ignoringthefactthatOracle,thecompany,producesothersoftware,andevenhardware).OracleDatabase(I’lldowhatmostdoandjustcallit“Oracle”tosimplifythings)hasbeenaroundsincethe1970s,makingitoneoftheearliestdatabasemanagementsystems.Oracleisoneofthemostuseddatabasemanagementsystems(DBMS)intheworld.Infact,mostsurveysrankitas#1indatabaseuseandpopularityworldwide,especiallyamongcorporateusers,andovertheyearsithasprovenitselftobeasolid,reliable,fast,andtrustedsolutiontoallsortsofdatastorageneeds.

That’sthegoodnews.Thenot-so-goodnewsisthatgettingstartedwithOraclecanbetricky,especiallywhencomparedtosomeofthealternativeDBMSs.Oracle’spower,capabilities,security,andmoreareanimportantpartofwhyitissotrusted.Butthatmakesinstallation,configuration,andeventhetoolingalittlemorecomplex,too.Ontopofthat,Oracle’simplementationoftheSQLlanguage,calledPL/SQL,tendstodiffersubtlyfromotherSQLimplementations,andthiscanmakeusingOraclejustabittrickier.

WhatIsThisBook?Thisbookisbasedonmybest-sellingSamsTeachYourselfSQLin10Minutes.ThatbookhasbecomeoneofthemostusedSQLtutorialsintheworld,withanemphasisonteachingwhatyoureallyneedtoknow—methodically,systematically,andsimply.However,aspopularandassuccessfulasthatbookis,itdoeshavesomelimitations:

IncoveringallthemajorDBMSs,coverageofDBMS-specificfeaturesandfunctionalityhadtobekepttoaminimum.

TosimplifytheSQLtaught,thelowestcommondenominatorhadtobefound—SQLstatementsthatwould(asmuchaspossible)workwithallmajorDBMSs.ThisrequirementnecessitatedthatbetterDBMS-specificsolutionsnotbecovered.

AlthoughbasicSQLtendstoberatherportablebetweenDBMSs,moreadvancedSQLmostdefinitelyisnot.Assuch,thatbookcouldnotcoveradvancedtopics,suchastriggers,cursors,storedprocedures,accesscontrol,transactions,andmore,inanyrealdetail.

Andthatiswherethisbookcomesin.SamsTeachYourselfOraclePL/SQLin10MinutesbuildsontheproventutorialsandstructureofSamsTeachYourselfSQLinTenMinutes,withoutgettingboggeddownwithanythingbutOracleandPL/SQL.Startingwithsimpledataretrievalandworkingtowardmorecomplextopics,includingtheuseofjoins,subqueries,regularexpressions,fulltext-basedsearches,storedprocedures,cursors,triggers,tableconstraints,andmuchmore.You’lllearnwhatyouneedtoknowmethodically,systematically,andsimply—inhighlyfocusedlessonsdesignedtomakeyouimmediatelyandeffortlesslyproductive.

WhoIsThisBookFor?Thisbookisforyouif

YouarenewtoSQL.

YouarejustgettingstartedwithOraclePL/SQLandwanttohitthegroundrunning.

YouwanttoquicklylearnhowtogetthemostoutofOracleandPL/SQL.

YouwanttolearnhowtouseOracleinyourownapplicationdevelopment.

YouwanttobeproductivequicklyandeasilyusingOraclewithouthavingtocallsomeoneforhelp.

Itisworthnotingthatthisbookisnotintendedforallreaders.IfyouareanexperiencedSQLuser,thenyoumightfindthecontentinthisbooktobetooelementary.However,iftheprecedinglistdescribesyouandyourneedsrelativetoOracle,you’llfindSamsTeachYourselfOraclePL/SQLin10MinutestobethefastestandeasiestwaytogetuptospeedwithOracle.

CompanionWebsiteThisbookhasacompanionwebsiteatforta.com/books/0672328666.Visitthesiteto

Accesstablecreationandpopulationscriptsforcreatingtheexampletablesusedthroughoutthisbook

Visittheonlinesupportforum

Accessonlineerrata(ifonemightberequired)

Findotherbooksthatmightbeofinteresttoyou

ConventionsUsedinThisBookThisbookusesdifferenttypefacestodifferentiatebetweencodeandregularEnglish,andalsotohelpyouidentifyimportantconcepts.

Textthatyoutypeandtextthatshouldappearonyourscreenappearsinmonospacetype.Itlookslikethistomimicthewaytextlooksonyourscreen.

Placeholdersforvariablesandexpressionsappearinmonospaceitalicfont.Youshouldreplacetheplaceholderwiththespecificvalueitrepresents.

Thisarrow( )atthebeginningofalineofcodemeansthatasinglelineofcodeistoolongtofitontheprintedpage.Continuetypingallthecharactersafterthe asiftheywerepartoftheprecedingline.

Note

ANotepresentsinterestingpiecesofinformationrelatedtothesurroundingdiscussion.

Tip

ATipoffersadviceorteachesaneasierwaytodosomething.

Caution

ACautionadvisesyouaboutpotentialproblemsandhelpsyousteerclearofdisaster.

NewTermsidebarsprovidecleardefinitionsofnew,essentialterms.

Input

TheInputiconidentifiescodethatyoucantypeinyourself.Itusuallyappearsbyalisting.

Output

TheOutputiconhighlightstheoutputproducedbyrunningOraclePL/SQLcode.Itusuallyappearsafteralisting.

Analysis

TheAnalysisiconalertsyoutotheauthor’sline-by-lineanalysisofinputoroutput.

Lesson1.UnderstandingSQL

Inthislesson,you’lllearnaboutdatabasesandSQL,prerequisitestolearningaboutOracleandPL/SQL.

DatabaseBasicsThefactthatyouarereadingthisbookindicatesthatyou,somehow,needtointeractwithdatabases.AndsobeforedivingintoOracleanditsimplementationoftheSQLlanguage(PL/SQL),itisimportantthatyouunderstandsomebasicconceptsaboutdatabasesanddatabasetechnologies.

Whetheryouareawareofitornot,youusedatabasesallthetime.Eachtimeyouselectanamefromyouremailorsmartphoneaddressbook,youuseadatabase.WhenyouconductasearchonanInternetsearchsite,youuseadatabase.Whenyoulogintoyournetworkatwork,youvalidateyournameandpasswordagainstadatabase.EvenwhenyouuseyourATMcardatacashmachine,youusedatabasesforPINverificationandbalancechecking.

Buteventhoughweallusedatabasesallthetime,muchconfusionremainsaboutwhatexactlyadatabaseis.Thisisespeciallytruebecausedifferentpeopleusethesamedatabasetermstomeandifferentthings.Therefore,agoodplacetostartourstudyiswithalistandexplanationofthemostimportantdatabaseterms.

Tip:ReviewingBasicConcepts

Whatfollowsisabriefoverviewofsomebasicdatabaseconcepts.Itisintendedtoeitherjoltyourmemoryifyoualreadyhavesomedatabaseexperience,ortoprovideyouwiththeabsolutebasicsifyouarenewtodatabases.UnderstandingdatabasesisanimportantpartofmasteringOracle,andyoumightwanttofindagoodbookondatabasefundamentalstobrushuponthesubjectifneeded.

WhatIsaDatabase?Thetermdatabaseisusedinmanydifferentways,butforourpurposesadatabaseisacollectionofdatastoredinsomeorganizedfashion.Thesimplestwaytothinkofitistoimagineadatabaseasafilingcabinet.Thefilingcabinetissimplyaphysicallocationtostoredata,regardlessofwhatthatdataisorhowitisorganized.

Database

Acontainer(usuallyafileorsetoffiles)tostoreorganizeddata.

Caution:MisuseCausesConfusion

Peopleoftenusethetermdatabasetorefertothedatabasesoftwaretheyarerunning.Thisisincorrect,anditisasourceofmuchconfusion.DatabasesoftwareisactuallycalledtheDatabaseManagementSystem(orDBMS).ThedatabaseisthecontainercreatedandmanipulatedviatheDBMS.Adatabasemightbeafilestoredonaharddrive,butitmightnot.Forthemostpart,thisisnotevensignificantbecauseyouneveraccessadatabasedirectlyanyway;youalwaysusetheDBMSanditaccessesthedatabaseforyou.

TablesWhenyoustoreinformationinyourfilingcabinet,youdon’tjusttossitinadrawer.Rather,youcreatefileswithinthefilingcabinet,andthenyoufilerelateddatainspecificfiles.

Inthedatabaseworld,thatfileiscalledatable.Atableisastructuredfilethatcanstoredataofaspecifictype.Atablemightcontainalistofcustomers,aproductcatalog,oranyotherlistofinformation.

Table

Astructuredlistofdataofaspecifictype.

Thekeyhereisthatthedatastoredinthetableisonetypeofdataoronelist.Youwouldneverstorealistofcustomersandalistofordersinthesamedatabasetable.Doingsowouldmakesubsequentretrievalandaccessdifficult.Rather,youwouldcreatetwotables,oneforeachlist.

Everytableinadatabasehasanamethatidentifiesit.Thatnameisalwaysunique—meaningnoothertableinthatdatabasecanhavethesamename.

Note:TableNames

Whatmakesatablenameuniqueisactuallyacombinationofseveralthings,includingthedatabasenameandtablename.Thismeansthatalthoughyoucannotusethesametablenametwiceinthesamedatabase,youdefinitelycanreusetablenamesindifferentdatabases.

Tableshavecharacteristicsandpropertiesthatdefinehowdataisstoredinthem.Theseincludeinformationaboutwhatdatamaybestored,howitisbrokenup,howindividualpiecesofinformationarenamed,andmuchmore.Thissetofinformationthatdescribesatableisknownasaschema,andschemadescribespecifictableswithinadatabase,aswellasentiredatabases(andtherelationshipbetweentablesinthem,ifany).

Schema

Informationaboutdatabaseandtablelayoutandproperties.

Note:SchemaorDatabase?

Occasionallyschemaisusedasasynonymfordatabase(andschemataasasynonymfordatabases).Whileunfortunate,itisusuallyclearfromthecontextwhichmeaningofschemaisintended.Inthisbook,schemareferstotheaforementioneddefinition.

ColumnsandDatatypesTablesaremadeupofcolumns.Acolumncontainsaparticularpieceofinformationinatable.

Column

Asinglefieldinatable.Alltablesaremadeupofoneormorecolumns.

Thebestwaytounderstandacolumnistoenvisiondatabasetablesasgrids,somewhatlikespreadsheets.Eachcolumninthegridcontainsaparticularpieceofinformation.Inacustomertable,forexample,onecolumncontainsthecustomernumber,anothercontainsthecustomername,andtheaddress,city,state,andZipCodeareallstoredintheirowncolumns.

Tip:BreakingUpData

Itisextremelyimportanttobreakdataintomultiplecolumnscorrectly.Forexample,city,state,andZipCodeshouldalwaysbeseparatecolumns.Bybreakingtheseout,itbecomespossibletosortorfilterdatabyspecificcolumns(forexample,tofindallcustomersinaparticularstateorinaparticularcity).Ifcityandstatearecombinedintoonecolumn,itwouldbeextremelydifficulttosortorfilterbystate.

Eachcolumninadatabasehasanassociateddatatype.Adatatypedefineswhattypeofdatathecolumncancontain.Forexample,ifthecolumnistocontainanumber(perhapsthenumberofitemsinanorder),thedatatypewouldbeanumericdatatype.Ifthecolumnweretocontaindates,text,notes,currencyamounts,andsoon,theappropriatedatatypewouldbeusedtospecifythis.

Datatype

Atypeofalloweddata.Everytablecolumnhasanassociateddatatypethatrestricts(orallows)specificdatainthatcolumn.

Datatypesrestrictthetypeofdatathatacolumncanstore(forexample,preventingtheentryofalphabeticalcharactersintoanumericfield).Datatypesalsohelpsortdatacorrectly,andplayanimportantroleinoptimizingdiskusage.Assuch,youmustgivespecialattentiontopickingtherightdatatypewhencreatingtables.

RowsDatainatableisstoredinrows;eachrecordsavedisstoredinitsownrow.Again,envisioningatableasaspreadsheetstylegrid,theverticalcolumnsinthegridarethetablecolumns,andthehorizontalrowsarethetablerows.

Forexample,acustomer’stablemightstoreonecustomerperrow.Thenumberofrowsinthetableisthenumberofrecordsinit.

Row

Arecordinatable.

Note:RecordsorRows?

Youmighthearusersrefertodatabaserecordswhenreferringtorows.Forthemostpart,peopleusethetwotermsinterchangeably,butrowistechnicallythecorrectterm.

PrimaryKeysEveryrowinatableshouldhavesomecolumn(orsetofcolumns)thatuniquelyidentifiesit.Atablecontainingcustomersmightuseacustomernumbercolumnforthispurpose,whereasatablecontainingordersmightusetheorderID.AnemployeelisttablemightuseanemployeeIDortheemployeeSocialSecurityNumbercolumn.

PrimaryKey

Acolumn(orsetofcolumns)whosevaluesuniquelyidentifyeveryrowinatable.

Thiscolumn(orsetofcolumns)thatuniquelyidentifieseachrowinatableiscalledaprimarykey.Youusetheprimarykeytorefertoaspecificrow.Withoutaprimarykey,updatingordeletingspecificrowsinatablebecomesextremelydifficultbecausenoguaranteedsafewayexiststorefertojusttherowstobeaffected.

Tip:AlwaysDefinePrimaryKeys

Althoughprimarykeysarenotactuallyrequired,mostdatabasedesignersensurethateverytabletheycreatehasaprimarykeysofuturedatamanipulationispossibleandmanageable.

Youcanestablishanycolumninatableastheprimarykey,aslongasitmeetsthefollowingconditions:

Notworowscanhavethesameprimarykeyvalue.

Everyrowmusthaveaprimarykeyvalue(primarykeycolumnsmaynotallowNULLvalues).

Tip:PrimaryKeyRules

TheruleslistedhereareenforcedbyOracleitself.

Youusuallydefineprimarykeysonasinglecolumninatable.Butthisisnotrequired,andyoumayusemultiplecolumnstogetherasaprimarykey.Whenyouusemultiplecolumns,therulespreviouslylistedmustapplytoallcolumnsthatmakeuptheprimarykey,andthevaluesofallcolumnstogethermustbeunique(individualcolumnsneednothaveuniquevalues).

Tip:PrimaryKeyBestPractices

InadditiontotherulesthatOracleenforces,severaluniversallyacceptedbestpracticesthatyoushouldadheretoincludethefollowing:

Don’tupdatevaluesinprimarykeycolumns.

Don’treusevaluesinprimarykeycolumns.

Don’tusevaluesthatmightchangeinprimarykeycolumns.(Forexample,whenyouuseanameasaprimarykeytoidentifyasupplier,youwouldhavetochangetheprimarykeywhenthesuppliermergesandchangesitsname.)

Anotherimportanttypeofkeyistheforeignkey,butI’llgettothatlateroninLesson15,“JoiningTables.”

WhatIsSQL?SQL(pronouncedasthelettersS-Q-Lorassequel)isanabbreviationforStructuredQueryLanguage.SQLisalanguagedesignedspecificallyforcommunicatingwithdatabases.

Unlikeotherlanguages(spokenlanguagessuchasEnglish,orprogramminglanguagessuchasC,Java,orPython),SQLismadeupofveryfewwords.Thisisdeliberate.SQLisdesignedtodoonethinganddoitwell—provideyouwithasimpleandefficientwaytoreadandwritedatafromadatabase.

WhataretheadvantagesofSQL?

SQLisnotaproprietarylanguageusedbyspecificdatabasevendors.AlmosteverymajorDBMSsupportsSQL,solearningthisonelanguageenablesyoutointeractwithjustabouteverydatabaseyou’llruninto.

SQLiseasytolearn.ThestatementsareallmadeupofdescriptiveEnglishwords,andtherearen’tthatmanyofthem.

Despiteitsapparentsimplicity,SQLisaverypowerfullanguage,andbycleverlyusingitslanguageelements,youcanperformcomplexandsophisticateddatabaseoperations.

Note:DBMS-SpecificSQL

AlthoughSQLisnotaproprietarylanguageandastandardscommitteeexiststhattriestodefineSQLsyntaxthatallDBMSscanuse,therealityisthatnotwoDBMSsimplementSQLidentically.TheSQLtaughtinthisbookisspecifictoOracle,andalthoughmuchofthelanguagetaughtisusablewithotherDBMSs,donotassumecompleteSQLsyntaxportability.

TryItYourselfAllthelessonsinthisbookuseworkingexamples,showingyoutheSQLsyntax,whatitdoes,andexplainingwhyitdoesit.IstronglysuggestthatyoutryeachandeveryexampleforyourselftolearnOraclefirsthand.

Note:YouNeedOracle

Obviously,you’llneedaccesstoanOracleDBMStofollowalong.InLesson2,“GettingStartedwithOracleandPL/SQL,”Iexplainexactlywhatyouneed,andpresentseveralinstallationandconfigurationoptionsthatyoucanuse.

SummaryInthisfirstlesson,youlearnedwhatSQLisandwhyitisuseful.BecauseSQLisusedtointeractwithdatabases,youalsoreviewedsomebasicdatabaseterminology.

Lesson2.GettingStartedwithOracleandPL/SQL

Inthislesson,you’lllearnwhatOracleandPL/SQLare,andwhattoolsyoucanusetoworkwiththem.

WhatIsOracle?Inthepreviouslesson,youlearnedaboutdatabasesandSQL.Asexplained,itisthedatabasesoftware(DBMSorDatabaseManagementSystem)thatactuallydoesalltheworkofstoring,retrieving,managing,andmanipulatingdata.OracleDBMS(orjust“Oracle”)isaDBMS;thatis,itisdatabasesoftware.

Oraclehasbeenaroundforalongtime.ThefirstversionoftheDBMSwasreleasedinthe1970s,andithasbeenupdatedandimprovedregularlyeversince.Thecurrent(asofthetimethisbookgoestoprint)versionofOracleis12c,whichwasreleasedin2013(the“c”in12cstandsfor“cloud”).OracleisoneofthemostdeployedandusedDBMSs,especiallywithincorporatesystemsandinfrastructures.

Client-ServerSoftwareDBMSsfallintotwocategories:sharedfile–basedandclient-server.Theformer(whichincludeproductssuchasMicrosoftAccessandFileMaker)aredesignedfordesktopuse,andaregenerallynotintendedforuseonhigher-endormorecriticalapplications(includingwebsitesandweb-basedapplications).

DatabasessuchasOracle,MySQL(anditsoffshootMariaDB),andMicrosoftSQLServerareclient-server–baseddatabases.Client-serverapplicationsaresplitintotwodistinctparts.Theserverportionisapieceofsoftwarethatisresponsibleforalldataaccessandmanipulation.Thissoftwarerunsonacomputercalledthedatabaseserver.

Onlytheserversoftwareinteractswiththedatafiles.Allrequestsfordata,dataadditionsanddeletions,anddataupdatesarefunneledthroughtheserversoftware.Theserequestsorchangescomefromcomputersrunningclientsoftware.Theclientisthepieceofsoftwarewithwhichtheuserinteracts.Ifyourequestanalphabeticallistofproducts,forexample,theclientsoftwaresubmitsthatrequestoverthenetworktotheserversoftware.Theserversoftwareprocessestherequest;filters,discards,andsortsdataasnecessary;andsendstheresultsbacktoyourclientsoftware.

Note:HowManyComputersDoYouNeed?

Theclientandserversoftwaremaybeinstalledontwocomputersorononecomputer.Regardless,theclientsoftwarecommunicateswiththeserversoftwareforalldatabaseinteraction,beitonthesamemachineornot.

Allthisactionoccurstransparentlytoyou,theuser.Thefactthatdataisstoredelsewhereorthatadatabaseserverisevenperformingallthisprocessingforyouishidden.Youneverneedtoaccessthedatafilesdirectly.Infact,mostnetworksaresetupsothatusershavenoaccesstothedata,oreventhedrivesonwhichitisstored.

Whyisthissignificant?BecausetoworkwithOracle,youneedaccesstobothacomputerrunningtheOracleserversoftwareandclientsoftwarewithwhichtoissuecommandstoOracle:

TheserversoftwareistheOracleDBMS.Youcanrunalocallyinstalledcopy,oryoucanconnecttoacopyrunningaremoteservertowhichyouhaveaccess.

TheclientcanbeOracle-providedtools,scriptinglanguages(suchasPythonandPerl),webapplicationdevelopmentlanguages(suchasPHP,JSP,andASP),programminglanguages(suchasC,C++,andJava),andmore.

Note:Clients?Servers?WhyShouldICare?

ThereasonIpointthisoutisthatclient-serversoftware,bydesign,isalittlemorecomplextogetstartedwith.Whenyouuseawordprocessororspreadsheet,youopentheapplicationonyourcomputeranditworkswithlocaldata.Client-serverdatabasesoftwaredoesn’tworkthatway.Productionserversusuallyrunindatacentersthatusersneveraccessdirectly,sothecomputersrunningtheserversoftwareseldomhaveclienttoolsonthem.Similarly,whenworkingwiththesedatabases,userstypicallyuselocaltoolsconnectedtoremoteproductionservers,sotheywouldhaveclienttoolsinstalledlocallybutnotaserver.Assuch,beforethoseclienttoolscanbeused,theymustbeconfiguredsothattheycanaccesstheremoteserver.Thisistrueevenifboththeserverandclienttoolsareindeedonthesamemachine,asyouwillseeshortly.

PL/SQLAsInotedinLesson1,“UnderstandingSQL,”allSQLimplementationsarenotcreatedequal.Thisisunfortunate;itwouldbeidealifyoucouldlearnandwriteSQLforoneDBMSandhaveitrunas-isonanyother.InearlySQLdays,thiswasactuallymorelikely,butovertheyearsDBMSvendorshaveneededtoaddfeaturesandfunctionalitybeyondthatsupportedbystandardSQL,andsotheycreatedtheirownvariantsoftheSQLlanguage.

PL/SQLstandsforProceduralLanguage/StructuredQueryLanguage,andPL/SQLisOracle’simplementationofSQL(andhasbeensinceOracleversion7).TheSQLyouwilllearninthisbookisPL/SQL,whichmeansthatitisintendedforusewithOracleonly.Mostofwhatyou’lllearn,especiallyintheearlierlessons,isquiteapplicabletootherDBMSs,butthisdefinitelyisnotthecaselaterinthebook.

ClientToolsAsalreadyexplained,Oracleisaclient-serverdatabase,andtouseit,you’llneedclientsoftware(theprogramyouusetoactuallyrunSQLcommands).Lotsofoptionsexistinregardtoclientsoftware,butyoushouldbeawareofthesetwoOracleoptionsspecifically:

AllOracleserverinstallationsincludeacommand-linetoolcalledSQL*Plus.ThisbasicclientsimplydisplaysaSQL>promptinatextwindow,allowingyoutoenter

commandsandinstructionstotheOracleserver.

OraclealsoprovidesafreegraphicalclientcalledOracleSQLDeveloper(itmightshowupnamedjust“SQLDeveloper”whenyouinstallitonyourcomputer).OracleSQLDeveloperletsyouinteractivelyconnecttoanduseyourOracleserverandisamuchbetteroptionfordailyOracleuse,especiallyforbeginners.

Althoughyouarefreetouseanyclienttoolyouwant(thePL/SQLyouusewillalwaysbethesameregardlessofclienttool),IhighlyrecommendusingOracleSQLDeveloperasyourfirsttool,andtheinstructionsinthisbookassumethatyouaredoingjustthat.

GettingSetUpAsyounowknow,tostartusingOracle,andtofollowalongwiththelessonsinthisbook,youneedaccesstoanOracleDBMS(or“OracleServer”)andclientapplications(softwareusedtoaccesstheserver).

WhatSoftwareDoYouNeed?YoudonotneedyourowninstalledOracleserver,butyoudoneedaccesstoone.Youbasicallyhavetwooptions:

AccesstoanexistingOracleDBMS,perhapsonebyyourhostingcompanyorplaceofbusinessorschool.Tousethisserver,youwillbegrantedaserveraccount(aloginnameandpassword).

YoumaydownloadandinstallyourowncopyofOracleforinstallationonyourowncomputer.OraclerunsonmajorplatformsincludingWindowsandLinux,butnolongeronMacOS.However,thatdoesnotmeanthatMacuserscan’tlearnanduseOraclePL/SQL.

Note:ImportantNoteforMacUsers

OraclehasstoppedofficiallysupportingMacOSasaserverplatform.IfyouareaMacOSuser,youcaninstalltheclientsoftwareanduseittoconnecttoaremoteOracledatabaseserver,butyouwon’tbeabletoinstalltheOracleDBMSitselfonyourMac(well,atleastnoteasilyorusinganydocumentedoptions).Assuch,Macusersmustoptforthefirstofthetwooptionsnotedpreviously.

Tip:IfYouCan,InstallaLocalServer

Forcompletecontrol,includingaccesstocommandsandfeaturesthatyouwillprobablynotbegrantedbyusingsomeoneelse’sOracleDBMS,installyourownlocalserver.Evenifyoudon’tendupusingyourlocalserverasyourfinalproductionDBMS,you’llstillbenefitfromhavingcompleteandunfetteredaccesstoalltheserverhastooffer.

IfyouwillbeusinganexistinghostedOracleserver,thenyoudon’tneedtoworryaboutwhatversionitis,becausejustabouteverythingyou’lllearninthisbookworkswithallversions(andifversion-specificissuesexistthatyouneedtobeawareof,Ipointthemout

alongtheway).

Ifyouwanttoinstallyourownserver,thenyouhavetwochoices:

YoucaninstallacompleteOracleserverinstallation.Thecurrentversion(asofwhenthisbookisgoingtoprint)isOracle12c,andyoucaninstallthatoranypriorversion.Oracleserveriscommercialsoftware,andsoalthoughyoucandownloadandinstallitwithoutbuyingalicense,youneedtopurchasealicenseforongoinguse.WhenyouinstallOracleserver,itpresentsyouwithlots(andIdomeanlots)ofconfigurationoptionsthatyoucanusetocontrolexactlywhatgetsinstalledandhowitisconfigured.

YoucanalsodownloadandinstallOracleDatabaseExpressEdition(alsocalledOracleDatabaseXE),afreeversionofOracleserverthathassomeimportantlimitations,noneofwhichwillimpactthelessonsinthisbook.InstallingOracleDatabaseExpressEditionisquickandpainless,andthePL/SQLyou’lllearnanduseappliestoallversionsofOracleserver.

Tip:OracleDatabaseExpressEditionIsRecommended

AsshouldbeapparentfromthedescriptionsIjustgaveyou,myrecommendationisthatifyouarenewtoOracleandwanttofocusonPL/SQL(asopposedtofocusingonmanagingandadministeringanOracleserver),usetheExpressEdition.Installingandconfiguringafull-blownOracleservercanbefrustratingifyou’veneverdoneitbefore,andifyourgoalistolearnPL/SQL,thateffortisunnecessary.Thecurrent(asofwhenthisbookisgoingtoprint)versionofOracleXEis11gRelease2.However,ifyoutrulydowanttodelveintotheworldofOracledatabaseadministration,thenbyallmeansinstallthefullOracleDBMS.

ObtainingtheSoftwareTolearnmoreaboutOracle,gotohttp://oracle.com/.

Todownloadacopyoftheserver,gototheOraclewebsiteandclickontheDownloadlink.Lotsofoptionspresentthemselves,buttheonesthatyouareinterestedinarethefollowing:

IntheDatabasesection,selectOracleDatabaseforafullOracleserverinstallation,ortheExpressEdition.

IntheDeveloperToolssection,selectSQLDeveloperfortheclienttool.

OracledoesrequirethecreationofanOracleaccounttodownloadanysoftware,soifyoudon’thaveanexistingaccount,thesitepromptsyoutocreateone.

Note:WhereIsOracleSQLDeveloper?

UnlikeSQL*Plus(whichisalwaysinstalledwithOracleserverinstallations),youmightneedtoinstallOracleSQLDeveloperseparately,dependingontheversionofOracleserveryouareusing.AsofOracle12c,OracleSQLDeveloperisindeedinstalledaspartoftheserverinstallation.However,ifyouareusinganolderversionofOracle,orOracleExpress,youmustdownloadandinstallOracleSQLDeveloperyourself.

InstallingtheSoftwareIfyouareinstallingalocalOracleserver,dosobeforeinstallinganyotherclientsorutilities.

ExactinstallationstepsforafullOracleserverarebeyondthescopeofthisbook,andifyouneedhelpwithaninstallation,youshouldrefertodocumentationontheOraclewebsite.

InstallationofOracleExpressEditioninvolvesthefollowing:

Dependingonyouroperatingsystem,youmightneedtoexpandthedownloadfiletouncompressit.

Runthesetupprogram.

Acceptthelicenseagreement.

Youcanleaveallquestionsandpromptswiththeirdefaultvalues.

Theprogramsasksyoutoprovideadatabasepassword;enteroneandrememberwhatitis!

Thenjustlettheinstallerdoitsthing.

Regardlessofwhetherornotyouinstallalocalserver,you’llwantalocalcopyofOracleSQLDeveloper.Ifonewasnotinstalled(ifand)whenyouinstalledtheOracleserver,dothefollowing:

Dependingonyouroperatingsystem,youmightneedtoexpandthedownloadfiletouncompressit.

Runthesetupprogram.

Acceptthelicenseagreement.

Youcanleaveallquestionsandpromptswiththeirdefaultvalues.

Thenjustlettheinstallerdoitsthing.

Aslongasthesoftwareinstallscorrectly,you’rereadytomoveontoLesson3,“WorkingwithOracle.”

SummaryYounowknowwhatOracleis,whatPL/SQLis,andwhatsoftwareyouneedtoproceed.YoushouldalsohaveaccesstoanOracleserver(localorremote),andhaveclientsoftwareinstalledandreadytouse.InLesson3,I’llshowyouhowtologinandlogoutoftheserver,andhowtoexecutecommands.ThelessonsinthisbookalluserealSQLstatementsandrealdata,andsoIwillalsowalkyouthroughcreatingandpopulatingtheexampledatabasetables.

Lesson3.WorkingwithOracle

Inthislesson,youlearnhowtoconnectandlogintoOracle,howtoissuePL/SQLSQLstatements,andhowtocreateandpopulatetheexampletablesthatwe’llbeusingthroughoutthisbook.

CreatingaWorkingEnvironmentNowthatyouhaveaccesstoOracleandclientsoftwaretousewithit,thenextstepistocreateaworkingenvironment.Databaseservers,likeyourOracleserver,areusuallyusedbylotsofdifferentusersandapplications.Imaginewhatwouldhappenifausercreatedatablecalledcustomerstostorecustomerdata,andanotherusertriedtocreateatableofthesamename.Userscouldoverwriteeachother’sdata;theycouldaccessincorrectinformation—yougettheidea.Inmulti-userenvironments,andDBMSsaredesignedtobeexactlythat,thistypeofcontentionisarealconcern.Andsowhenworkinginclient-serverdatabases,it’simportantforeachusertohaveaprivatesafeworkspace.Backtoourexample,byhavingthisworkspace,oneuser’scustomerstabledoesn’tinterferewithanotheruser’stableofthesamename.

Manydifferentwaysexisttocreatesafe,isolatedworkenvironments.IfyouareusinganexistingOracleserver,perhapsacorporatedatabase,thenthedatabaseadministratorwilllikelygiveyouyourownloginandworkspace,andwhenyoulogintoOracle,you’llbeintherightsafeworkspaceautomatically.Ifthisisthecase,youcanjumpaheadtothelatersection,“MakingtheConnection.”

If,however,youareusingyourownOracleserver,thenyou’llneedtodothisforyourself.

Caution:NotRequired,ButHighlyRecommended

WhenOracleisfirstinstalled,itcreatesonedefaultinstance.ThisiswhereOracleitselfstoressysteminformation,includinguserlogindetailsandmore.Thetruthisthatyoucanusethisdefaultsysteminstance,too;youcouldcreatetheexampletableswithinit,populatethemwiththeexampledata,andbeabletoproceedwiththelessonsinthisbook.However,usingthedefaultsysteminstanceforyourownworkisnotrecommended.Infact,doingsoisgenerallyconsideredabadidea.Why?Well,asIjustexplained,thissysteminstanceisusedtostoreinformationthatOracleDBMSitselfneeds,criticalinformationwithoutwhichtheDBMSmightnotrunproperly(ormaybenotrunatall).Asyouwillseeinlaterlessons,editingdata,evendeletingentiretables,isalltooeasytodo,andsoworkingandexperimentinginthedefaultsysteminstanceisaskingfortrouble.That’swhyIwantyoutocreateyourownsafeworkspace,oneotherthanthedefaultsysteminstance.

CreatingaDedicatedOracleInstanceThebestwaytocreateasafeworkenvironmentistocreateadedicatedinstanceofOracleforyourself.YoucanthinkofitasOracleallowingmultiplecopiesofitselftoberunonasingleserver,eachoneisolatedfromanothercopy.Eachserverisreferredtoasaninstance,andeachinstancehasauniquename.

Note:AreYouUsingOracleExpressEdition?

ThecreationofmultipleinstancesissupportedbyfullOracleinstallationsonly,butnotbyOracleExpressEdition.IfyouareusingExpressEdition,jumpaheadto“CreatingaCustomWorkspace.”

TocreateadedicatedOracleinstanceforusewiththisbook,dothefollowing:

1.RuntheOracleinstalledapplicationnamedDatabaseConfigur-ationAssistant;thisisusedtocreate(aswellasupdateanddelete)databaseinstances.

2.Whentheapplicationlaunches,selectthefirstoption,CreateaDatabase,andthenclicktheNextbutton.

3.YoumaybeaskedtoselectaDatabaseTemplate.Ifso,selectGeneralPurposeandthenclicktheNextbutton.

4.Everydatabasemustbeuniquelynamed.Inproductionenvironments,databasenamesarecarefullymanagedandareusuallyintheformorganization.domain.database.However,tokeepthingssimple,entercrashcourseastheGlobalDatabaseNameandastheSID(theSystemIdentifier),andthenclicktheNextbutton.

5.IfyouareaskedaboutEnterpriseManager,leavethedefaultsettings,andclicktheNextbutton.

6.You’llthenbeaskedforpasswordsforimportantmanagementaccounts.Youcanenterauniquepasswordforeachaccount,or,asthisisanon-mission-criticaldatabaseinstance,checktheUsetheSameAdministrativePasswordoptionandprovideapassword.Rememberthispassword;withoutit,youcannotaccessyournewdatabaseinstance.ClickNext.

7.Whenaskedaboutdatabasestoragelocationsandtemplates,leavethedefaultsettings,andclicktheNextbutton.

8.Whenaskedaboutrecoveryoptions,onceagain,leavethedefaultsettings,andclicktheNextbutton.

9.Oraclecaninstallsampletablesanddatainyournewinstance.Wedonotneedthisbecausewearegoingtouseourownexampledata.So,whenaskedaboutSampleSchemas,makesuretheboxisnotchecked,andthenclicktheNextbutton.

10.Whenaskedaboutmemory,sizing,charactersets,andconnections,leavethedefaultsettings,andclicktheNextbutton.

11.Eventuallyyou’llbeaskedwhetheryouwanttocreateadatabase,createadatabase

template,orgeneratedatabasecreationscripts.TheonlyoptionyouwantcheckedisCreateDatabase.

12.ClicktheNextbutton,andwhenpromptedforconfirmation,clicktheOKbutton.

TheOracleDatabaseConfigurationAssistantnowcreatesyournewcrashcoursedatabaseinstance.

Note:IfYouSeeWarningMessages

Youmightseewarningspertainingtospecificsettings.Aslongasthefinalscreensaysthatthedatabaseinstancecreationcompletessuccessfully,you’llbegoodtogo.

Afteryourdatabaseinstancehasbeencreated,youcanjumptothelatersection,“MakingtheConnection.”

CreatingaCustomWorkspaceIfyouareusingOracleExpressEdition,youwon’tbeabletocreateyourowndatabaseinstance.Soinstead,createauser-specificworkspacewithintheexistingdatabaseinstance.

Here’swhatyouneedtodo:

1.OracleExpressEditionismanagedviaanembeddedwebserver.TheOracleExpressEditioninstallercreatedalinknamedGetStartedwithOracleExpressEdition.Clickthelink,andawebbrowseropensdisplayingawebpagewithoptionstomanageStorage,Sessions,andmore.Ifyouarepromptedtologin,usetheloginnameSYSTEMandthepasswordyouprovidedatinstallationtime.

2.ClickontheredApplicationExpressbutton.You’llbepresentedwithawebpagethatcanbeusedtocreateanapplicationworkspace.

3.MakesureCreateNewisselected.

4.ForDatabaseUsername,typecrashcourse.

5.ForApplicationExpressUsername,typecrashcourse(oruseyourownname).

6.Enterapasswordofyourchoiceandconfirmit.

7.ClicktheredCreateWorkspacebutton.

8.Youshouldseeaprompttellingyouthattheworkspacewassuccessfullycreated,andallowingyoutologin.Clickontheloginoption.Ifyoudon’tseetheprompt,justclickontheApplicationExpressbuttonagain,andthistimeclickontheAlreadyhaveanaccount?LoginHerebutton.

9.WhenpromptedforWorkspace,entercrashcourse;forUsername,entertheusernamefromstep5,andenterthePasswordyouselected.

10.ClicktheLoginbutton.

YoushouldseeanewscreenwithoptionsforApplicationBuilder,SQLWorkshop,and

more.Ifthisisthecase,you’rereadytoproceed.

Tip:YouCanUseApplicationExpress

ApplicationExpressisaweb-basedinterfacetoOracleExpressEdition.AmongitsfeaturesisatoolnamedSQLWorkshopthatcanbeusedtoenterSQLstatements,buildscripts,andmore.Assuch,ApplicationExpressisanotherOracleclientthatyoucanuse.

Afteryourworkspacehasbeencreated,youcanjumptothefollowing“MakingtheConnection”section.

MakingtheConnectionOracle,likeallclient-serverDBMSs,requiresthatyoulogintotheDBMSbeforebeingabletoissuecommands.Loginnamesmightnotbethesameasyournetworkloginname(assumingthatyouareusinganetwork);Oraclemaintainsitsownlistofusersinternally,andassociatesrightswitheach.Foradatabaseclient,likeOracleSQLDeveloper,toconnecttotheOracleserver(evenalocalOracleserver),youmusttellitwheretofindtheserver,andhowtologin.

ToconnectOracleSQLDevelopertotheOracleserver,followthesesteps:

1.RunOracleSQLDeveloper.

2.Whentheapplicationloads,youseeascreensplitintothreesections,withmenusandanicontoolbarontop.Thetop-leftwindowistheConnectionswindow,anditlistsanydefinedOracleservers(ofwhichtherewillcurrentlybenone).

3.AtthetopoftheConnectionswindow,clickonthegreen+buttontoaddanewdatabaseconnection.

4.ForConnectionName,entercrashcourse.(Thenamedoesnothavetomatchthedatabase,workspace,login,oranythingelse;thisisjustthenamethatOracleSQLDeveloperusestoidentifyeachdefinedconnection.)

5.ForUsernameandPassword,enterwhatyouspecifiedwhenyoucreatedthedatabaseinstanceorworkspacepreviously.

6.ChecktheSavePasswordcheckboxsothatyoudon’thavetokeepenteringthepassword.

7.ForHostname,enterlocalhostifyouareusingyourownlocalOracleserver.Ifyouareusingaremoteorhostedserver,enterthehostnamegiventoyoubythatserver’sadministrator.

8.SIDisthedatabaseinstanceid.IfyouareusingalocalOracleserverandfollowedtheprecedingsteps,thenthisiscrashcourseifyouhaveadedicatedOracleinstance,orxeifyouareusingyourownworkspacewiththesingleOracleExpressEditioninstance.

9.ClicktheTestbutton.

10.Atthebottomleftofthedialogbox,youshouldseeStatus:Success.Ifthatisdisplayed,clicktheSavebuttontosavethisnewconnection.Ifanerrormessageisdisplayed,checktheformfieldsandcorrecttheerrorbeforeproceeding.

Afteryousavethenewcrashcourseconnection,youshouldseeitlistedintheConnectionswindowonthetopright.Youcannowclosethedialogbox.

Note:UsingOtherClients

IfyouareusingaclientotherthanOracleSQLDeveloper,youstillneedtoprovidethisinformationtoconnecttoOracle.Theexactstepsmightdiffer,butthesameinformationisrequired.

AQuickIntroductiontoOracleSQLDeveloperYou’llbeusingOracleSQLDeveloperextensivelyasyoulearnPL/SQL,soit’sworthtakingamomenttofamiliarizeyourselfwiththistool:

Note:JusttheBasics

OracleSQLDeveloperisapowerfuldatabaseclient,andwe’lljustusebasicqueryexecutioncapabilitiesinthisbook.Inthefuture,asyouusemoreofOracle’scapabilities,itwouldbetoyouradvantagetolearnmoreaboutthistool.

Clickthe+nexttoyournewcrashcourseconnectiontoexpandit.Thisshowsyoualltables,views,andmuchmore.Youcanfurtherexpandintoeachmenuoption,andcanright-clickoneachtoeditandmore.

Themostimportantpartofthescreenisthelargeareaontheright.ThisiswhereyouenteryourPL/SQLstatementsanddisplayresults(ifthereareany).

Whenyouopenaconnection,aworksheetshouldautomaticallyopenforyoutostartenteringSQL.Ifitdoesnot,orifyouwantmultipleworksheetsopen,youcanclickontheSQLWorksheetbuttonintheapplicationtoolbar(it’stheonewithagreeniconandthewordSQLinblackonwhiteinfrontofit).ClickOKandyou’llhaveanotherworksheettouse.

Let’sgiveitatry.EnterthefollowingPL/SQLintheWorksheetscreen.(Don’tworryifthecodedoesn’tmakesense;itwillwithinthenextfewlessons.)

ClickheretoviewcodeimageSELECTTO_CHAR(SYSDATE,‘DD-MON-YYYYHH:MI:SS’)FROMDUAL;

ClicktheRunScriptbutton(it’stheonewithagreenarrowontopofadocument;itshouldbethesecondfromtheleftinthetoolbarabovetheWorksheetwindow)toexecutetheSQLstatement.YoushouldseethesystemdateandtimedisplayedinaQueryResultscreenbelow.

Lastly,whenthescreensgetcluttered,clickontheClearbutton(theonewiththepictureofapencileraser)aboveeitherscreentoclearthecontents.

Execute

SQLdevelopersoftenusethetermsexecuteandruninterchangeably;bothmeanactuallyrunningtheSQL.

Note:RunStatementvs.RunScript

IjusthadyouclicktheRunScriptbuttontoexecutetheSQLstatementsintheWorksheetwindow.RunScriptdoesexactlythat—itrunstheentirescript,everylineofcodeintheworksheet.Attimes,however,youmightwanttorunjustpartofascript,perhapsasinglestatement.Todothis,youcanusetheRunStatementbuttoninstead(ithasagreenright-facingarrow);itrunswhateveriscurrentlyselectedintheWorksheetscreen,ratherthantheentirescript.

Tip:UsingMultipleWorksheets

YounowknowhowtoopenmultipleWorksheetscreensatonce.You’llfinddoingsousefulwhenyouareworkingonandtestingmultipleSQLstatementsatthesametime.

Withthat,you’rereadytorunsomeimportantSQLscripts—theonesusedtocreateandpopulatetheexampletablesthatyou’llbeusinginfuturelessons.

CreatingandPopulatingtheExampleTablesThetablesusedthroughoutthisbookarepartofanorderentrysystemusedbyanimaginarydistributorofparaphernaliathatmightbeneededbyyourfavoritecartooncharacters(yes,cartooncharacters;noonesaidthatlearningOraclehadtobeboring).Thetablesareusedtoperformseveraltasks,including:

Managevendors

Manageproductcatalogs

Managecustomerlists

Entercustomerorders

Makingthisallworkrequiressixtablesthatarecloselyinterconnectedaspartofarelationaldatabasedesign.Herearethetableswe’llbeusing:

Thecustomerstablecontainsyourcustomers.

Theorderstablecontainsonerowperorderplaced.

Theorderitemstablecontainsthedetailsforeachiteminanorder(theordersintheorderstable).

Theproductstablelistsallavailableproductsfromallvendors.

Theproductnotestablecontainsnotespertainingtoproducts.

Thevendorstablecontainsproductvendors.

Thesesixtablescontainmultiplecolumns,andareallconnectedusingforeignkeys.AdetaileddescriptionofeachofthetablesappearsinAppendixA,“TheExampleTables.”

Note:SimplifiedExamples

Thetablesusedherearebynomeanscomplete.Areal-worldorderentrysystemwouldhavetokeeptrackoflotsofotherdatathathasnotbeenincludedhere(forexample,paymentandaccountinginformation,shipmenttracking,andmore).However,thesetablesdodemonstratethekindsofdataorganizationandrelationshipsyouencounterinmostrealinstallations.Youcanapplythesetechniquesandtechnologiestoyourowndatabases.

ObtainingtheSameTableScriptsTofollowalongwiththeexamples,youneedasetofpopulatedtables.Everythingyouneedtogetupandrunningcanbefoundonthisbook’swebpageathttp://forta.com/books/0672328666.

ThewebpagecontainsaZIPfilethatyoushoulddownload.InsideitaretwoSQLscriptfiles:

create.sqlcontainsthePL/SQLstatementstocreatethesixdatabasetables(includingdefiningallprimarykeysandforeignkeyconstraints).

populate.sqlcontainsthePL/SQLINSERTstatementsusedtopopulatethesetableswithsampledata.

Note:ForOracleOnly

TheSQLstatementsinthedownloadable.sqlfilesareveryDBMSspecific,andaredesignedtobeusedonlywithOracle.

Afteryouhavedownloadedthescripts,youcanusethemtocreateandpopulatethetablesneededtofollowalongwiththelessonsinthisbook.

Note:Create,ThenPopulate

Youmustrunthetablecreationscriptsbeforethetablepopulationscripts.Besuretocheckforanyerrormessagesreturnedbythesescripts.Ifthecreationscriptsfail,youneedtoremedywhateverproblemmightexistbeforecontinuingwithtablepopulation.

CreatetheTablesDatabasetablesarecreatedusingtheSQLstatementCREATETABLE,butratherthanhaveyoutypethatallout,youcanusethecreate.sqlfilethatyoudownloaded.

1.MakesureOracleSQLDeveloperisopenandthecrashcourseconnectionis

open.

2.UsetheOpenbutton(ithasapictureofayellowfolder)orchooseFile,Opentoopencreate.sql.Thecontentsofcreate.sqlappearinanewworksheet.

3.Becauseyoucouldbeworkingwithmultipledatabaseconnections,youneedtotellOracleSQLDevelopertousethecrashcourseconnection.Fromthedrop-downboxatthetoprightabovetheWorksheetscreen,selectcrashcourse.

4.ClicktheRunScriptbutton(onceagain,it’stheoneabovetheWorksheetscreen;agreenarrowoveradocument).Youshouldthenseethefollowingoutput:

OutputtableCUSTOMERScreated.tableORDERITEMScreated.tableORDERScreated.tablePRODUCTScreated.tableVENDORScreated.tablePRODUCTNOTEScreated.tableCUSTOMERSaltered.tableORDERITEMSaltered.tableORDERSaltered.tablePRODUCTSaltered.tableVENDORSaltered.tablePRODUCTNOTESaltered.tableORDERITEMSaltered.tableORDERITEMSaltered.tableORDERSaltered.tablePRODUCTSaltered.tablePRODUCTNOTESaltered.

Theprecedingtellsyouthatsixtableswerecreated,andthattheywerethenalsoaltered(wedothistoaddprimaryandforeignkeys).Nowthatyouhavetables,let’spopulatethem.

PopulatetheTablesDataisinsertedintoatableusingtheINSERTstatement.Onceagain,ratherthantypinghundredsoflinesofSQL,we’llusethedownloadedfileinstead.

1.UsetheOpenbutton(orchooseFile,Open)toopenpopulate.sql.Thecontentsofpopulate.sqlappearinanewworksheet.

2.Makesurethatcrashcourseisselectedinthedrop-downboxatthetoprightabovetheWorksheetscreen.

3.ClicktheRunScriptbutton(onceagain,it’stheoneabovetheWorksheetscreen;agreenarrowoveradocument).Youshouldthenseethefollowingmessageappear55times(onceforeachrowinserted):

Output1rowsinserted.

Younowhavethetablesanddatayouneedtoproceed.

OneMoreLookatOracleSQLDeveloperBeforefinishingthislesson,IwanttopointoutonemoreinvaluablefeatureofOracleSQLDeveloper.Nowthatyouhavecreatedandpopulatedtheexampletables,trythefollowing:

1.LocatethecrashcoursedatabaseconnectionintheConnectionsscreen,andclick+toexpandit.

2.Thefirstitemdisplayedisb;click+toexpandthat.

3.Scrollthroughthelistoftablestofindonethatwejustcreated.Thefirstoneyou’llseeiscustomers,butanyofourtableswilldo.

4.Clickthe+toexpandthetable,andseethetablecolumnnames.

Inaddition,OracleSQLDeveloperopensanewtabinthemainWorksheetareaandthetablecolumns(showingdetailsabouttype,nullable,andmore).Abovethedataareothertabsthatyoucanclickon—Datashowsthecontentsofthetable,Constraintslistsprimaryandforeignkeysandanyotherdefinedconstraints,Detailslistsallsortsofinformationaboutthetableandhowitisbeingused,SQLlistsSQLcodethatcouldbeusedtocreatethetable,andsoon.Feelfreetobrowsearound;thisdataandviewareusefulforworkingwithOracle.

SummaryInthislesson,youlearnedhowtoconnectandlogintoOracle,andhowtoenterandexecuteSQLstatements.Youalsocreatedandpopulatedtheexampletables.Armedwiththisknowledge,youcannowdigintotheall-importantSELECTstatement.

Lesson4.RetrievingData

Inthislesson,you’lllearnhowtousetheSELECTstatementtoretrieveoneormorecolumnsofdatafromatable.

The Statement

Note:SampleTablesRequired

Fromthispointon,alllessonsusethesampledatabasetables.Ifyouhaveyettoinstallthese,pleaserefertoLesson3,“WorkingwithOracle,”beforeproceeding.

AsexplainedinLesson1,“UnderstandingSQL,”SQLstatementsaremadeupofplainEnglishterms.Thesetermsarecalledkeywords,andeverySQLstatementismadeupofoneormorekeywords.TheSQLstatementyou’llprobablyusemostfrequentlyistheSELECTstatement.Itspurposeistoretrieveinformationfromoneormoretables.

TouseSELECTtoretrievetabledata,youmust,ataminimum,specifytwopiecesofinformation—whatyouwanttoselect,andfromwhereyouwanttoselectit.

RetrievingIndividualColumnsWe’llstartwithasimpleSQLSELECTstatement,asfollows:

Input

SELECTprod_nameFROMproducts;

Tip:TypeThenExecute

Bynowitshouldbeobvious,butI’llremindyouonelasttime.TypetheSQLcodeintheOracleSQLDeveloperWorksheetscreen,andthenclicktheRunScriptbuttontoexecuteit.ResultsappearinascreenbelowtheWorksheet.Ifyouneedmoreroom,youcandragandresizeallthescreens.

Analysis

ThepreviousstatementusestheSELECTstatementtoretrieveasinglecolumncalledprod_namefromtheproductstable.ThedesiredcolumnnameisspecifiedrightaftertheSELECTkeyword,andtheFROMkeywordspecifiesthenameofthetablefromwhichtoretrievethedata.Thefollowingshowstheoutputfromthisstatement:

Output+–––––-+|prod_name|+–––––-+|.5tonanvil||1tonanvil|

|2tonanvil||Oilcan||Fuses||Sling||TNT(1stick)||TNT(5sticks)||Birdseed||Carrots||Safe||Detonator||JetPack1000||JetPack2000|+–––––-+

Note:UnsortedData

Ifyoutriedthisqueryyourself,youmighthavediscoveredthatthedatadisplayedinadifferentorderthanshownhere.Ifthisisthecase,don’tworry—itisworkingexactlyasitissupposedto.Ifqueryresultsarenotexplicitlysorted(we’llgettothatinthenextlesson),datawillbereturnedinnoorderofanysignificance.Itmightbetheorderinwhichthedatawasaddedtothetable,butitmightnot.Aslongasyourqueryreturnedthesamenumberofrows,thenitisworking.

AsimpleSELECTstatementliketheonejustshownreturnsalltherowsinatable.Dataisnotfiltered(soastoretrieveasubsetoftheresults),norisitsorted.We’lldiscussthesetopicsinthenextfewlessons.

Note:TerminatingStatements

MultipleSQLstatementsmustbeseparatedbysemicolons(the;character).Oracle(likemostDBMSs)doesnotrequirethatasemicolonbespecifiedaftersinglestatements.Thatsaid,mostSQLdevelopersgetinthehabitofalwaysterminatingtheirSQLstatementswithsemicolons,evenwhentheyarenotneeded.

Note:SQLStatementsandCase

NotethatSQLstatementsarenotcasesensitive,soSELECTisthesameasselect,whichisthesameasSelect.ManySQLdevelopersfindthatusinguppercaseforallSQLkeywordsandlowercaseforcolumnandtablenamesmakescodeeasiertoreadanddebug.

However,beawarethatwhiletheSQLlanguageisnotcasesensitive,identifiers(thenamesofdatabases,tables,andcolumns)mightbe.Asabestpractice,pickacaseconvention,anduseitconsistently.

Tip:UseofWhiteSpace

AllextrawhitespacewithinaSQLstatementisignoredwhenthatstatementisprocessed.YoucanspecifySQLstatementsononelonglineorbreakthemupovermanylines.MostSQLdevelopersfindthatbreakingupstatementsovermultiplelinesmakesthemeasiertoreadanddebug.

RetrievingMultipleColumnsToretrievemultiplecolumnsfromatable,youusethesameSELECTstatement.TheonlydifferenceisthatyoumustspecifymultiplecolumnnamesaftertheSELECTkeyword,andseparateeachcolumnbyacomma.

Tip:TakeCarewithCommas

Whenselectingmultiplecolumns,besuretospecifyacommabetweeneachcolumnname,butnotafterthelastcolumnname.Doingsogeneratesanerror.

ThefollowingSELECTstatementretrievesthreecolumnsfromtheproductstable:

InputClickheretoviewcodeimage

SELECTprod_id,prod_name,prod_priceFROMproducts;

Analysis

Justasinthepriorexample,thisstatementusestheSELECTstatementtoretrievedatafromtheproductstable.Inthisexample,threecolumnnamesarespecified,eachseparatedbyacomma.Theoutputfromthisstatementisasfollows:

OutputClickheretoviewcodeimage

+–––+–––––-+––––+|prod_id|prod_name|prod_price|+–––+–––––-+––––+|ANV01|.5tonanvil|5.99||ANV02|1tonanvil|9.99||ANV03|2tonanvil|14.99||OL1|Oilcan|8.99||FU1|Fuses|3.42||SLING|Sling|4.49||TNT1|TNT(1stick)|2.5||TNT2|TNT(5sticks)|10||FB|Birdseed|10||FC|Carrots|2.5||SAFE|Safe|50||DTNTR|Detonator|13||JP1000|JetPack1000|35||JP2000|JetPack2000|55|

+–––+–––––-+––––+

Note:PresentationofData

SQLstatementstypicallyreturnraw,unformatteddata.Dataformattingisapresentationissue,notaretrievalissue.Therefore,presentation(forexample,alignmentanddisplayingthepricevaluesascurrencyamountswiththecurrencysymbolandcommas)istypicallyspecifiedintheapplicationthatdisplaysthedata.Actualrawretrieveddata(withoutapplication-providedformatting)israrelydisplayedasis.

RetrievingAllColumnsInadditiontobeingabletospecifydesiredcolumns(oneormore,asshownpreviously),youcanalsouseSELECTstatementstorequestallcolumnswithouthavingtolistthemindividually.Thisisdoneusingtheasterisk(*)wildcardcharacterinlieuofactualcolumnnames,asfollows:

Input

SELECT*FROMproducts;

Analysis

Whenyouspecifyawildcard(*),allthecolumnsinthetablearereturned.Thecolumnsareintheorderinwhichthecolumnsappearinthetabledefinition.However,youcannotrelyonthisbecausechangestotableschemas(addingandremovingcolumns,forexample)couldcauseorderingchanges.

Caution:UsingWildcards

Asarule,youarebetteroffnotusingthe*wildcardunlessyoureallydoneedeverycolumninthetable.Eventhoughuseofwildcardsmightsaveyouthetimeandeffortneededtolistthedesiredcolumnsexplicitly,retrievingunnecessarycolumnsusuallyslowsdowntheperformanceofyourretrievalandyourapplication.

Tip:RetrievingUnknownColumns

Thereisonebigadvantagetousingwildcards.Asyoudonotexplicitlyspecifycolumnnames(becausetheasteriskretrieveseverycolumn),itispossibletoretrievecolumnswhosenamesareunknown.

RetrievingDistinctRowsAsyouhaveseen,SELECTreturnsallmatchedrows.Butwhatifyoudidnotwanteveryoccurrenceofeveryvalue?Forexample,supposeyouwantedthevendorIDofallvendorswithproductsinyourproductstable:

Input

SELECTvend_idFROMproducts;

Output+–––+|vend_id|+–––+|1001||1001||1001||1002||1002||1003||1003||1003||1003||1003||1003||1003||1005||1005|+–––+

TheSELECTstatementreturned14rows(eventhoughonly4vendorsareinthatlist)because14productsarelistedintheproductstable.Sohowcouldyouretrievealistofdistinctvalues?

ThesolutionistousetheDISTINCTkeywordwhich,asitsnameimplies,instructsOracletoonlyreturndistinctvalues:

Input

SELECTDISTINCTvend_idFROMproducts;

Analysis

SELECTDISTINCTvend_idtellsOracletoonlyreturndistinct(unique)vend_idrows,andsoonly4rowsarereturned,asshowninthefollowingoutput.Ifyouuseit,youmustplacetheDISTINCTkeyworddirectlyinfrontofthecolumnnames:

Output+–––+|vend_id|+–––+|1001||1002||1003|

|1005|+–––+

Caution:Can’tBePartially

TheDISTINCTkeywordappliestoallcolumns,notjusttheoneitprecedes.IfyouweretospecifySELECTDISTINCTvend_id,prod_price,allrowswouldberetrievedunlessbothofthespecifiedcolumnsweredistinct.

UsingFullyQualifiedTableNamesTheSQLexamplesusedthusfarhavereferredtocolumnsbyjustthecolumnnames.Referringtocolumnsusingfullyqualifiednames(usingboththetableandcolumnnames)isalsopossible.Lookatthisexample:

Input

SELECTproducts.prod_nameFROMproducts;

ThisSQLstatementisfunctionallyidenticaltothefirstoneusedinthislesson,buthereafullyqualifiedcolumnnameisspecified.

Tablenames,too,maybefullyqualified,asshownhere:

Input

SELECTproducts.prod_nameFROMcrashcourse.products;

Onceagain,thisstatementisfunctionallyidenticaltotheonejustused(assuming,ofcourse,thattheproductstableisindeedinthecrashcoursedatabase).

Situationsexistwherefullyqualifiednamesarerequired,aswewillseeinlaterlessons.Fornow,itisworthnotingthissyntaxsoyou’llknowwhatitisifyourunacrossit.

UsingCommentsAsyouhaveseen,SQLstatementsareinstructionsthatOracleprocesses.Butwhatifyouwantedtoincludetextthatyoudonotwantprocessedandexecuted?Whywouldyoueverwanttodothis?Hereareafewreasons:

TheSQLstatementswe’vebeenusinghereareallveryshortandverysimple.But,asyourSQLstatementgrows(inlengthandcomplexity),you’llwanttoincludedescriptivecomments(foryourownfuturereferenceorforwhoeverhastoworkontheprojectnext).YouneedtoembedthesecommentsintheSQLscripts,buttheyareobviouslynotintendedforOracleprocessing.(Foranexampleofthis,seethecreate.sqlandpopulate.sqlfilesyouusedinLesson3.)

ThesameistrueforheadersatthetopofaSQLfile,perhapscontainingtheprogrammercontactinformationandadescriptionandnotes.(Youalsoseethisuse

caseinthecreate.sqlandpopulate.sqlfiles.)

AnotherimportantuseforcommentsistotemporarilystopSQLcodefrombeingexecuted.IfyouwereworkingwithalongSQLstatementandwantedtotestjustpartofit,youcouldcommentoutsomeofthecodesothatOraclesawitascommentsandignoredit.

Oraclesupportstwoformsofcommentsyntax.We’llstartwithinlinecomments:

InputClickheretoviewcodeimage

SELECTprod_name—thisisacommentFROMproducts;

Analysis

Youmayembedcommentsinlineusing--(twohyphens).Anythingafterthe--isconsideredcommenttext,makingthisagoodoptionfordescribingcolumnsinaCREATETABLEstatement,forexample.

Hereisanotherformofinlinecomment:

Input

—ThisisacommentSELECTprod_nameFROMproducts;

Analysis

A--atthestartofalinemakestheentirelineacomment.Youcanseethisformatcommentusedintheaccompanyingcreate.sqlandpopulate.sqlscripts.

Youcanalsocreatemulti-linecomments,andcommentsthatstopandstartanywherewithinthescript:

Input

/*SELECTprod_name,vend_idFROMproducts;*/

SELECTprod_nameFROMproducts;

Analysis

/*startsacomment,and*/endsit.Anythingbetween/*and*/iscommenttext.Thistypeofcommentisoftenusedtocommentoutcode,asshowninthisexample.Here,twoSELECTstatementsaredefined,butthefirstwon’texecutebecauseithasbeencommentedout.

Tip:OracleSQLDeveloperColorCoding

YoumighthavenoticedthatOracleSQLDevelopercolorcodesyourPL/SQL.SQLstatementsareusuallydisplayedinblue,identifiers(liketableandcolumnnames)areinblack,andsoon.Colorcodingmakesiteasiertoreadyourcodeandtofindmistakes;ifyou’vemistypedaPL/SQLstatement,it’llprobablyappearinthewrongcolor.OracleSQLDeveloperalsocolorcodesanycomments(inlineormulti-line)anddisplaystheminalightgray.Thismakesiteasytolocatecommentsandcommented-outcode(andcanalsohelpyoufindcodethatyounolongerwantcommentedout).

SummaryInthislesson,youlearnedhowtousetheSQLSELECTstatementtoretrieveasingletablecolumn,multipletablecolumns,andalltablecolumns.Youalsolearnedaboutcommentingandsawvariouswaysthatyoucanusecomments.Inthenextlesson,you’lllearnhowtosorttheretrieveddata.

Lesson5.SortingRetrievedData

ThislessonshowsyouhowtousetheSELECTstatement’sORDERBYclausetosortretrieveddataasneeded.

SortingDataAsyoulearnedinthelastlesson,thefollowingSQLstatementreturnsasinglecolumnfromadatabasetable.Butlookattheoutput.Thedataappearstobedisplayedinnoparticularorderatall:

Input

SELECTprod_nameFROMproducts;

Output+–––––-+|prod_name|+–––––-+|.5tonanvil||1tonanvil||2tonanvil||Oilcan||Fuses||Sling||TNT(1stick)||TNT(5sticks)||Birdseed||Carrots||Safe||Detonator||JetPack1000||JetPack2000|+–––––-+

Actually,theretrieveddataisnotinamererandomorder.Ifunsorted,datatypicallydisplaysintheorderinwhichitappearsintheunderlyingtables.Thiscouldbetheorderinwhichthedatawasaddedtothetablesinitially.However,ifdatawassubsequentlyupdatedordeleted,theorderisaffectedbyhowOraclereusesreclaimedstoragespace.Theendresultisthatyoucannot(andshouldnot)relyonthesortorderifyoudonotexplicitlycontrolit.Relationaldatabasedesigntheorystatesthatthesequenceofretrieveddatacannotbeassumedtohavesignificanceiforderingwasnotexplicitlyspecified.

Clause

SQLstatementsaremadeupofclauses,somerequiredandsomeoptional.Aclauseusuallyconsistsofakeywordandsupplieddata.AnexampleofthisistheSELECTstatement’sFROMclause,whichyousawinthelastlesson.

ToexplicitlysortdataretrievedusingaSELECTstatement,youusetheORDERBYclause.ORDERBYtakesthenameofoneormorecolumnsbywhichtosorttheoutput.

Lookatthefollowingexample:

Input

SELECTprod_nameFROMproductsORDERBYprod_name;

Analysis

Thisstatementisidenticaltotheearlierstatement,exceptitalsospecifiesanORDERBYclauseinstructingOracletosortthedataalphabeticallybytheprod_namecolumn.Theresultsarethefollowing:

Output+–––––-+|prod_name|+–––––-+|.5tonanvil||1tonanvil||2tonanvil||Birdseed||Carrots||Detonator||Fuses||JetPack1000||JetPack2000||Oilcan||Safe||Sling||TNT(1stick)||TNT(5sticks)|+–––––-+

Tip:SortingbyNonselectedColumns

Moreoftenthannot,thecolumnsusedinanORDERBYclauseareonesthatwereselectedfordisplay.However,thisisactuallynotrequired,andsortingdatabyacolumnthatisnotretrievedisperfectlylegal.

SortingbyMultipleColumnsSortingdatabymorethanonecolumnisoftennecessary.Forexample,youmightwanttodisplayanemployeelistsortedbylastnameandfirstname(firstsortbylastname,andthenwithineachlastnamesortbyfirstname).Thisisusefulifmultipleemployeeshavethesamelastname.

Tosortbymultiplecolumns,simplyspecifythecolumnnamesseparatedbycommas(justasyoudowhenyouareselectingmultiplecolumns).

Thefollowingcoderetrievesthreecolumnsandsortstheresultsbytwoofthem—firstbypriceandthenbyname:

Input

Clickheretoviewcodeimage

SELECTprod_id,prod_price,prod_nameFROMproductsORDERBYprod_price,prod_name;

OutputClickheretoviewcodeimage

+–––+––––+–––––-+|prod_id|prod_price|prod_name|+–––+––––+–––––-+|FC|2.5|Carrots||TNT1|2.5|TNT(1stick)||FU1|3.42|Fuses||SLING|4.49|Sling||ANV01|5.99|.5tonanvil||OL1|8.99|Oilcan||ANV02|9.99|1tonanvil||FB|10|Birdseed||TNT2|10|TNT(5sticks)||DTNTR|13|Detonator||ANV03|14.99|2tonanvil||JP1000|35|JetPack1000||SAFE|50|Safe||JP2000|55|JetPack2000|+–––+––––+–––––-+

Youshouldunderstandthatwhenyousortbymultiplecolumns,thesortsequenceisexactlyasspecified.Inotherwords,usingtheoutputinthepreviousexample,theproductsaresortedbytheprod_namecolumnonlywhenmultiplerowshavethesameprod_pricevalue.Ifallthevaluesintheprod_pricecolumnhadbeenunique,nodatawouldhavebeensortedbyprod_name.

Asyou’veseen,ORDERBYsortsresultsbycolumns,thenamesofwhichareprovidedinacomma-delimitedlist.OraclealsoallowsyoutospecifythesortorderbyreferringtothecolumnpositionintheSELECTstatement.HereistheSQLstatementwejustused:

InputClickheretoviewcodeimage

SELECTprod_id,prod_price,prod_nameFROMproductsORDERBYprod_price,prod_name;

WhatfollowsisthesameSQLstatement,butwithaslightlydifferentlookattheORDERBYclause:

InputClickheretoviewcodeimage

SELECTprod_id,prod_price,prod_nameFROMproducts

ORDERBY2,3;

Analysis

Insteadofspecifyingcolumnnames,ORDERBY2,3instructsOracletosortbythesecondandthirdcolumnsintheSELECTstatement,namelyprod_priceandprod_name.Eitherway,theoutputisthesame.

Tip:UseSequenceNumberOrderingwithCare

ThetypeofORDERBYjustshown,whereSELECTcolumnpositionisusedinsteadofcolumnnames,isreferredtoasorderingbysequencenumber.Ishowyouthissyntaxsothatyou’llknowwhatitisifyourunacrossit.But,ingeneral,usingthistypeofORDERBYstatementisrisky,becauseifyoueverchangetheSELECTstatement,youmightinadvertentlybreakyourordering.Asarule,beingexplicitisalwaysbetter.

SpecifyingSortDirectionDatasortingisnotlimitedtoascendingsortorders(fromAtoZ).Althoughthisisthedefaultsortorder,youcanalsousetheORDERBYclausetosortindescendingorder(fromZtoA).Tosortbydescendingorder,youmustspecifythekeywordDESC.

Thefollowingexamplesortstheproductsbypriceindescendingorder(mostexpensivefirst):

InputClickheretoviewcodeimage

SELECTprod_id,prod_price,prod_nameFROMproductsORDERBYprod_priceDESC;

OutputClickheretoviewcodeimage

+–––+––––+–––––-+|prod_id|prod_price|prod_name|+–––+––––+–––––-+|JP2000|55|JetPack2000||SAFE|50|Safe||JP1000|35|JetPack1000||ANV03|14.99|2tonanvil||DTNTR|13|Detonator||TNT2|10|TNT(5sticks)||FB|10|Birdseed||ANV02|9.99|1tonanvil||OL1|8.99|Oilcan||ANV01|5.99|.5tonanvil||SLING|4.49|Sling||FU1|3.42|Fuses||FC|2.5|Carrots|

|TNT1|2.5|TNT(1stick)|+–––+––––+–––––-+

Butwhatifyouweretosortbymultiplecolumns?Thefollowingexamplesortstheproductsindescendingorder(mostexpensivefirst),plusproductname:

InputClickheretoviewcodeimage

SELECTprod_id,prod_price,prod_nameFROMproductsORDERBYprod_priceDESC,prod_name;

OutputClickheretoviewcodeimage

+–––+––––+–––––-+|prod_id|prod_price|prod_name|+–––+––––+–––––-+|JP2000|55|JetPack2000||SAFE|50|Safe||JP1000|35|JetPack1000||ANV03|14.99|2tonanvil||DTNTR|13|Detonator||FB|10|Birdseed||TNT2|10|TNT(5sticks)||ANV02|9.99|1tonanvil||OL1|8.99|Oilcan||ANV01|5.99|.5tonanvil||SLING|4.49|Sling||FU1|3.42|Fuses||FC|2.5|Carrots||TNT1|2.5|TNT(1stick)|+–––+––––+–––––-+

Analysis

TheDESCkeywordonlyappliestothecolumnnamethatdirectlyprecedesit.Inthepreviousexample,DESCwasspecifiedfortheprod_pricecolumn,butnotfortheprod_namecolumn.Therefore,theprod_pricecolumnissortedindescendingorder,buttheprod_namecolumn(withineachprice)isstillsortedinstandardascendingorder.

Tip:SortingDescendingonMultipleColumns

Ifyouwanttosortdescendingonmultiplecolumns,besureeachcolumnhasitsownDESCkeyword.

TheoppositeofDESCisASC(forascending),whichyoumayspecifytosortinascendingorder.Inpractice,however,youdon’tusuallyuseASCbecauseascendingorderisthedefaultsequence(andisassumedifneitherASCnorDESCarespecified).

Tip:CaseSensitivityandSortOrders

Whenyousorttextualdata,isAthesameasa?AnddoesacomebeforeBorafterZ?Thesearenottheoreticalquestions,andtheanswersdependonhowthedatabaseissetup.

Indictionarysortorder,Aistreatedthesameasa,andthatisthedefaultbehaviorinOracle(andindeedmostDBMSs).However,administratorscanchangethisbehaviorifneeded.(Ifyourdatabasecontainslotsofforeignlanguagecharacters,thismightbecomenecessary.)

Thekeyhereisthat,ifyoudoneedanalternatesortorder,youcannotaccomplishitwithasimpleORDERBYclause.Youmustcontactyourdatabaseadministrator.

SummaryInthislesson,youlearnedhowtosortretrieveddatausingtheSELECTstatement’sORDERBYclause.Youcanusethisclause,whichmustbethelastintheSELECTstatement,tosortdataononeormorecolumnsasneeded.

Lesson6.FilteringData

ThislessonshowsyouhowtousetheSELECTstatement’sWHEREclausetospecifysearchconditions.

Usingthe ClauseDatabasetablesusuallycontainlargeamountsofdata,andyouseldomneedtoretrievealltherowsinatable.Moreoftenthannot,you’llwanttoextractasubsetofthetable’sdataasneededforspecificoperationsorreports.Retrievingjustthedatayouwantinvolvesspecifyingsearchcriteria,alsoknownasafiltercondition.

WithinaSELECTstatement,youfilterdatabyspecifyingsearchcriteriaintheWHEREclause.YouspecifytheWHEREclauserightafterthetablename(theFROMclause),asfollows:

Input

SELECTprod_name,prod_priceFROMproductsWHEREprod_price=2.50;

Analysis

Thisstatementretrievestwocolumnsfromtheproductstable,butinsteadofreturningallrows,onlyrowswithaprod_pricevalueof2.50arereturned,asfollows:

OutputClickheretoviewcodeimage

+–––––+––––+|prod_name|prod_price|+–––––+––––+|Carrots|2.5||TNT(1stick)|2.5|+–––––+––––+

Note:No ClauseSpecified

Intheinterestsofsavingspace(andyourtyping),IomittedtheORDERBYclauseinmanyoftheseexamples.Assuch,itisentirelypossiblethatyouroutputwon’texactlymatchtheoutputinthebook.Althoughthenumberofreturnedrowsshouldalwaysmatch,theirordermightnot.Ofcourse,feelfreetoaddanORDERBYclauseifyouwant;itneedstogoaftertheWHEREclause.

Note:DecimalRounding

EventhoughtheWHEREclausespecifiedavalueof2.50,yourreturneddatamightshowthevalueroundedto2.5(asitdidforme).Oracle,likeallDBMSs,hasdefaultbehaviorsforhowitformatsreturneddata,andtheresultmightnotalwaysbeexactlywhatyouwant.InLesson11,“UsingDataManipulationFunctions,”youlearnhowtousefunctionstoformatdataexactlyasneeded.

Thisexampleusesasimpleequalitytest:Itcheckstoseewhetheracolumnhasaspecifiedvalue,anditfiltersthedataaccordingly.However,SQLenablesyoutodomorethanjusttestforequality.

Tip:SQLVersusApplicationFiltering

Youcanalsofilterdataattheapplicationlevel.Todothis,theSQLSELECTstatementretrievesmoredatathanisactuallyrequiredfortheclientapplication,andtheclientcodeloopsthroughthereturneddatatoextractjusttheneededrows.

Asarule,thispracticeisstronglydiscouraged.Databasesareoptimizedtoperformfilteringquicklyandefficiently.Makingtheclientapplication(ordevelopmentlanguage)dothedatabase’sjobdramaticallyimpactsapplicationperformanceandcreatesapplicationsthatcannotscaleproperly.Inaddition,ifdataisfilteredattheclient,theserverhastosendunneededdataacrossthenetworkconnections,resultinginawasteofnetworkbandwidthresources.

Caution: ClausePosition

WhenusingbothORDERBYandWHEREclauses,makesureORDERBYcomesaftertheWHERE;otherwise,anerrorisgenerated.(SeeLesson5,“SortingRetrievedData,”formoreinformationonusingORDERBY.)

The ClauseOperatorsThefirstWHEREclausewelookedattestsforequality—determiningwhetheracolumncontainsaspecificvalue.Oraclesupportsawholerangeofconditionaloperators,someofwhichTable6.1lists.

TABLE6.1WHEREClauseOperators

CheckingAgainstaSingleValueWehavealreadyseenanexampleoftestingforequality.Here’sonemore:

Input

SELECTprod_name,prod_priceFROMproductsWHEREprod_name=‘Fuses’;

Output+–––—+––––+|prod_name|prod_price|+–––—+––––+|Fuses|3.42|+–––—+––––+

Analysis

CheckingforWHEREprod_name='Fuses'returnedasinglerowwithavalueofFuses.

DependingonhowyourOracleserverisconfigured,Oraclecouldbecasesensitivewhenperformingmatches,inwhichcasefusesandFuseswouldnotbethesame.Trythisexample:

Input

SELECTprod_name,prod_priceFROMproductsWHEREprod_name=‘fuses’;

Analysis

Bydefault,Oracleiscasesensitive,andsocomparingtolowercasefusesreturnsnoresults,becausefusesandFusesarenotthesame.

Tip:CaseInsensitiveEqualityComparisons

Sohowcanyoufindfuses,Fuses,FUSES,andanyothermixofupper-andlowercase?Thetrickistousefunctionstochangeeverythingtoonecase,eitherupperorlower.You’lllearnaboutstringmanipulationfunctionsinLesson10,“CreatingCalculatedFields.”

Nowlookatafewexamplestodemonstratetheuseofotheroperators.

Thisfirstexamplelistsallproductsthatcostlessthan10:

Input

SELECTprod_name,prod_priceFROMproductsWHEREprod_price<10;

OutputClickheretoviewcodeimage

+–––––+––––+|prod_name|prod_price|+–––––+––––+|.5tonanvil|5.99||1tonanvil|9.99||Carrots|2.5||Fuses|3.42||Oilcan|8.99||Sling|4.49||TNT(1stick)|2.5|+–––––+––––+

Thisnextstatementretrievesallproductscosting10orless(resultingintwoadditionalmatches):

Input

SELECTprod_name,prod_priceFROMproductsWHEREprod_price<=10;

OutputClickheretoviewcodeimage

+–––––-+––––+|prod_name|prod_price|+–––––-+––––+|.5tonanvil|5.99||1tonanvil|9.99||Birdseed|10||Carrots|2.5||Fuses|3.42||Oilcan|8.99||Sling|4.49|

|TNT(1stick)|2.5||TNT(5sticks)|10|+–––––-+––––+

CheckingforNonmatchesThisnextexamplelistsallproductsnotmadebyvendor1003:

Input

SELECTvend_id,prod_nameFROMproductsWHEREvend_id<>1003;

Output+–––+––––—+|vend_id|prod_name|+–––+––––—+|1001|.5tonanvil||1001|1tonanvil||1001|2tonanvil||1002|Fuses||1005|JetPack1000||1005|JetPack2000||1002|Oilcan|+–––+––––—+

Tip:WhentoUseQuotes

Ifyoulookcloselyattheconditionsusedintheexamples’WHEREclauses,youwillnoticethatsomevaluesareenclosedinsinglequotes(suchas'Fuses'usedpreviously),andothersarenot.Youusesinglequotestodelimitstrings.Comparingavalueagainstacolumnthatisastringdatatyperequiresthedelimitingquotes.Youdon’tusequotestodelimitvaluesusedwithnumericcolumns.

Thefollowingisthesameexample,exceptthisoneusesthe!=operatorinsteadof<>:

Input

SELECTvend_id,prod_nameFROMproductsWHEREvend_id!=1003;

Note: Versus

Yes,both<>and!=lookfornonmatches.!=meansnotequalto,and<>meanslessthanorgreaterthan(inotherwords,notequalto).Usewhicheveryouprefer.

CheckingforaRangeofValuesTocheckforarangeofvalues,youcanusetheBETWEENoperator.ItssyntaxisalittledifferentfromotherWHEREclauseoperatorsbecauseitrequirestwovalues:thebeginningandendoftherange.YoucanusetheBETWEENoperator,forexample,tocheckforallproductsthatcostbetween5and10orforalldatesthatfallbetweenspecifiedstartandenddates.

ThefollowingexampledemonstratestheuseoftheBETWEENoperatorbyretrievingallproductswithapricebetween5and10:

InputClickheretoviewcodeimage

SELECTprod_name,prod_priceFROMproductsWHEREprod_priceBETWEEN5AND10;

OutputClickheretoviewcodeimage

+–––––-+––––+|prod_name|prod_price|+–––––-+––––+|.5tonanvil|5.99||1tonanvil|9.99||Birdseed|10||Oilcan|8.99||TNT(5sticks)|10|+–––––-+––––+

Analysis

Asshowninthisexample,whenyouuseBETWEEN,youmustspecifytwovalues—thelowendandhighendofthedesiredrange.YoumustalsoseparatethetwovaluesbytheANDkeyword.BETWEENmatchesallthevaluesintherange,includingthespecifiedrangestartandendvalues.

CheckingforNoValueWhencreatingatable,thetabledesignercanspecifywhetherindividualcolumnsmaycontainnovalue.Whenacolumncontainsnovalue,itissaidtocontainaNULLvalue.Columnsdestinedtocontainoptionaldataareoftencreatedthisway.

NULL

Novalue,asopposedtoafieldcontaining0,oranemptystring,orjustspaces.

TheSELECTstatementhasaspecialWHEREclausethatyoucanusetocheckforcolumnswithNULLvalues—theISNULLclause.Thesyntaxlookslikethis:

Input

SELECTprod_nameFROMproductsWHEREprod_priceISNULL;

Thisstatementreturnsalistofallproductsthathavenoprice(anemptyprod_pricefield,notapriceof0),andbecausetherearenone,nodataisreturned.Thecustomerstable,however,doescontaincolumnswithNULLvalues—thecust_emailcolumncontainsNULLifacustomerhasnoemailaddressonfile:

Input

SELECTcust_idFROMcustomersWHEREcust_emailISNULL;

Output+–––+|cust_id|+–––+|10002||10005|+–––+

Caution: andNonmatches

Youmightexpectthatwhenyoufiltertoselectallrowsthatdonothaveaparticularvalue,rowswithaNULLwillbereturned.Buttheywillnot.Becauseofthespecialmeaningofunknown,thedatabasedoesnotknowwhetherornottheymatch,andsotheyarenotreturnedwhenfilteringformatchesorwhenfilteringfornon-matches.

Whenfilteringdata,makesuretoverifythattherowswithaNULLinthefilteredcolumnarereallypresentinthereturneddata.

SummaryInthislesson,youlearnedhowtofilterreturneddatausingtheSELECTstatement’sWHEREclause.Youlearnedhowtotestforequality,non-equality,greaterthanandlessthan,valueranges,andNULLvalues.

Lesson7.AdvancedDataFiltering

ThislessonshowsyouhowtocombineWHEREclausestocreatepowerfulandsophisticatedsearchconditions,andhowtousetheNOTandINoperators.

Combining ClausesAlltheWHEREclausesintroducedinLesson6,“FilteringData,”filterdataonasinglecriterion.Foragreaterdegreeoffiltercontrol,OracleallowsyoutospecifymultipleWHEREclauses.Youmayusetheseclausesintwoways:asANDclausesorasORclauses.

Operator

AspecialkeywordusedtojoinorchangeclausesinaWHEREclause.Alsoknownaslogicaloperators.

Usingthe OperatorTofilterbymorethanonecolumn,youusetheANDoperatortoappendconditionstoyourWHEREclause.Thefollowingcodedemonstratesthis:

InputClickheretoviewcodeimage

SELECTprod_id,prod_price,prod_nameFROMproductsWHEREvend_id=1003ANDprod_price<=10;

Analysis

TheprecedingSQLstatementretrievestheproductnameandpriceforallproductsmadebyvendor1003aslongasthepriceis10orless.TheWHEREclauseinthisSELECTstatementismadeupoftwoconditions,andthekeywordANDisusedtojointhem.ANDinstructstheDBMStoreturnonlyrowsthatmeetalltheconditionsspecified.Ifaproductismadebyvendor1003butitcostsmorethan10,itisnotretrieved.Similarly,productsthatcostlessthan10thataremadebyavendorotherthantheonespecifiedarenotretrieved.TheoutputgeneratedbythisSQLstatementisasfollows:

OutputClickheretoviewcodeimage

+–––+––––+–––––-+|prod_id|prod_price|prod_name|+–––+––––+–––––-+|FB|10|Birdseed||FC|2.5|Carrots||SLING|4.49|Sling||TNT1|2.5|TNT(1stick)||TNT2|10|TNT(5sticks)|+–––+––––+–––––-+

AND

AkeywordusedinaWHEREclausetospecifythatonlyrowsmatchingallthespecifiedconditionsshouldberetrieved.

ThepreviousexamplecontainedasingleANDclauseandwasthusmadeupoftwofilterconditions.Youcoulduseadditionalfilterconditionsaswell,eachseparatedbyanANDkeyword.

Note:No ClauseSpecified

Asbefore,IomittedtheORDERBYclauseinmanyoftheseexamples.FeelfreetoaddanORDERBYclauseifyouwant.

Usingthe OperatorTheORoperatorisexactlytheoppositeofAND.TheORoperatorinstructsOracletoretrieverowsthatmatcheithercondition.

LookatthefollowingSELECTstatement:

InputClickheretoviewcodeimage

SELECTprod_name,prod_priceFROMproductsWHEREvend_id=1002ORvend_id=1003;

Analysis

TheprecedingSQLstatementretrievestheproductnameandpriceforanyproductsmadebyeitherofthetwospecifiedvendors.TheORoperatortellstheDBMStomatcheithercondition,notboth.IfanANDoperatorhadbeenusedhere,nodatawouldbereturned(itwouldhavecreatedaWHEREclausethatcouldneverbematched).TheoutputgeneratedbythisSQLstatementisasfollows:

OutputClickheretoviewcodeimage

+–––––-+––––+|prod_name|prod_price|+–––––-+––––+|Detonator|13||Birdseed|10||Carrots|2.5||Fuses|3.42||Oilcan|8.99||Safe|50||Sling|4.49||TNT(1stick)|2.5||TNT(5sticks)|10|

+–––––-+––––+

OR

AkeywordusedinaWHEREclausetospecifythatanyrowsmatchingeitherofthespecifiedconditionsshouldberetrieved.

UnderstandingOrderofEvaluationWHEREclausescancontainanynumberofANDandORoperators.Combiningthetwoenablesyoutoperformsophisticatedandcomplexfiltering.

ButcombiningANDandORoperatorspresentsaninterestingproblem.Todemonstratethis,lookatanexample.Youneedalistofallproductscosting10ormoremadebyvendors1002and1003.ThefollowingSELECTstatementusesacombinationofANDandORoperatorstobuildaWHEREclause:

InputClickheretoviewcodeimage

SELECTprod_name,prod_priceFROMproductsWHEREvend_id=1002ORvend_id=1003ANDprod_price>=10;

OutputClickheretoviewcodeimage

+–––––-+––––+|prod_name|prod_price|+–––––-+––––+|Detonator|13||Birdseed|10||Fuses|3.42||Oilcan|8.99||Safe|50||TNT(5sticks)|10|+–––––-+––––+

Analysis

Lookatthepreviouslylistedresults.Twooftherowsreturnedhavepriceslessthan10—so,obviously,therowswerenotfilteredasintended.Whydidthishappen?Theansweristheorderofevaluation.SQL(likemostlanguages)processesANDoperatorsbeforeORoperators.WhenSQLseestheprecedingWHEREclause,itreadsproductsmadebyvendor1002regardlessofprice,andanyproductscosting10ormoremadebyvendor1003.Inotherwords,becauseANDrankshigherintheorderofevaluation,thewrongoperatorswerejoinedtogether.

Thesolutiontothisproblemistouseparenthesestoexplicitlygrouprelatedoperators.TakealookatthefollowingSELECTstatementandoutput:

InputClickheretoviewcodeimage

SELECTprod_name,prod_priceFROMproductsWHERE(vend_id=1002ORvend_id=1003)ANDprod_price>=10;

OutputClickheretoviewcodeimage

+–––––-+––––+|prod_name|prod_price|+–––––-+––––+|Detonator|13||Birdseed|10||Safe|50||TNT(5sticks)|10|+–––––-+––––+

Analysis

TheonlydifferencebetweenthisSELECTstatementandtheearlieroneisthat,inthisstatement,thefirsttwoWHEREclauseconditionsareenclosedwithinparentheses.BecauseparentheseshaveahigherorderofevaluationthaneitherANDorORoperators,theDBMSfirstfilterstheORconditionwithinthoseparentheses.TheSQLstatementthenbecomesanyproductsmadebyeithervendor1002orvendor1003costing10orgreater,whichisexactlywhatyouwant.

Tip:UsingParenthesesin Clauses

WheneveryouwriteWHEREclausesthatusebothANDandORoperators,useparenthesestoexplicitlygroupoperators.Don’teverrelyonthedefaultevaluationorder,evenifitisexactlywhatyouwant.Thereisnodownsidetousingparentheses,andyouarealwaysbetteroffeliminatinganyambiguity.

Usingthe OperatorParentheseshaveanotherverydifferentuseinWHEREclauses.YouusetheINoperatortospecifyarangeofconditions,anyofwhichcanbematched.INtakesacomma-delimitedlistofvalidvalues,allenclosedwithinparentheses.Thefollowingexampledemonstratesthis:

Input

SELECTprod_name,prod_priceFROMproductsWHEREvend_idIN(1002,1003)ORDERBYprod_name;

Output

Clickheretoviewcodeimage

+–––––-+––––+|prod_name|prod_price|+–––––-+––––+|Birdseed|10||Carrots|2.5||Detonator|13||Fuses|3.42||Oilcan|8.99||Safe|50||Sling|4.49||TNT(1stick)|2.5||TNT(5sticks)|10|+–––––-+––––+

Analysis

TheSELECTstatementretrievesallproductsmadebyvendor1002andvendor1003.Acomma-delimitedlistofvalidvaluesfollowstheINoperator,andyoumustenclosetheentirelistwithinparentheses.

IfyouarethinkingthattheINoperatoraccomplishesthesamegoalasOR,youareright.ThefollowingSQLstatementaccomplishestheexactsamethingasthepreviousexample:

InputClickheretoviewcodeimage

SELECTprod_name,prod_priceFROMproductsWHEREvend_id=1002ORvend_id=1003ORDERBYprod_name;

OutputClickheretoviewcodeimage

+–––––-+––––+|prod_name|prod_price|+–––––-+––––+|Birdseed|10||Carrots|2.5||Detonator|13||Fuses|3.42||Oilcan|8.99||Safe|50||Sling|4.49||TNT(1stick)|2.5||TNT(5sticks)|10|+–––––-+––––+

WhyusetheINoperator?Theadvantagesare

Whenyouareworkingwithlonglistsofvalidoptions,theINoperatorsyntaxisfarcleanerandeasiertoread.

TheorderofevaluationiseasiertomanagewhenyouuseIN(astherearefewer

operatorsused).

INoperatorsalmostalwaysexecutemorequicklythanlistsofORoperators(althoughyouwon’tseeanyperformancedifferencewithveryshortlistsliketheonesusedhere).

ThebiggestadvantageofINisthattheINoperatorcancontainanotherSELECTstatement,enablingyoutobuildhighlydynamicWHEREclauses.You’lllookatthisindetailinLesson14,“WorkingwithSubqueries.”

IN

AkeywordusedinaWHEREclausetospecifyalistofvaluestobematchedusinganORcomparison.

Usingthe OperatorTheWHEREclause’sNOToperatorhasonefunctionandonefunctiononly—NOTnegateswhateverconditioncomesnext.

NOT

AkeywordusedinaWHEREclausetonegateacondition.

ThefollowingexampledemonstratestheuseofNOT.Tolisttheproductsmadebyallvendorsexceptvendors1002and1003,youcanusethefollowing:

InputClickheretoviewcodeimage

SELECTprod_name,prod_priceFROMproductsWHEREvend_idNOTIN(1002,1003)ORDERBYprod_name;

Output+––––—+––––+|prod_name|prod_price|+––––—+––––+|.5tonanvil|5.99||1tonanvil|9.99||2tonanvil|14.99||JetPack1000|35||JetPack2000|55|+––––—+––––+

Analysis

TheNOTherenegatestheconditionthatfollowsit;soinsteadofmatchingvend_idto1002or1003,Oraclematchesvend_idtoanythingthatisnot1002or1003.

SowhyuseNOT?Well,forsimpleWHEREclauses,reallynoadvantageexiststousing

NOT.NOTisusefulinmorecomplexclauses.Forexample,usingNOTinconjunctionwithanINoperatormakesitsimpletofindallrowsthatdonotmatchalistofcriteria.

SummaryThislessonpickedupwherethelastlessonleftoffandtaughtyouhowtocombineWHEREclauseswiththeANDandORoperators.Youalsolearnedhowtoexplicitlymanagetheorderofevaluation,andhowtousetheINandNOToperators.

Lesson8.UsingWildcardFiltering

Inthislesson,you’lllearnwhatwildcardsare,howtousethem,andhowtoperformwildcardsearchesusingtheLIKEoperatorforsophisticatedfilteringofretrieveddata.

Usingthe OperatorAllthepreviousoperatorswestudiedfilteragainstknownvalues.Beitmatchingoneormorevalues,testingforgreater-thanorless-thanknownvalues,orcheckingarangeofvalues,thecommondenominatoristhatthevaluesusedinthefilteringareknown.Butfilteringdatathatwaydoesnotalwayswork.Forexample,howcouldyousearchforallproductsthatcontainedthetextanvilwithintheproductname?Thatcannotbedonewithsimplecomparisonoperators;that’sajobforwildcardsearching.Usingwildcards,youcancreatesearchpatternsthatcanbecomparedagainstyourdata.Inthisexample,ifyouwanttofindallproductsthatcontainthewordsanvil,youcouldconstructawildcardsearchpatternenablingyoutofindthatanviltextanywherewithinaproductname.

Wildcards

Specialcharactersusedtomatchpartsofavalue.

Searchpattern

Asearchconditionmadeupofliteraltext,wildcardcharacters,oranycombinationofthetwo.

ThewildcardsthemselvesareactuallycharactersthathavespecialmeaningswithinSQLWHEREclauses,andSQLsupportsseveralwildcardtypes.

Tousewildcardsinsearchclauses,youmustusetheLIKEoperator.LIKEinstructsOracletocomparethefollowingsearchpatternusingawildcardmatchratherthanastraightequalitymatch.

Note:Predicates

Whenisanoperatornotanoperator?Whenitisapredicate.Technically,LIKEisapredicate,notanoperator.Theendresultisthesame;justbeawareofthistermincaseyourunacrossitintheOraclePL/SQLdocumentation.

SearchingwiththePercentSign( )WildcardThemostfrequentlyusedwildcardisthepercentsign(%).Inasearchstring,%meansmatchanynumberofoccurrencesofanycharacter.Forexample,tofindallproductsthatstartwiththewordjet,youcanissuethefollowingSELECTstatement:

Input

SELECTprod_id,prod_nameFROMproductsWHEREprod_nameLIKE‘Jet%’;

Output+–––+––––—+|prod_id|prod_name|+–––+––––—+|JP1000|JetPack1000||JP2000|JetPack2000|+–––+––––—+

Analysis

Thisexampleusesasearchpatternof'Jet%'.Whenthisclauseisevaluated,anyvaluethatstartswithJetisretrieved.The%tellsOracletoacceptanycharactersafterthewordJet,regardlessofhowmanycharactersthereare.

Note:Case-Sensitivity

AsnotedinLesson6,“FilteringData,”dependingonhowOracleisconfigured,searchesmightbecasesensitive,inwhichcase'jet%'wouldnotmatchJetPack1000.

Youcanusewildcardsanywhereinthesearchpattern,andusemultiplewildcardsaswell.Thefollowingexampleusestwowildcards,oneateitherendofthepattern:

InputClickheretoviewcodeimage

SELECTprod_id,prod_nameFROMproductsWHEREprod_nameLIKE‘%anvil%’;

Output+–––+––––—+|prod_id|prod_name|+–––+––––—+|ANV01|.5tonanvil||ANV02|1tonanvil||ANV03|2tonanvil|+–––+––––—+

Analysis

Thesearchpattern'%anvil%'meansmatchanyvaluethatcontainsthetextanvilanywherewithinit,regardlessofanycharactersbeforeorafterthattext.

Youcanalsousewildcardsinthemiddleofasearchpattern,althoughthatrarelytendstobeuseful.

Itisimportanttonotethat,inadditiontomatchingoneormorecharacters,%alsomatcheszerocharacters.%representszero,one,ormorecharactersatthespecifiedlocationinthesearchpattern.

Note:WatchforTrailingSpaces

Trailingspacescaninterferewithwildcardmatching.Forexample,theclauseWHEREprod_nameLIKE'%anvil'mightnotmatchrowsiftherewereadditionalcharactersafterthefinall.Onesimplesolutiontothisproblemistoalwaysappendafinal%tothesearchpattern.Abettersolutionistotrimthespacesusingfunctions,discussedinLesson11,“UsingDataManipulationFunctions.”

Caution:Watchfor

Althoughitmightseemthatthe%wildcardmatchesanything,thereisoneexception:NULL.NoteventheclauseWHEREprod_nameLIKE'%'willmatcharowwiththevalueNULLastheproductname.

Tip:Searchingfor

Here’safunquestion.Howwouldyoucreateasearchpatterntolookforthetext@itself(insteadof@matchingmultiplecharacters)?Theansweristousetwo@’s,asin@@.Thisisknownasescaping.

SearchingwiththeUnderscore(_)WildcardAnotherusefulwildcardistheunderscore(_).Theunderscoreisusedjustlike%,butinsteadofmatchingmultiplecharacters,theunderscorematchesjustasinglecharacter.

Takealookatthisexample:

InputClickheretoviewcodeimage

SELECTprod_id,prod_nameFROMproductsWHEREprod_nameLIKE‘_tonanvil%’;

Output+–––+––––-+|prod_id|prod_name|+–––+––––-+|ANV02|1tonanvil||ANV03|2tonanvil|+–––+––––-+

Analysis

ThesearchpatternusedinthisWHEREclausespecifiesawildcardfollowedbyliteraltext.Theresultsshownaretheonlyrowsthatmatchthesearchpattern:Theunderscorematches1inthefirstrowand2inthesecondrow.The.5tonanvilproductdidnotmatchbecausethesearchpatternmatchedasinglecharacter,nottwo.Thesearchpatternalsoendswithawildcard,justtobesafe(seetheearlier“WatchforTrailingSpaces”

note).

Bycontrast,thefollowingSELECTstatementusesthe%wildcardandreturnsthreematchingproducts:

InputClickheretoviewcodeimage

SELECTprod_id,prod_nameFROMproductsWHEREprod_nameLIKE‘%tonanvil%’;

Output+–––+––––—+|prod_id|prod_name|+–––+––––—+|ANV01|.5tonanvil||ANV02|1tonanvil||ANV03|2tonanvil|+–––+––––—+

Unlike%,whichcanmatchzerocharacters,_alwaysmatchesonecharacter—nomoreandnoless.

TipsforUsingWildcardsAsyoucansee,Oracle’swildcardsareextremelypowerful.Butthatpowercomeswithaprice:Wildcardsearchestypicallytakefarlongertoprocessthananyothersearchtypesdiscussedpreviously.Herearesometipstokeepinmindwhenusingwildcards:

Don’toverusewildcards.Ifanothersearchoperatorwilldo,useitinstead.

Whenyoudousewildcards,trytonotusethematthebeginningofthesearchpatternunlessabsolutelynecessary.Searchpatternsthatbeginwithwildcardsaretheslowesttoprocess.

Paycarefulattentiontotheplacementofthewildcardsymbols.Iftheyaremisplaced,youmightnotreturnthedatayouintended.

Havingsaidthat,wildcardsareanimportantandusefulsearchtoolthatyouwillusefrequently.

SummaryInthislesson,youlearnedwhatwildcardsareandhowtouseSQLwildcardsinyourWHEREclauses.Youalsolearnedthatyoushouldusewildcardscarefullyandneveroverusethem.

Lesson9.SearchingUsingRegularExpressions

Inthislesson,you’lllearnhowtouseregularexpressionswithinOraclePL/SQLWHEREclausesforgreatercontroloverdatafiltering.

UnderstandingRegularExpressionsThefilteringexamplesintheprevioustwolessonsenabledyoutolocatedatausingmatches,comparisons,andwildcardoperators.Forbasicfiltering(andevensomenot-so-basicfiltering),thismightbeenough.Butasthecomplexityoffilteringconditionsgrows,sodoesthecomplexityoftheWHEREclausesthemselves.

Andthisiswhereregularexpressionsbecomeuseful.Regularexpressionsarepartofaspeciallanguageusedtomatchtext.Ifyouneededtoextractphonenumbersfromatextfile,youmightusearegularexpression.Ifyouneededtolocateallfileswithdigitsinthemiddleoftheirnames,youmightusearegularexpression.Ifyouwantedtofindallrepeatedwordsinablockoftext,youmightusearegularexpression.AndifyouwantedtoreplaceallURLsinapagewithactualHTMLlinkstothosesameURLs,yes,youmightusearegularexpression(ortwo,forthislastexample).

Regularexpressionsaresupportedinallsortsofprogramminglanguages,texteditors,operatingsystems,andmore.Savvyprogrammersandnetworkmanagershavelongregardedregularexpressionsasavitalcomponentoftheirtechnicaltoolboxes.

Regularexpressionsarecreatedusingtheregularexpressionlanguage,aspecializedlanguagedesignedtodoeverythingthatwasjustdiscussedandmuchmore.Likeanylanguage,regularexpressionshaveaspecialsyntaxandinstructionsthatyoumustlearn.

Note:ToLearnMore

Fullcoverageofregularexpressionsisbeyondthescopeofthislesson.Althoughthebasicsarecoveredhere,foramorethoroughintroductiontoregularexpressions,youmightwanttoobtainacopyofmySamsTeachYourselfRegularExpressionsin10Minutes(ISBN0672325667).

UsingOraclePL/SQLRegularExpressionsSowhatdoesthishavetodowithOracle?Asalreadyexplained,allregularexpressionsdoismatchtext,comparingapattern(theregularexpression)withastringoftext.PL/SQLprovidesrathersophisticatedsupportforregularexpressionsthatyoucanuseinWHEREclauses,allowingyoutospecifyregularexpressionsthatfilterdataretrievedusingSELECT.

Note:NotJustin Clauses

PL/SQLprovidesfourfunctionswithwhichtoaccessregularexpressions.Inthislesson,wefocusonlyonusingregularexpressionstofilterdata,andsoweonlyusetheREGEXP_LIKE()function,andwedonotuseREGEXP_REPLACE()(usedtoreplacecharactersinastring),orREGEXP_INSTR()andREGEXP_SUBSTR()(bothusedtoperformsearchesforsubstringswithinstrings).ThereasonIpointthisoutissothatyouareawarethatthisadditionalfunctionalityexists,becausetheregularexpressionsexamplesyou’lllearnwhileusingREGEXP_LIKE()inthislessonalsoapplytothoseotherfunctions.

Thiswillallbecomemuchclearerwithsomeexamples.

BasicCharacterMatchingWe’llstartwithasimpleexample.Thefollowingstatementretrievesallrowswherecolumnprod_namecontainsthetext1000:

InputClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,‘1000’)ORDERBYprod_name;

Output+––––—+|prod_name|+––––—+|JetPack1000|+––––—+

Analysis

ThisstatementlooksmuchliketheonesthatusedLIKE(inLesson8,“UsingWildcardFiltering”),exceptthattheLIKEhasbeenreplacedwithaREGEXP_LIKE()functioncall.ThistellsOracletotreatwhatfollowsasaregularexpression(onethatjustmatchestheliteraltext1000).

Note:That’sanOdd Clause

Beforegoingfurther,let’stakeanotherlookattheWHEREclausewejustused.EveryWHEREclauseyou’veseenthusfarrequiredthatyoupassitacolumnnameandavalue,aswellasanoperator(=,orLIKE,forexample).WhenOracleprocessestheWHEREclauses,theresultiseithertrue,inwhichcasetherowisretrieved,orfalse,inwhichcaseitisnot.WHEREREGEXP_LIKE(prod_name,'1000')isdifferent;it’safunctionthattakesparameters.Sowhatisactuallybeingchecked?TheansweristhatREGEXP_LIKE()isindeedreturningtrueorfalse,andwhentrue(amatchisfound),thatrowmatchestheWHEREclauseandisreturned.

So,whybotherusingaregularexpression?Intheexamplejustused,regularexpressionsreallyaddnovalue(andprobablyhurtperformance),butconsiderthisnextexample:

InputClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,’.000’)ORDERBYprod_name;

Output+––––—+|prod_name|+––––—+|JetPack1000||JetPack2000|+––––—+

Analysis

Heretheregularexpression.000wasused..isaspecialcharacterintheregularexpressionlanguage.Itmeansmatchanysinglecharacter,andsoboth1000and2000matchedandwerereturned.

Ofcourse,thisparticularexamplecouldalsohavebeenaccomplishedusingLIKEandwildcards(asdiscussedinLesson8).

Note: Versus

ThereisoneveryimportantdifferencebetweenLIKEandREGEXP.Lookatthesetwostatements:

SELECTprod_nameFROMproductsWHEREprod_nameLIKE‘1000’ORDERBYprod_name;

andClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,‘1000’)ORDERBYprod_name;

Ifyouweretotrythemboth,youwoulddiscoverthatthefirstreturnsnodataandthesecondreturnsonerow.Whyisthis?

AsshowninLesson8,LIKEmatchesanentirecolumn.Ifthetexttobematchedexistedinthemiddleofacolumnvalue,LIKEwouldnotfinditandtherowwouldnotbereturned(unlesswildcardcharacterswereused).REGEXP_LIKE(),ontheotherhand,looksformatcheswithincolumnvalues,andsoifthetexttobematchedexistedinthemiddleofacolumnvalue,REGEXP_LIKE()wouldfinditandtherowwouldbereturned.Thisisaveryimportantdistinction.

SocanREGEXP_LIKE()beusedtomatchentirecolumnvalues(sothatitfunctionslikeLIKE)?Actually,yes,usingthe^and$anchors,aswillbeexplainedlaterinthislesson.

Tip:MatchesAreCaseSensitive

RegularexpressionmatchinginOracleiscasesensitive.

Performing MatchesTosearchforoneoftwostrings(eitheroneortheother),use|asshownhere:

InputClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,‘1000|2000’)ORDERBYprod_name;

Output+––––—+|prod_name|+––––—+

|JetPack1000||JetPack2000|+––––—+

Analysis

Heretheregularexpression1000|2000wasused.|istheregularexpressionORoperator.Itmeansmatchoneortheother,andsoboth1000and2000matchedandwerereturned.

Using|isfunctionallysimilartousingORstatementsinSELECTstatements,withmultipleORconditionsbeingconsolidatedintoasingleregularexpression.

Tip:MoreThanTwo Conditions

MorethantwoORconditionsmaybespecified.Forexample,'1000|2000|3000'wouldmatch1000or2000or3000.

MatchingOneofSeveralCharacters.matchesanysinglecharacter.Butwhatifyouwantedtomatchonlyspecificcharacters?Youcandothisbyspecifyingasetofcharactersenclosedwithin[and],asshownhere:

InputClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,‘[123]ton’)ORDERBYprod_name;

Output+––––-+|prod_name|+––––-+|1tonanvil||2tonanvil|+––––-+

Analysis

Heretheregularexpression[123]tonwasused.[123]definesasetofcharacters,andhereitmeansmatch1or2or3,soboth1tonand2tonmatchedandwerereturned(therewasno3ton).

Asyouhavejustseen,[]isanotherformofORstatement.Infact,theregularexpression[123]Tonisshorthandfor[1|2|3]ton,whichalsowouldhaveworked.Butthe[]charactersareneededtodefinewhattheORstatementislookingfor.Tobetterunderstandthis,lookatthenextexample:

InputClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,‘1|2|3ton’)ORDERBYprod_name;

Output+–––––+|prod_name|+–––––+|1tonanvil||2tonanvil||JetPack1000||JetPack2000||TNT(1stick)|+–––––+

Analysis

Well,thatdidnotwork.Thetworequiredrowswereretrieved,butsowerethreeothers.ThishappenedbecauseOracleassumedthatyoumeant‘1’or‘2’or‘3ton’,andsoanyrowswithproductnamescontaining1or2werealsomatched.The|characterappliestotheentirestringunlessitisenclosedwithaset.

Setsofcharacterscanalsobenegated.Thatis,they’llmatchanythingbutthespecifiedcharacters.Tonegateacharacterset,placea^atthestartoftheset.So,whereas[123]matchescharacters1,2,or3,[^123]matchesanythingbutthosecharacters.Here’sanexample:

InputClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,‘[^123]ton’)ORDERBYprod_name;

Output+–––––+|prod_name|+–––––+|.5tonanvil|+–––––+

Analysis

[^123]meansmatchanythingotherthanthecharacters1,2,and3,andso[^123]tonmatchedtheonlyotheranvil.

MatchingRangesSetscanbeusedtodefineoneormorecharacterstobematched.Forexample,thefollowingwillmatchdigits0through9:

[0123456789]

Tosimplifythistypeofset,-canbeusedtodefinearange.Thefollowingisfunctionallyidenticaltothelistofdigitsjustshown:

[0-9]

Rangesarenotlimitedtocompletesets—[1-3]and[6-9]arevalidranges,too.Inaddition,rangesneednotbenumeric,andso[a-z]willmatchanyalphabeticalcharacter.

Hereisanexample:

InputClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,‘[1-5]ton’)ORDERBYprod_name;

Output+––––—+|prod_name|+––––—+|.5tonanvil||1tonanvil||2tonanvil|+––––—+

Analysis

Heretheregularexpression[1-5]tonwasused.[1-5]definesarange,andsothisexpressionmeansmatch1through5,andsothreematcheswerereturned..5tonwasreturnedbecause5tonmatched(withoutthe.character).

MatchingSpecialCharactersTheregularexpressionlanguageismadeupofspecialcharactersthathavespecificmeanings.You’vealreadyseen.,[],|,and-,andthereareothers,too.Thisbegsthequestion:Ifyouneededtomatchthosecharacters,howwouldyoudoso?Forexample,ifyouwantedtofindvaluesthatcontainthe.character,howwouldyousearchforit?Lookatthisexample:

InputClickheretoviewcodeimage

SELECTvend_nameFROMvendorsWHEREREGEXP_LIKE(vend_name,‘.’)ORDERBYvend_name;

Output+–––––-+|vend_name|

+–––––-+|ACME||AnvilsRUs||FurballInc.||JetSet||JouetsEtOurs||LTSupplies|+–––––-+

Analysis

Thatdidnotwork..matchesanycharacter,andsoeveryrowwasretrieved.

Tomatchspecialcharacters,theymustbeprecededby\.So,\-meansfind–and\.meansfind.:

InputClickheretoviewcodeimage

SELECTvend_nameFROMvendorsWHEREREGEXP_LIKE(vend_name,‘.’)ORDERBYvend_name;

Output+––––—+|vend_name|+––––—+|FurballInc.|+––––—+

Analysis

Thatworked.\.matches.,andsoonlyasinglerowwasretrieved.Thisprocessisknownasescaping(yousawthattermusedinthelastlesson,too),andallcharactersthathavespecialsignificanceinregularexpressionsmustbeescapedthisway.Thisincludes.,|,[],andalltheotherspecialcharactersusedthusfar.

Tip:ToMatch\

Tomatchthebackslashcharacteritself(\),youneedtoescapeitanduse\\.

MatchingCharacterClassesTherearematchesthatyou’llfindyourselfusingfrequently,suchasdigits,orallalphabeticalcharacters,orallalphanumericalcharacters,andsoon.Tomakeworkingwiththeseeasier,youcanusepredefinedcharactersetsknownascharacterclasses.Table9.1listssomeofthesecharacterclassesandwhattheymean.

TABLE9.1CharacterClasses

MatchingMultipleInstancesAlltheregularexpressionsusedthusfarattempttomatchasingleoccurrence.Ifthereisamatch,therowisretrieved,andifnot,nothingisretrieved.Butsometimesyou’llrequiregreatercontroloverthenumberofmatches.Forexample,youmightwanttolocateallnumbersregardlessofhowmanydigitsthenumbercontains,oryoumightwanttolocateawordbutalsobeabletoaccommodateatrailingsifoneexists,andsoon.

Thiscanbeaccomplishedusingtheregularexpressionsrepetitionmetacharacters,listedinTable9.2.

TABLE9.2RepetitionMetacharacters

Followingaresomeexamples:

InputClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,‘\(\dsticks?\)’)ORDERBYprod_name;

Output+–––––-+|prod_name|+–––––-+|TNT(1stick)||TNT(5sticks)|+–––––-+

Analysis

Regularexpression'\(\dsticks?\)'requiressomeexplanation.\(matches(,\dmatchesanydigit(1and5inthisexample),sticks?matchesstickandsticks(the?afterthesmakesthatsoptionalbecause?matches0or1occurrenceofwhateveritfollows),and\)matchestheclosing).Without?,itwouldhavebeenverydifficulttomatchbothstickandsticks.

Here’sanotherexample.Thistimewe’lltrytomatchfourconsecutivedigits:

InputClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,‘\d{4}’)ORDERBYprod_name;

Output+––––—+|prod_name|+––––—+|JetPack1000||JetPack2000|+––––—+

Analysis

Asexplainedpreviously,\dmatchesanydigit.{4}requiresexactlyfouroccurrencesofwhateveritfollows(anydigit),andso\d{4}matchesanyfourconsecutivedigits.

Itisworthnotingthatwhenyouuseregularexpressions,thereisalmostalwaysmorethanonewaytowriteaspecificexpression.Thepreviousexamplecouldhavealsobeenwrittenasfollows:

InputClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,‘[0-9][0-9][0-9][0-9]’)ORDERBYprod_name;

Actually,itcouldalsohavebeenwrittenas:

InputClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,‘[0-9]{4}’)ORDERBYprod_name;

AnchorsAlltheexamplesthusfarhavematchedtextanywherewithinastring.Tomatchtextatspecificlocations,youneedtouseanchors,aslistedinTable9.3.

TABLE9.3AnchorMetacharacters

Forexample,whatifyouwantedtofindallproductsthatstartedwithanumber(includingnumbersstartingwithadecimalpoint)?Asimplesearchfor[0-9\.](or[\d\.])wouldnotworkbecauseitwouldfindmatchesanywherewithinthetext.Thesolutionistousethe^anchor,asshownhere:

InputClickheretoviewcodeimage

SELECTprod_nameFROMproductsWHEREREGEXP_LIKE(prod_name,‘^[0-9.]’)ORDERBYprod_name;

Output+––––—+|prod_name|+––––—+|.5tonanvil||1tonanvil||2tonanvil|+––––—+

Analysis

^matchesthestartofastring.Assuch,^[0-9\.]matches.oranydigitonlyiftheyarethefirstcharacterswithinastring.Withoutthe^,fourotherrowswouldhavebeenretrieved,too(thosethathavedigitsinthemiddle).

Note:TheDualPurpose

^hastwouses.Withinaset(definedusing[and]),itisusedtonegatethatset.Otherwise,itisusedtorefertothestartsofastring.

Note:Making BehaveLike

Earlierinthislesson,ImentionedthatLIKEandREGEXP_LIKE()behaveddifferentlyinthatLIKEmatchedanentirestringandREGEXP_LIKE()matchedsubstrings,too.Usinganchors,REGEXP_LIKE()canbemadetobehavejustlikeLIKEbysimplystartingeachexpressionwith^andendingitwith$.

SummaryInthislesson,youlearnedthebasicsofregularexpressions,andhowtousetheminOraclePL/SQLSELECTstatementsviatheREGEXP_LIKE()function.

Lesson10.CreatingCalculatedFields

Inthislesson,youwilllearnwhatcalculatedfieldsare,howtocreatethem,andhowtousealiasestorefertothemfromwithinyourapplication.

UnderstandingCalculatedFieldsDatastoredwithinadatabase’stablesisoftennotavailableintheexactformatneededbyyourapplications.Herearesomeexamples:

Youneedtodisplayafieldcontainingthenameofacompanyalongwiththecompany’slocation,butthatinformationisstoredinseparatedtablecolumns.

City,state,andZIPCodearestoredinseparatecolumns(astheyshouldbe),butyourmailinglabelprintingprogramneedsthemretrievedasonecorrectlyformattedfield.

Columndataisinmixedupper-andlowercase,andyourreportneedsalldatapresentedinuppercase.

Anorderitemstablestoresitempriceandquantitybutnottheexpandedprice(pricemultipliedbyquantity)ofeachitem.Toprintinvoices,youneedthatexpandedprice.

Youneedtotal,averages,orothercalculationsbasedontabledata.

Ineachoftheseexamples,thedatastoredinthetableisnotexactlywhatyourapplicationneeds.Ratherthanretrievethedataasitisandthenreformatitwithinyourclientapplicationorreport,whatyoureallywantistoretrieveconverted,calculated,orreformatteddatadirectlyfromthedatabase.

Thisiswherecalculatedfieldscomein.Unlikeallthecolumnsweretrievedinthelessonsthusfar,calculatedfieldsdon’tactuallyexistindatabasetables.Rather,acalculatedfieldiscreatedontheflyinaSQLSELECTstatement.

Field

Essentiallymeansthesamethingascolumnandoftenisusedinterchangeably,althoughdatabasecolumnsaretypicallycalledcolumnsandthetermfieldsisnormallyusedinconjunctionwithcalculatedfields.

ItisimportanttonotethatonlythedatabaseknowswhichcolumnsinaSELECTstatementareactualtablecolumnsandwhicharecalculatedfields.Fromtheperspectiveofaclient(forexample,yourapplication),acalculatedfield’sdataisreturnedinthesamewayasdatafromanyothercolumn.

Tip:ClientVersusServerFormatting

ManyoftheconversionsandreformattingthatcanbeperformedinSQLstatementscanalsobeperformeddirectlyinyourclientapplication.However,asarule,itisfarquickertoperformtheseoperationsonthedatabaseserverthanitistoperformthemwithintheclientbecauseDBMSsarebuilttoperformthistypeofprocessingquicklyandefficiently.

ConcatenatingFieldsTodemonstrateworkingwithcalculatedfields,let’sstartwithasimpleexample—creatingatitlemadeupoftwocolumns.

Thevendorstablecontainsvendornameandaddressinformation.Imagineyouaregeneratingavendorreportandneedtolistthevendorlocationaspartofthevendornameintheformatname(location).

Thereportwantsasinglevalue,andthedatainthetableisstoredintwocolumns:vend_nameandvend_country.Inaddition,youneedtosurroundvend_countrywithparentheses,andthosearedefinitelynotstoredinthedatabasetable.TheSELECTstatementthatreturnsthevendornamesandlocationsissimpleenough,buthowwouldyoucreatethiscombinedvalue?

Concatenate

Joiningvaluestogether(byappendingthemtoeachother)toformasinglelongvalue.

Thesolutionistoconcatenatethetwocolumns.InOracleSELECTstatements,youcanconcatenatecolumnsusingthe||operator.

Tip:No+forConcatenation

ManyDBMSsallowyoutouse+toconcatenatestrings.Oracledoesnot;youmustuse||forconcatenation.

InputClickheretoviewcodeimage

SELECTvend_name||‘,(‘||vend_country||‘)’FROMvendorsORDERBYvend_name;

OutputClickheretoviewcodeimage

+––––––––––––––––––-+|VEND_NAME||’,(‘||VEND_COUNTRY||’)’|

+––––––––––––––––––-+|ACME,(USA)||AnvilsRUs,(USA)||FurballInc.,(USA)||JetSet,(England)||JouetsEtOurs,(France)||LTSupplies,(USA)|+––––––––––––––––––-+

Analysis

||concatenatesstrings,appendingthemtoeachothertocreateonebiggerstring.ThepreviousSELECTstatementsconcatenatefourelements:

Thenamestoredinthevend_namecolumn

Astringcontainingaspaceandanopenparenthesis

Thestatestoredinthevend_countrycolumn

Astringcontainingthecloseparenthesis

Asyoucanseeintheoutputshownpreviously,theSELECTstatementreturnsasinglecolumn(acalculatedfield)containingallfouroftheseelementsasoneunit.However,theoutputcontainslotsofextraneousspacing.WhatwereallywantissomethinglikeACME,(USA).

BackinLesson8,“UsingWildcardFiltering,”Imentionedtheneedtotrimdatatoremoveanytrailingspaces.ThiscanbedoneusingthePL/SQLRTrim()function,asfollows:

InputClickheretoviewcodeimage

SELECTRTrim(vend_name)||‘,(‘||RTrim(vend_country)||‘)’FROMvendorsORDERBYvend_name;

OutputClickheretoviewcodeimage

+––––––––––––––––––-+|RTRIM(VEND_NAME)||’,(‘||RTRIM(VEND_COUNTRY)||’)’|+––––––––––––––––––-+|ACME,(USA)||AnvilsRUs,(USA)||FurballInc.,(USA)||JetSet,(England)||JouetsEtOurs,(France)||LTSupplies,(USA)|+––––––––––––––––––-+

Analysis

TheRTrim()functiontrimsallspacesfromtherightofavalue.ByusingRTrim(),the

individualcolumnsarealltrimmedproperly.

The Functions

InadditiontoRTrim()(which,asjustshown,trimstherightsideofastring),PL/SQLsupportstheuseofLTrim()(whichtrimstheleftsideofastring),andTrim()(whichtrimsboththerightandleft).

UsingAliasesTheSELECTstatementusedtoconcatenatetheaddressfieldworkswell,asshowninthepreviousoutput.Butwhatisthenameofthisnewcalculatedcolumn?Well,thetruthis,ithasnoname;itissimplyavalue.AlthoughthiscanbefineifyouarejustlookingattheresultsinaSQLquerytool,anunnamedcolumncannotbeusedwithinaclientapplicationbecausetheclienthasnowaytorefertothatcolumn.

Tosolvethisproblem,SQLsupportscolumnaliases.Analiasisjustthat—analternativenameforafieldorvalue.AliasesareassignedwiththeASkeyword.TakealookatthefollowingSELECTstatement:

InputClickheretoviewcodeimage

SELECTRTrim(vend_name)||‘,(‘||RTrim(vend_country)||‘)’ASvend_titleFROMvendorsORDERBYvend_name;

OutputClickheretoviewcodeimage

+––––––––––––––––––-+|VEND_TITLE|+––––––––––––––––––-+|ACME,(USA)||AnvilsRUs,(USA)||FurballInc.,(USA)||JetSet,(England)||JouetsEtOurs,(France)||LTSupplies,(USA)|+––––––––––––––––––-+

Analysis

TheSELECTstatementitselfisthesameastheoneusedinthepreviouscodesnippet,exceptthatherethecalculatedfieldisfollowedbythetextASvend_title.ThisinstructsSQLtocreateacalculatedfieldnamedvend_titlecontainingtheresultsofthespecifiedcalculation.Asyoucanseeintheoutput,theresultsarethesameasbefore,butthecolumnisnownamedvend_titleandanyclientapplicationcanrefertothiscolumnbyname,justasitwouldtoanyactualtablecolumn.

Tip:OtherUsesforAliases

Aliaseshaveotheruses,too.Somecommonusesincluderenamingacolumniftherealtablecolumnnamecontainsillegalcharacters(forexample,spaces)andexpandingcolumnnamesiftheoriginalnamesareeitherambiguousoreasilymisread.

Note:DerivedColumns

Aliasesarealsosometimesreferredtoasderivedcolumns,soregardlessofthetermyourunacross,theymeanthesamething.

PerformingMathematicalCalculationsAnotherfrequentuseforcalculatedfieldsisperformingmathematicalcalculationsonretrieveddata.Let’stakealookatanexample.Theorderstablecontainsallordersreceived,andtheorderitemstablecontainstheindividualitemsineachorder.ThefollowingSQLstatementretrievesalltheitemsinordernumber20005:

InputClickheretoviewcodeimage

SELECTprod_id,quantity,item_priceFROMorderitemsWHEREorder_num=20005;

OutputClickheretoviewcodeimage

+–––+–––-+––––+|prod_id|quantity|item_price|+–––+–––-+––––+|ANV01|10|5.99||ANV02|3|9.99||TNT2|5|10||FB|1|10|+–––+–––-+––––+

Theitem_pricecolumncontainstheperunitpriceforeachiteminanorder.Toexpandtheitemprice(itempricemultipliedbyquantityordered),yousimplydothefollowing:

InputClickheretoviewcodeimage

SELECTprod_id,quantity,item_price,quantity*item_priceASexpanded_priceFROMorderitems

WHEREorder_num=20005;

OutputClickheretoviewcodeimage

+–––+–––-+––––+–––––-+|prod_id|quantity|item_price|expanded_price|+–––+–––-+––––+–––––-+|ANV01|10|5.99|59.9||ANV02|3|9.99|29.97||TNT2|5|10|50||FB|1|10|10|+–––+–––-+––––+–––––-+

Analysis

Theexpanded_pricecolumnshowninthepreviousoutputisacalculatedfield;thecalculationissimplyquantity*item_price.Theclientapplicationcannowusethisnewcalculatedcolumnjustasitwouldanyothercolumn.

OraclesupportsthebasicmathematicaloperatorslistedinTable10.1.Inaddition,parenthesescanbeusedtoestablishorderofprecedence.RefertoLesson7,“AdvancedDataFiltering,”foranexplanationofprecedence.

TABLE10.1OracleMathematicalOperators

Tip:HowtoTestCalculations

SELECTprovidesagreatwaytotestandexperimentwithfunctionsandcalculations.AlthoughSELECTisusuallyusedtoretrievedatafromatable,theFROMclausecanbeomittedbyreplacingitwithaspecialtablenameddual.Forexample,SELECT3*2FROMdual;wouldreturn6,andSELECTTrim('abc')FROMdual;wouldreturnabc.Ifthatdualtablelooksvaguelyfamiliar,it’sbecauseweuseditinourfirstPL/SQLstatementbackinLesson3,“WorkingwithOracle.”

SummaryInthislesson,youlearnedwhatcalculatedfieldsareandhowtocreatethem.Weusedexamplesdemonstratingtheuseofcalculatedfieldsforbothstringconcatenationandmathematicaloperations.Inaddition,youlearnedhowtocreateandusealiasessoyourapplicationcanrefertocalculatedfields.

Lesson11.UsingDataManipulationFunctions

Inthislesson,you’lllearnwhatfunctionsare,whattypesoffunctionsOraclesupports,andhowtousethesefunctions.

UnderstandingFunctionsLikealmostanyothercomputerlanguage,SQLsupportstheuseoffunctionstomanipulatedata.Functionsareoperationsthatareusuallyperformedondata,usuallytofacilitateconversionandmanipulation.

AnexampleofafunctionistheRTrim()thatweusedinthelastlessontotrimanyspacesfromtheendofastring.

Note:FunctionsAreLessPortableThanSQL

Codethatrunsonmultiplesystemsissaidtobeportable.MostSQLstatementsarerelativelyportable,andwhendifferencesbetweenSQLimplementationsdooccur,theyareusuallynotthatdifficulttodealwith.Functions,ontheotherhand,tendtobefarlessportable.JustabouteverymajorDBMSsupportsfunctionsthatothersdon’t,andsometimesthedifferencesaresignificant.

Withcodeportabilityinmind,manySQLprogrammersoptnottouseanyimplementation-specificfeatures.Althoughthisisasomewhatnobleandidealisticview,itisnotalwaysinthebestinterestsofapplicationperformance.Ifyouoptnottousethesefunctions,youmakeyourapplicationcodeworkharder.ItmustuseothermethodstodowhattheDBMScouldhavedonemoreefficiently.

Ifyoudodecidetousefunctions,makesureyoucommentyourcodewell,sothatatalaterdate,you(oranotherdeveloper)willknowexactlytowhichSQLimplementationyouwerewriting.CodecommentingwasintroducedbackinLesson4,“RetrievingData.”

UsingFunctionsMostSQLimplementationssupportthefollowingtypesoffunctions:

Textfunctionsareusedtomanipulatestringsoftext(forexample,trimmingorpaddingvaluesandconvertingvaluestoupper-andlowercase).

Numericfunctionsareusedtoperformmathematicaloperationsonnumericdata(forexample,returningabsolutenumbersandperformingalgebraiccalculations).

Dateandtimefunctionsareusedtomanipulatedateandtimevaluesandtoextractspecificcomponentsfromthesevalues(forexample,returningdifferencesbetweendatesandcheckingdatevalidity).

SystemfunctionsreturninformationspecifictotheDBMSbeingused(forexample,returninguserlogininformationorcheckingversionspecifics).

TextManipulationFunctionsYou’vealreadyseenanexampleoftext-manipulationfunctionsinthelastlesson—theRTrim()functionwasusedtotrimwhitespacefromtheendofacolumnvalue.Hereisanotherexample,thistimeusingtheUpper()function:

InputClickheretoviewcodeimage

SELECTvend_name,Upper(vend_name)ASvend_name_upcaseFROMvendorsORDERBYvend_name;

OutputClickheretoviewcodeimage

+–––––-+––––––+|vend_name|vend_name_upcase|+–––––-+––––––+|ACME|ACME||AnvilsRUs|ANVILSRUS||FurballInc.|FURBALLINC.||JetSet|JETSET||JouetsEtOurs|JOUETSETOURS||LTSupplies|LTSUPPLIES|+–––––-+––––––+

Analysis

Asyoucansee,Upper()convertstexttouppercase,andsointhisexample,eachvendorislistedtwice,firstexactlyasstoredinthevendorstable,andthenconvertedtouppercaseascolumnvend_name_upcase.

Table11.1listssomecommonlyusedtext-manipulationfunctions.

TABLE11.1CommonlyUsedText-ManipulationFunctions

OneiteminTable11.1requiresfurtherexplanation.SOUNDEXisanalgorithmthatconvertsanystringoftextintoanalphanumericpatterndescribingthephoneticrepresentationofthattext.SOUNDEXtakesintoaccountsimilarsoundingcharactersandsyllables,enablingstringstobecomparedbyhowtheysoundratherthanhowtheyhave

beentyped.AlthoughSOUNDEXisnotaSQLconcept,Oracle(likemanyotherDBMSs)offersSOUNDEXsupport.Here’sanexampleusingtheSoundex()function.CustomerCoyoteInc.isinthecustomerstableandhasacontactnamedY.Lee.Butwhatifthatwereatypo,andthecontactactuallywassupposedtohavebeenY.Lie?Obviously,searchingbythecorrectcontactnamewouldreturnnodata,asshownhere:

InputClickheretoviewcodeimage

SELECTcust_name,cust_contactFROMcustomersWHEREcust_contact=‘Y.Lie’;

OutputClickheretoviewcodeimage

+––––-+––––—+|cust_name|cust_contact|+––––-+––––—+

NowtrythesamesearchusingtheSoundex()functiontomatchallcontactnamesthatsoundsimilartoY.Lie:

InputClickheretoviewcodeimage

SELECTcust_name,cust_contactFROMcustomersWHERESoundex(cust_contact)=Soundex(‘YLie’);

OutputClickheretoviewcodeimage

+––––-+––––—+|cust_name|cust_contact|+––––-+––––—+|CoyoteInc.|YLee|+––––-+––––—+

Analysis

Inthisexample,theWHEREclauseusestheSoundex()functiontoconvertboththecust_contactcolumnvalueandthesearchstringtotheirSOUNDEXvalues.BecauseY.LeeandY.Liesoundalike,theirSOUNDEXvaluesmatch,andsotheWHEREclausecorrectlyfilteredthedesireddata.

DateandTimeManipulationFunctionsDateandtimesarestoredintablesusingspecialdatatypesusingspecialinternalformatssotheymaybesortedorfilteredquicklyandefficiently,aswellastosavephysicalstoragespace.

Theformatusedtostoredatesandtimesisusuallyofnousetoyourapplications,andsodateandtimefunctionsarealmostalwaysusedtoread,expand,andmanipulatethesevalues.Becauseofthis,dateandtimemanipulationfunctionsaresomeofthemostimportantfunctionsinOraclePL/SQL.

Table11.2listssomecommonlyuseddateandtimemanipulationfunctions.

TABLE11.2CommonlyUsedDateandTimeManipulationFunctions

Note:TheAll-Important Function

Ifyou’veusedotherDBMSs,you’reprobablywonderingwhyPL/SQLhassofewdateandtimefunctions.OtherDBMSshavefarmore,includingshortcutsforextractingspecificvaluesfromdatesandtimes.InPL/SQL,onefunctiondoesitall—theall-importantExtract()function—asyouwillsoonsee.

ThiswouldbeagoodtimetorevisitdatafilteringusingWHERE.ThusfarwehavefiltereddatausingWHEREclausesthatcomparednumbersandtext,butfrequentlydataneedstobefilteredbydate.Filteringbydaterequiressomeextracare,andtheuseofspecialPL/SQLfunctions.

Thefirstthingtokeepinmindisthedateformattingcangettricky.Afterall,whatdateis2015-03-04?Is03themonthand04theday,orviceversa?Forthisreason,anytimeyouprovideadatetoOracle,youmustexplicitlystatehowitisformatted.

Tip:AlwaysUseFour-DigitYears

Oracleusesfour-digityears.Ifyouprovideatwo-digityear,Oraclemightnottreatitasyouwouldexpect.Assuch,itisfarsafertoalwaysuseafullfour-digityearsothatOracledoesnothavetomakeanyassumptionsforyou.

Assuch,abasicdatecomparisonshouldbesimpleenough:

InputClickheretoviewcodeimage

SELECTcust_id,order_numFROMorders

WHEREorder_date=TO_DATE(‘2015-02-01’,‘yyyy-mm-dd’);

Output+–––+–––—+|cust_id|order_num|+–––+–––—+|10001|20005|+–––+–––—+

Analysis

ThatSELECTstatementworked;itretrievedasingleorderrecord,onewithanorder_dateof2015-02-01.Topreventambiguity,theTo_Date()functionwaspassedaformattingstringofyyyy-mm-dd,whichtellsOraclethatthedateisformattedasafour-digityear,followedbyahyphen,followedbyatwo-digitmonth,followedbyanotherhyphen,andthenatwo-digitdate.

Anotherthingtokeepinmindisthatourorder_datefieldisindeedadatefield,notadateandtimefield.Ididthistosimplifythings,butintherealworld,ordermayindeedbesavedwithorderdateandordertime.Hadorder_datebeenadatetimefield,thingswouldhavegottenabitmorecomplicated.Why?BecauseWHEREorder_date=TO_DATE('2015-02-01','yyyy-mm-dd’);wouldfailif,forexample,thestoredorder_datevaluewas2015-02-0111:30:05.Eventhougharowwiththatdateispresent,itwouldnotberetrievedbecausetheWHEREmatchfailed.

ThesolutioninthiscasewouldbetoinstructOracletosearchadaterange,likethis:

InputClickheretoviewcodeimage

SELECTcust_id,order_numFROMordersWHEREorder_date>=TO_DATE(‘2015-02-01’,‘yyyy-mm-dd’)ANDorder_date<TO_DATE(‘2015-02-02’,‘yyyy-mm-dd’)

Thissametechniquecanbeusedtosearchfordateranges.Forexample,whatifyouwantedtoretrieveallordersplacedinFebruary2015?Thereareseveralsolutions,oneofwhichissimilartothepreceding:

InputClickheretoviewcodeimage

SELECTcust_id,order_numFROMordersWHEREorder_date>=TO_DATE(‘2015-02-01’,‘yyyy-mm-dd’)ANDorder_date<TO_DATE(‘2015-03-01’,‘yyyy-mm-dd’);

Output+–––+–––—+|cust_id|order_num|+–––+–––—+|10001|20005|

|10003|20006||10004|20007|+–––+–––—+

YoucouldalsousetheBETWEENoperator,discussedinLesson6,“FilteringData.”

InputClickheretoviewcodeimage

SELECTcust_id,order_numFROMordersWHEREorder_dateBETWEENTO_DATE(‘2015-02-01’,‘yyyy-mm-dd’)ANDTO_DATE(‘2015-02-28’,‘yyyy-mm-dd’);

Analysis

HereaBETWEENoperatorisusedtodefine2015-02-01and2015-02-28astherangeofdatestomatch.

Moreflexibledatearithmeticrequirestheabilitytoextractspecificpartsofadateortime.ThisiswheretheExtract()functioncomesintoplay.Asitsnamesuggests,Extract()extractspartsofdatesandtimes,allowingyoutoworkwithjusttheYEAR,MONTH,DAY,HOUR,MINUTE,andSECOND.

Here’sanothersolutiontothepreviousproblem(onethatwon’trequireyoutofigureouthowmanydaysareineachmonth,orworryaboutFebruaryinleapyears):

InputClickheretoviewcodeimage

SELECTcust_id,order_numFROMordersWHEREExtract(YearFROMorder_date)=2015ANDExtract(MonthFROMorder_date)=2

Output+–––+–––—+|cust_id|order_num|+–––+–––—+|10001|20005||10003|20006||10004|20007|+–––+–––—+

Analysis

Extract(Year)returnstheyearfromadate.Similarly,Extract(Month)returnsthemonthfromadate.WHEREExtract(YearFROMorder_date)=2015ANDExtract(MonthFROMorder_date)=2thusretrievesallrowsthathaveanorder_dateinyear2015andinmonth2.

NumericManipulationFunctionsNumericmanipulationfunctionsdojustthat—manipulatenumericdata.Thesefunctionstendtobeusedprimarilyforalgebraic,trigonometric,orgeometriccalculationsand,therefore,arenotasfrequentlyusedasstringordateandtimemanipulationfunctions.

TheironicthingisthatofallthefunctionsfoundinthemajorDBMSs,thenumericfunctionsaretheonesthataremostuniformandconsistent.Table11.3listssomeofthemorecommonlyusednumericmanipulationfunctions.

TABLE11.3CommonlyUsedNumericManipulationFunctions

SummaryInthislesson,youlearnedhowtouseSQL’sdatamanipulationfunctions,andpaidspecialattentiontoworkingwithdates.

Lesson12.SummarizingData

Inthislesson,youwilllearnwhattheSQLaggregatefunctionsareandhowtousethemtosummarizetabledata.

UsingAggregateFunctionsItisoftennecessarytosummarizedatawithoutactuallyretrievingitall,andOracleprovidesspecialfunctionsforthispurpose.Usingthesefunctions,Oraclequeriesareoftenusedtoretrievedataforanalysisandreportingpurposes.Examplesofthistypeofretrievalincludethefollowing:

Determiningthenumberofrowsinatable(orthenumberofrowsthatmeetsomeconditionorcontainaspecificvalue)

Obtainingthesumofagroupofrowsinatable

Findingthehighest,lowest,andaveragevaluesinatablecolumn(eitherforallrowsorforspecificrows)

Ineachoftheseexamples,youwantasummaryofthedatainatable,nottheactualdataitself.Therefore,returningtheactualtabledatawouldbeawasteoftimeandprocessingresources(nottomentionbandwidth).Torepeat,allyoureallywantisthesummaryinformation.

Tofacilitatethistypeofretrieval,Oraclefeaturesasetofaggregatefunctions,someofwhicharelistedinTable12.1.Thesefunctionsenableyoutoperformallthetypesofretrievaljustenumerated.

TABLE12.1SQLAggregateFunctions

AggregateFunctions

Functionsthatoperateonasetofrowstocalculateandreturnasinglevalue.

Theuseofeachofthesefunctionsisexplainedinthefollowingsections.

Note:StandardDeviation

AseriesofstandarddeviationaggregatefunctionsarealsosupportedbyOracle,butarenotcoveredinthelessons.

The FunctionAVG()isusedtoreturntheaveragevalueofaspecificcolumnbycountingboththenumberofrowsinthetableandthesumoftheirvalues.AVG()canbeusedtoreturntheaveragevalueofallcolumnsorofspecificcolumnsorrows.

ThisfirstexampleusesAVG()toreturntheaveragepriceofalltheproductsintheproductstable:

InputClickheretoviewcodeimage

SELECTAVG(prod_price)ASavg_priceFROMproducts;

Output+––––+|avg_price|+––––+|16.1335714|+––––+

Analysis

TheprecedingSELECTstatementreturnsasinglevalue,avg_price,thatcontainstheaveragepriceofallproductsintheproductstable.avg_priceisanalias,asexplainedinLesson10,“CreatingCalculatedFields.”

AVG()canalsobeusedtodeterminetheaveragevalueofspecificcolumnsorrows.Thefollowingexamplereturnstheaveragepriceofproductsofferedbyaspecificvendor:

InputClickheretoviewcodeimage

SELECTAVG(prod_price)ASavg_priceFROMproductsWHEREvend_id=1003;

Output+–––—+|avg_price|+––––+|13.2128571|+––––+

Analysis

ThisSELECTstatementdiffersfromthepreviousoneonlyinthatthisonecontainsaWHEREclause.TheWHEREclausefiltersonlyproductswithavend_idof1003,and,therefore,thevaluereturnedinavg_priceistheaverageofjustthatvendor’sproducts.

Caution:IndividualColumnsOnly

AVG()mayonlybeusedtodeterminetheaverageofaspecificnumericcolumn,andthatcolumnnamemustbespecifiedasthefunctionparameter.Toobtaintheaveragevalueofmultiplecolumns,multipleAVG()functionsmustbeused.

Note: Values

ColumnrowscontainingNULLvaluesareignoredbytheAVG()function.

The FunctionCOUNT()doesjustthat:Itcounts.UsingCOUNT(),youcandeterminethenumberofrowsinatableorthenumberofrowsthatmatchaspecificcriterion.

COUNT()canbeusedtwoways:

UseCOUNT(*)tocountthenumberofrowsinatable,whethercolumnscontainvaluesorNULLvalues.

UseCOUNT(column)tocountthenumberofrowsthathavevaluesinaspecificcolumn,ignoringNULLvalues.

Thisfirstexamplereturnsthetotalnumberofcustomersinthecustomerstable:

Input

SELECTCOUNT(*)ASnum_custFROMcustomers;

Output+–––-+|num_cust|+–––-+|5|+–––-+

Analysis

Inthisexample,COUNT(*)isusedtocountallrows,regardlessofvalues.Thecountisreturnedinnum_cust.

Thefollowingexamplecountsjustthecustomerswithanemailaddress:

InputClickheretoviewcodeimage

SELECTCOUNT(cust_email)ASnum_custFROMcustomers;

Output

+–––-+|num_cust|+–––-+|3|+–––-+

Analysis

ThisSELECTstatementusesCOUNT(cust_email)tocountonlyrowswithavalueinthecust_emailcolumn.Inthisexample,cust_emailis3(meaningthatonlythreeofthefivecustomershaveemailaddresses).

Note: Values

ColumnrowswithNULLvaluesinthemareignoredbytheCOUNT()functionifacolumnnameisspecified,butnotiftheasterisk(*)isused.

The FunctionMAX()returnsthehighestvalueinaspecifiedcolumn.MAX()requiresthatthecolumnnamebespecified,asshownhere:

InputClickheretoviewcodeimage

SELECTMAX(prod_price)ASmax_priceFROMproducts;

Output+–––—+|max_price|+–––—+|55|+–––—+

Analysis

HereMAX()returnsthepriceofthemostexpensiveitemintheproductstable.

Tip:Using withNon-NumericData

AlthoughMAX()isusuallyusedtofindthehighestnumericordatevalues,Oracleallowsittobeusedtoreturnthehighestvalueinanycolumnincludingtextualcolumns.Whenusedwithtextualdata,MAX()returnstherowthatwouldbethelastifthedataweresortedbythatcolumn.

Note: Values

ColumnrowswithNULLvaluesinthemareignoredbytheMAX()function.

The FunctionMIN()doestheexactoppositeofMAX();itreturnsthelowestvalueinaspecifiedcolumn.LikeMAX(),MIN()requiresthatthecolumnnamebespecified,asshownhere:

InputClickheretoviewcodeimage

SELECTMIN(prod_price)ASmin_priceFROMproducts;

Output+–––—+|min_price|+–––—+|2.5|+–––—+

Analysis

HereMIN()returnsthepriceoftheleastexpensiveitemintheproductstable.

Tip:Using withNon-NumericData

AswiththeMAX()function,OracleallowsMIN()tobeusedtoreturnthelowestvalueinanycolumnsincludingtextualcolumns.Whenusedwithtextualdata,MIN()returnstherowthatwouldbefirstifthedataweresortedbythatcolumn.

Note: Values

ColumnrowswithNULLvaluesinthemareignoredbytheMIN()function.

The FunctionSUM()isusedtoreturnthesum(total)ofthevaluesinaspecificcolumn.

Hereisanexampletodemonstratethis.Theorderitemstablecontainstheactualitemsinanorder,andeachitemhasanassociatedquantity.Thetotalnumberofitemsordered(thesumofallthequantityvalues)canberetrievedasfollows:

InputClickheretoviewcodeimage

SELECTSUM(quantity)ASitems_orderedFROMorderitemsWHEREorder_num=20005;

Output+–––––+|items_ordered|+–––––+

|19|+–––––+

Analysis

ThefunctionSUM(quantity)returnsthesumofalltheitemquantitiesinanorder,andtheWHEREclauseensuresthatjusttherightorderitemsareincluded.

SUM()canalsobeusedtototalcalculatedvalues.Inthisnextexample,thetotalorderamountisretrievedbytotalingitem_price*quantityforeachitem:

InputClickheretoviewcodeimage

SELECTSUM(item_price*quantity)AStotal_priceFROMorderitemsWHEREorder_num=20005;

Output+––––-+|total_price|+––––-+|149.87|+––––-+

Analysis

ThefunctionSUM(item_price*quantity)returnsthesumofalltheexpandedpricesinanorder,andagaintheWHEREclauseensuresthatjustthecorrectorderitemsareincluded.

Tip:PerformingCalculationsonMultipleColumns

Alltheaggregatefunctionscanbeusedtoperformcalculationsonmultiplecolumnsusingthestandardmathematicaloperators,asshownintheexample.

Note: Values

ColumnrowswithNULLvaluesinthemareignoredbytheSUM()function.

AggregatesonDistinctValuesThefiveaggregatefunctionscanallbeusedintwoways:

Toperformcalculationsonallrows,specifytheALLargument,orspecifynoargumentatall(becauseALListhedefaultbehavior).

Toonlyincludeuniquevalues,specifytheDISTINCTargument.

Tip: IsDefault

TheALLargumentneednotbespecifiedbecauseitisthedefaultbehavior.IfDISTINCTisnotspecified,ALLisassumed.

ThefollowingexampleusestheAVG()functiontoreturntheaverageproductpriceofferedbyaspecificvendor.ItisthesameSELECTstatementusedinthepreviousexample,butheretheDISTINCTargumentisusedsotheaverageonlytakesintoaccountuniqueprices:

InputClickheretoviewcodeimage

SELECTAVG(DISTINCTprod_price)ASavg_priceFROMproductsWHEREvend_id=1003;

Output+–––—+|avg_price|+–––—+|15.998|+–––—+

Analysis

Asyoucansee,inthisexample,avg_priceishigherwhenDISTINCTisusedbecausetherearemultipleitemswiththesamelowerprice.Excludingthemraisestheaverageprice.

Caution:Using

DISTINCTmayonlybeusedwithCOUNT()ifacolumnnameisspecified.DISTINCTmaynotbeusedwithCOUNT(*),andsoCOUNT(DISTINCT*)isnotallowedandgeneratesanerror.Similarly,DISTINCTmustbeusedwithacolumnnameandnotwithacalculationorexpression.

Tip:Using with and

AlthoughDISTINCTcantechnicallybeusedwithMIN()andMAX(),thereisactuallynovalueindoingso.Theminimumandmaximumvaluesinacolumnarethesamewhetherornotonlydistinctvaluesareincluded.

CombiningAggregateFunctionsAlltheexamplesofaggregatefunctionsusedthusfarhaveinvolvedasinglefunction.Butactually,SELECTstatementsmaycontainasfeworasmanyaggregatefunctionsasneeded.Lookatthisexample:

InputClickheretoviewcodeimage

SELECTCOUNT(*)ASnum_items,MIN(prod_price)ASprice_min,MAX(prod_price)ASprice_max,AVG(prod_price)ASprice_avgFROMproducts;

OutputClickheretoviewcodeimage

+–––—+–––—+–––—+––––+|num_items|price_min|price_max|price_avg|+–––—+–––—+–––—+––––+|14|2.5|55|16.1335714|+–––—+–––—+–––—+––––+

Analysis

HereasingleSELECTstatementperformsfouraggregatecalculationsinonestepandreturnsfourvalues(thenumberofitemsintheproductstable;andthehighest,lowest,andaverageproductprices).

Tip:NamingAliases

Whenspecifyingaliasnamestocontaintheresultsofanaggregatefunction,trytonotusethenameofanactualcolumninthetable.Althoughthereisnothingactuallyillegalaboutdoingso,usinguniquenamesmakesyourSQLeasiertounderstandandworkwith(andtroubleshootinthefuture).

SummaryAggregatefunctionsareusedtosummarizedata.Oraclesupportsarangeofaggregatefunctions,allofwhichcanbeusedinmultiplewaystoreturnjusttheresultsyouneed.Thesefunctionsaredesignedtobehighlyefficient,andtheyusuallyreturnresultsfarmorequicklythanyoucouldcalculatethemyourselfinyourownclientapplication.

Lesson13.GroupingData

Inthislesson,you’lllearnhowtogroupdatasoyoucansummarizesubsetsoftablecontents.ThisinvolvestwonewSELECTstatementclauses:theGROUPBYclauseandtheHAVINGclause.

UnderstandingDataGroupingInthelastlesson,youlearnedthattheSQLaggregatefunctionscanbeusedtosummarizedata.Thisenablesyoutocountrows,calculatesumsandaverages,andobtainhighandlowvalueswithouthavingtoretrieveallthedata.

AllthecalculationsthusfarwereperformedonallthedatainatableorondatathatmatchedaspecificWHEREclause.Asareminder,thefollowingexamplereturnsthenumberofproductsofferedbyvendor1003:

InputClickheretoviewcodeimage

SELECTCOUNT(*)ASnum_prodsFROMproductsWHEREvend_id=1003;

Output+–––—+|num_prods|+–––—+|7|+–––—+

Butwhatifyouwanttoreturnthenumberofproductsofferedbyeachvendor?Orproductsofferedbyvendorswhoofferasingleproduct,oronlythosewhooffermorethan10products?

Thisiswheregroupscomeintoplay.Groupingenablesyoutodividedataintologicalsetssoyoucanperformaggregatecalculationsoneachgroup.

CreatingGroupsGroupsarecreatedusingtheGROUPBYclauseinyourSELECTstatement.Thebestwaytounderstandthisistolookatanexample:

Input

SELECTvend_id,COUNT(*)ASnum_prodsFROMproductsGROUPBYvend_id;

Output+–––+–––—+|vend_id|num_prods|

+–––+–––—+|1001|3||1002|2||1003|7||1005|2|+–––+–––—+

Analysis

TheprecedingSELECTstatementspecifiestwocolumns:vend_id,whichcontainstheIDofaproduct’svendor,andnum_prods,whichisacalculatedfield(createdusingtheCOUNT(*)function).TheGROUPBYclauseinstructsOracletosortthedataandgroupitbyvend_id.Thiscausesnum_prodstobecalculatedoncepervend_idratherthanoncefortheentiretable.Asyoucanseeintheoutput,vendor1001has3productslisted,vendor1002has2productslisted,vendor1003has7productslisted,andvendor1005has2productslisted.

BecauseyouusedGROUPBY,youdidnothavetospecifyeachgrouptobeevaluatedandcalculated.Thatwasdoneautomatically.TheGROUPBYclauseinstructsOracletogroupthedataandthenperformtheaggregateoneachgroupratherthanontheentireresultset.

BeforeyouuseGROUPBY,herearesomeimportantrulesaboutitsusethatyouneedtoknow:

GROUPBYclausescancontainasmanycolumnsasyouwant.Thisenablesyoutonestgroups,providingyouwithmoregranularcontroloverhowdataisgrouped.

IfyouhavenestedgroupsinyourGROUPBYclause,dataissummarizedatthelastspecifiedgroup.Inotherwords,allthecolumnsspecifiedareevaluatedtogetherwhengroupingisestablished(soyouwon’tgetdatabackforeachindividualcolumnlevel).

EverycolumnlistedinGROUPBYmustbearetrievedcolumnoravalidexpression(butnotanaggregatefunction).IfanexpressionisusedintheSELECT,thatsameexpressionmustbespecifiedinGROUPBY.Aliasescannotbeused.

Asidefromtheaggregatecalculationsstatements,everycolumninyourSELECTstatementshouldbepresentintheGROUPBYclause.

IfthegroupingcolumncontainsarowwithaNULLvalue,NULLwillbereturnedasagroup.IftherearemultiplerowswithNULLvalues,they’llallbegroupedtogether.

TheGROUPBYclausemustcomeafteranyWHEREclauseandbeforeanyORDERBYclause.

FilteringGroupsInadditiontobeingabletogroupdatausingGROUPBY,Oraclealsoallowsyoutofilterwhichgroupstoincludeandwhichtoexclude.Forexample,youmightwantalistofallcustomerswhohavemadeatleasttwoorders.Toobtainthisdata,youmustfilterbasedonthecompletegroup,notonindividualrows.

You’vealreadyseentheWHEREclauseinaction(introducedbackinLesson6,“FilteringData”).ButWHEREdoesnotworkherebecauseWHEREfiltersspecificrows,notgroups.Asamatteroffact,WHEREhasnoideawhatagroupis.

SowhatdoyouuseinsteadofWHERE?Oracleprovidesyetanotherclauseforthispurpose:theHAVINGclause.HAVINGisverysimilartoWHERE.Infact,alltypesofWHEREclausesyoulearnedaboutthusfarcanalsobeusedwithHAVING.TheonlydifferenceisthatWHEREfiltersrowsandHAVINGfiltersgroups.

Tip: SupportsAllof ’sOperators

InLesson6andLesson7,“AdvancedDataFiltering,”youlearnedaboutWHEREclauseconditions(includingwildcardconditionsandclauseswithmultipleoperators).AllthetechniquesandoptionsyoulearnedaboutWHEREcanbeappliedtoHAVING.Thesyntaxisidentical;justthekeywordisdifferent.

Sohowdoyoufilterrows?Lookatthefollowingexample:

InputClickheretoviewcodeimage

SELECTcust_id,COUNT(*)ASordersFROMordersGROUPBYcust_idHAVINGCOUNT(*)>=2;

Output+–––+––—+|cust_id|orders|+–––+––—+|10001|2|+–––+––—+

Analysis

ThefirstthreelinesofthisSELECTstatementaresimilartothestatementsshownpreviously.ThefinallineaddsaHAVINGclausethatfiltersonthosegroupswithaCOUNT(*)>=2—twoormoreorders.

Obviously,aWHEREclausecouldn’thaveworkedherebecausethefilteringisbasedonthegroupaggregatevalue,notonthevaluesofspecificrows.

Note:TheDifferenceBetween and

Here’sanotherwaytolookatit:WHEREfiltersbeforedataisgrouped,andHAVINGfiltersafterdataisgrouped.Thisisanimportantdistinction;rowsthatareeliminatedbyaWHEREclausearenotincludedinthegroup.Thiscouldchangethecalculatedvalues,whichinturncouldaffectwhichgroupsarefilteredbasedontheuseofthosevaluesintheHAVINGclause.

SoisthereeveraneedtousebothWHEREandHAVINGclausesinonestatement?Actually,yes,thereis.Supposeyouwanttofurtherfilterthepreviousstatementsoitreturnsanycustomerswhoplacedtwoormoreordersinthepast12months.Todothat,youcanaddaWHEREclausethatfiltersoutjusttheordersplacedinthepast12months.YouthenaddaHAVINGclausetofilterjustthegroupswithtwoormorerowsinthem.

Tobetterdemonstratethis,lookatthefollowingexamplethatlistsallvendorswhohave2ormoreproductspricedat10ormore:

InputClickheretoviewcodeimage

SELECTvend_id,COUNT(*)ASnum_prodsFROMproductsWHEREprod_price>=10GROUPBYvend_idHAVINGCOUNT(*)>=2;

Output+–––+–––—+|vend_id|num_prods|+–––+–––—+|1003|4||1005|2|+–––+–––—+

Analysis

Thisstatementwarrantsanexplanation.ThefirstlineisabasicSELECTusinganaggregatefunction—muchliketheexamplesthusfar.TheWHEREclausefiltersallrowswithaprod_priceofatleast10.Dataisthengroupedbyvend_id,andthenaHAVINGclausefiltersjustthosegroupswithacountof2ormore.WithouttheWHEREclause,twoextrarowswouldhavebeenretrieved(vendor1002whoonlysellsproductsallpricedunder10,andvendor1001whosellsthreeproductsbutonlyoneofthemispricedgreaterorequalto10),asshownhere:

InputClickheretoviewcodeimage

SELECTvend_id,COUNT(*)ASnum_prodsFROMproductsGROUPBYvend_idHAVINGCOUNT(*)>=2;

Output+–––+–––—+|vend_id|num_prods|+–––+–––—+|1001|3||1002|2||1003|7||1005|2|

+–––+–––—+

GroupingandSortingItisimportanttounderstandthatGROUPBYandORDERBYareverydifferent,eventhoughtheyoftenaccomplishthesamething.Table13.1summarizesthedifferencesbetweenthem.

TABLE13.1ORDERBYVersusGROUPBY

ThefirstdifferencelistedinTable13.1isextremelyimportant.Moreoftenthannot,youwillfindthatdatagroupedusingGROUPBYwillindeedbeoutputingrouporder.Butthatisnotalwaysthecase,anditisnotactuallyrequiredbytheSQLspecifications.Furthermore,youmightactuallywantitsorteddifferentlythanitisgrouped.Justbecauseyougroupdataoneway(toobtaingroup-specificaggregatevalues)doesnotmeanthatyouwanttheoutputsortedthatsameway.YoushouldalwaysprovideanexplicitORDERBYclauseaswell,evenifitisidenticaltotheGROUPBYclause.

Tip:Don’tForget

Asarule,anytimeyouuseaGROUPBYclause,youshouldalsospecifyanORDERBYclause.Thatistheonlywaytoensurethatdataissortedproperly.NeverrelyonGROUPBYtosortyourdata.

TodemonstratetheuseofbothGROUPBYandORDERBY,let’slookatanexample.ThefollowingSELECTstatementissimilartotheonesshownpreviously.Itretrievestheordernumberandtotalorderpriceofallorderswithatotalpriceof50ormore:

InputClickheretoviewcodeimage

SELECTorder_num,SUM(quantity*item_price)ASordertotalFROMorderitemsGROUPBYorder_numHAVINGSUM(quantity*item_price)>=50;

Output+–––—+––––+

|order_num|ordertotal|+–––—+––––+|20005|149.87||20006|55||20007|1000||20008|125|+–––—+––––+

Tosorttheoutputbyordertotal,allyouneedtodoisaddanORDERBYclause,asfollows:

InputClickheretoviewcodeimage

SELECTorder_num,SUM(quantity*item_price)ASordertotalFROMorderitemsGROUPBYorder_numHAVINGSUM(quantity*item_price)>=50ORDERBYordertotal;

Output+–––—+––––+|order_num|ordertotal|+–––—+––––+|20006|55||20008|125||20005|149.87||20007|1000|+–––—+––––+

Analysis

Inthisexample,theGROUPBYclauseisusedtogroupthedatabyordernumber(theorder_numcolumn)sothattheSUM(*)functioncanreturnthetotalorderprice.TheHAVINGclausefiltersthedatasothatonlyorderswithatotalpriceof50ormorearereturned.Finally,theoutputissortedusingtheORDERBYclause.

ClauseOrderingThisisprobablyagoodtimetoreviewtheorderinwhichSELECTstatementclausesaretobespecified.Table13.2listsalltheclausesyouhavelearnedthusfar,intheordertheymustbeused.

TABLE13.2SELECTClausesandTheirSequence

SummaryInLesson12,“SummarizingData,”youlearnedhowtousetheSQLaggregatefunctionstoperformsummarycalculationsonyourdata.Inthislesson,youlearnedhowtousetheGROUPBYclausetoperformthesecalculationsongroupsofdata,returningresultsforeachgroup.YousawhowtousetheHAVINGclausetofilterspecificgroups.YoualsolearnedthedifferencebetweenORDERBYandGROUPBYandbetweenWHEREandHAVING.

Lesson14.WorkingwithSubqueries

Inthislesson,you’lllearnwhatsubqueriesareandhowtousethem.

UnderstandingSubqueriesSELECTstatementsareSQLqueries.AlltheSELECTstatementsyouhaveseenthusfararesimplequeries:singlestatementsretrievingdatafromindividualdatabasetables.

Query

AnySQLstatement.However,thetermisusuallyusedtorefertoSELECTstatements.

SQLalsoenablesyoutocreatesubqueries:queriesthatareembeddedintootherqueries.Whywouldyouwanttodothis?Thebestwaytounderstandthisconceptistolookatacoupleofexamples.

FilteringbySubqueryThedatabasetablesusedinallthelessonsinthisbookarerelationaltables.(SeeAppendixA,“TheExampleTables,”foradescriptionofeachofthetablesandtheirrelationships.)Orderdataisstoredintwotables.Theorderstablestoresasinglerowforeachordercontainingordernumber,customerID,andorderdate.Theindividualorderitemsarestoredintherelatedorderitemstable.Theorderstabledoesnotstorecustomerinformation.ItonlystoresacustomerID.Theactualcustomerinformationisstoredinthecustomerstable.

NowsupposeyouwantedalistofallthecustomerswhoordereditemTNT2.Whatwouldyouhavetodotoretrievethisinformation?Herearethesteps:

1.RetrievetheordernumbersofallorderscontainingitemTNT2.

2.RetrievethecustomerIDofallthecustomerswhohaveorderslistedintheordernumbersreturnedinthepreviousstep.

3.RetrievethecustomerinformationforallthecustomerIDsreturnedinthepreviousstep.

Eachofthesestepscanbeexecutedasaseparatequery.Bydoingso,youusetheresultsreturnedbyoneSELECTstatementtopopulatetheWHEREclauseofthenextSELECTstatement.

Youcanalsousesubqueriestocombineallthreequeriesintoonesinglestatement.

ThefirstSELECTstatementshouldbeself-explanatorybynow.Itretrievestheorder_numcolumnforallorderitemswithaprod_idofTNT2.Theoutputliststhetwoorderscontainingthisitem:

Input

SELECTorder_numFROMorderitemsWHEREprod_id=‘TNT2’;

Output+–––—+|order_num|+–––—+|20005||20007|+–––—+

ThenextstepistoretrievethecustomerIDsassociatedwithorders20005and20007.UsingtheINclausedescribedinLesson7,“AdvancedDataFiltering,”youcancreateaSELECTstatementasfollows:

InputClickheretoviewcodeimage

SELECTcust_idFROMordersWHEREorder_numIN(20005,20007);

Output+–––+|cust_id|+–––+|10001||10004|+–––+

Now,combinethetwoqueriesbyturningthefirst(theonethatreturnedtheordernumbers)intoasubquery.LookatthefollowingSELECTstatement:

InputClickheretoviewcodeimage

SELECTcust_idFROMordersWHEREorder_numIN(SELECTorder_numFROMorderitemsWHEREprod_id=‘TNT2’);

Output+–––+|cust_id|+–––+|10001||10004|+–––+

Analysis

SubqueriesarealwaysprocessedstartingwiththeinnermostSELECTstatementandworkingoutward.WhentheprecedingSELECTstatementisprocessed,Oracleactually

performstwooperations.

First,itrunsthesubquery:Clickheretoviewcodeimage

SELECTorder_numFROMorderitemsWHEREprod_id=‘TNT2’

Thatqueryreturnsthetwoordernumbers20005and20007.ThosetwovaluesarethenpassedtotheWHEREclauseoftheouterqueryinthecomma-delimitedformatrequiredbytheINoperator.TheouterquerynowbecomesClickheretoviewcodeimage

SELECTcust_idFROMordersWHEREorder_numIN(20005,20007)

Asyoucansee,theoutputiscorrectandexactlythesameastheoutputreturnedbytheprevioushard-codedWHEREclause.

Tip:FormattingYourSQL

SELECTstatementscontainingsubqueriescanbedifficulttoreadanddebug,especiallyastheygrowincomplexity.Breakingupthequeriesovermultiplelinesandindentingthelinesappropriatelyasshownherecangreatlysimplifyworkingwithsubqueries.

YounowhavetheIDsofallthecustomerswhoordereditemTNT2.ThenextstepistoretrievethecustomerinformationforeachofthosecustomerIDs.TheSQLstatementtoretrievethetwocolumnsisasfollows:

InputClickheretoviewcodeimage

SELECTcust_name,cust_contactFROMcustomersWHEREcust_idIN(10001,10004);

Insteadofhard-codingthosecustomerIDs,youcanturnthisWHEREclauseintoyetanothersubquery:

InputClickheretoviewcodeimage

SELECTcust_name,cust_contactFROMcustomersWHEREcust_idIN(SELECTcust_idFROMordersWHEREorder_numIN(SELECTorder_numFROMorderitemsWHEREprod_id=‘TNT2’));

OutputClickheretoviewcodeimage

+–––––-+––––—+

|cust_name|cust_contact|+–––––-+––––—+|CoyoteInc.|YLee||YosemitePlace|YSam|+–––––-+––––—+

Analysis

ToexecutethisSELECTstatement,OraclehadtoactuallyperformthreeSELECTstatements.TheinnermostsubqueryreturnedalistofordernumbersthatwerethenusedastheWHEREclauseforthesubqueryaboveit.ThatsubqueryreturnedalistofcustomerIDsthatwereusedastheWHEREclauseforthetop-levelquery.Thetop-levelqueryactuallyreturnedthedesireddata.

Asyoucansee,usingsubqueriesinaWHEREclauseenablesyoutowriteextremelypowerfulandflexibleSQLstatements.Wenestedthreelevelsdeephere,butifneeded,youcannestfardeeperthanthat.Justkeepinmindthatperformancewillstarttodeterioratethefurtheryounestqueries.

Caution:ColumnsMustMatch

WhenusingasubqueryinaWHEREclause(asshownhere),makesurethattheSELECTstatementhasthesamenumberofcolumnsasintheWHEREclause.Usually,asinglecolumnwillbereturnedbythesubqueryandmatchedagainstasinglecolumn,butmultiplecolumnsmaybeusedifneeded.

AlthoughusuallyusedwiththeINoperator,subqueriescanalsobeusedtotestforequality(using=),non-equality(using<>),andsoon.

Note:MaximumNumberofSubqueries

Oracleallowsyoutonestamaximumof255levelsofsubquerieswithinaWHEREclause(althoughyouwouldbehardpressedtofindasituationthatwarrantsdoingthis!).

Caution:SubqueriesandPerformance

Thecodeshownhereworks,anditachievesthedesiredresult.However,usingsubqueriesisnotalwaysthemostefficientwaytoperformthistypeofdataretrieval,althoughitmightbe.MoreonthisisinLesson15,“JoiningTables,”whereyouwillrevisitthissameexample.

UsingSubqueriesasCalculatedFieldsAnotherwaytousesubqueriesisincreatingcalculatedfields.Supposeyouwanttodisplaythetotalnumberofordersplacedbyeverycustomerinyourcustomerstable.OrdersarestoredintheorderstablealongwiththeappropriatecustomerID.

Toperformthisoperation,followthesesteps:

1.Retrievethelistofcustomersfromthecustomerstable.

2.Foreachcustomerretrieved,countthenumberofassociatedordersintheorderstable.

Asyoulearnedintheprevioustwolessons,youcanuseSELECTCOUNT(*)tocountrowsinatable,andbyprovidingaWHEREclausetofilteraspecificcustomerID,youcancountjustthatcustomer’sorders.Forexample,thefollowingcodecountsthenumberofordersplacedbycustomer10001:

Input

SELECTCOUNT(*)ASordersFROMordersWHEREcust_id=10001;

ToperformthatCOUNT(*)calculationforeachcustomer,useCOUNT*asasubquery.Lookatthefollowingcode:

InputClickheretoviewcodeimage

SELECTcust_name,cust_state,(SELECTCOUNT(*)FROMordersWHEREorders.cust_id=customers.cust_id)ASordersFROMcustomersORDERBYcust_name;

OutputClickheretoviewcodeimage

+–––––-+––––+––—+|cust_name|cust_state|orders|+–––––-+––––+––—+|CoyoteInc.|MI|2||EFudd|IL|1||MouseHouse|OH|0||Wascals|IN|1||YosemitePlace|AZ|1|+–––––-+––––+––—+

Analysis

ThisSELECTstatementreturnsthreecolumnsforeverycustomerinthecustomerstable:cust_name,cust_state,andorders.ordersisacalculatedfieldthatissetbyasubqueryprovidedinparentheses.Thatsubqueryisexecutedonceforeverycustomerretrieved.Inthisexample,thesubqueryisexecutedfivetimesbecausefivecustomerswereretrieved.

TheWHEREclauseinthesubqueryisalittledifferentfromtheWHEREclausesusedpreviouslybecauseitusesfullyqualifiedcolumnnames(firstmentionedinLesson4,“RetrievingData”).ThefollowingclausetellsSQLtocomparethecust_idinthe

orderstabletotheonecurrentlybeingretrievedfromthecustomerstable:Clickheretoviewcodeimage

WHEREorders.cust_id=customers.cust_id

CorrelatedSubquery

Asubquerythatreferstotheouterquery.

Thetypeofsubqueryiscalledacorrelatedsubquery.Thissyntax—thetablenameandthecolumnnameseparatedbyaperiod—mustbeusedwheneverthereispossibleambiguityaboutcolumnnames.Why?Well,let’slookatwhathappensiffullyqualifiedcolumnnamesarenotused:

InputClickheretoviewcodeimage

SELECTcust_name,cust_state,(SELECTCOUNT(*)FROMordersWHEREcust_id=cust_id)ASordersFROMcustomersORDERBYcust_name;

OutputClickheretoviewcodeimage

+–––––-+––––+––—+|cust_name|cust_state|orders|+–––––-+––––+––—+|CoyoteInc.|MI|5||EFudd|IL|5||MouseHouse|OH|5||Wascals|IN|5||YosemitePlace|AZ|5|+–––––-+––––+––—+

Analysis

Obviouslythereturnedresultsareincorrect(comparethemtothepreviousresults),butwhydidthishappen?Therearetwocust_idcolumns,oneincustomersandoneinorders,andthosetwocolumnsneedtobecomparedtocorrectlymatchorderswiththeirappropriatecustomers.Withoutfullyqualifyingthecolumnnames,Oracleassumesyouarecomparingthecust_idintheorderstabletoitself.AndClickheretoviewcodeimage

SELECTCOUNT(*)FROMordersWHEREcust_id=cust_id;

alwaysreturnsthetotalnumberofordersintheorderstable(becauseOraclecheckstoseethateveryorder’scust_idmatchesitself,whichitalwaysdoes,ofcourse).

AlthoughsubqueriesareextremelyusefulinconstructingthistypeofSELECTstatement,caremustbetakentoproperlyqualifyambiguouscolumnnames.

Note:AlwaysMoreThanOneSolution

Asexplainedearlierinthislesson,althoughthesamplecodeshownhereworks,itisoftennotthemostefficientwaytoperformthistypeofdataretrieval.Youwillrevisitthisexampleinalaterlesson.

Tip:BuildQuerieswithSubqueriesIncrementally

Testinganddebuggingquerieswithsubqueriescanbetricky,particularlyasthesestatementsgrowincomplexity.Thesafestwaytobuild(andtest)querieswithsubqueriesistodosoincrementally,inmuchthesamewayasOracleprocessesthem.Buildandtesttheinnermostqueryfirst.Thenbuildandtesttheouterquerywithhard-codeddata,andonlyafteryouhaveverifiedthatitisworkingembedthesubquery.Thentestitagain,andkeeprepeatingthesestepsforeachadditionalquery.Thiswilltakejustalittlelongertoconstructyourqueries,butitsavesyoulotsoftimelater(whenyoutrytofigureoutwhyqueriesarenotworking)andsignificantlyincreasesthelikelihoodofthemworkingthefirsttime.

Note: ClauseSubqueries

InadditiontothesubqueriesusedinSELECTandWHEREclausesshowninthislesson,OraclealsosupportstheuseofsubqueriesintheFROMclause.Thistypeofsubqueryiscalledaninlineview,anditisawaytocreateavirtualtableofsorts.Inlineviewsareinfrequentlyusedandarethusnotcoveredinthisbook,butviewsthemselvesareintroducedinLesson21,“UsingViews.”

SummaryInthislesson,youlearnedwhatsubqueriesareandhowtousethem.ThemostcommonusesforsubqueriesareinWHEREclauses,inINoperators,andforpopulatingcalculatedcolumns.Yousawexamplesofbothofthesetypesofoperations.

Lesson15.JoiningTables

Inthislesson,you’lllearnwhatjoinsare,whytheyareused,andhowtocreateSELECTstatementsusingthem.

UnderstandingJoinsOneofSQL’smostpowerfulfeaturesisthecapabilitytojointablesontheflywithindataretrievalqueries.JoinsareoneofthemostimportantoperationsyoucanperformusingSQLSELECT,andagoodunderstandingofjoinsandjoinsyntaxisanextremelyimportantpartoflearningSQL.

Beforeyoucaneffectivelyusejoins,youmustunderstandrelationaltablesandthebasicsofrelationaldatabasedesign.Whatfollowsisbynomeansacompletecoverageofthesubject,butitshouldbeenoughtogetyouupandrunning.

UnderstandingRelationalTablesThebestwaytounderstandrelationaltablesistolookatareal-worldexample.

Supposeyouhadadatabasetablecontainingaproductcatalog,witheachcatalogiteminitsownrow.Thekindofinformationyouwouldstorewitheachitemwouldincludeaproductdescriptionandprice,alongwithvendorinformationaboutthecompanythatcreatestheproduct.

Nowsupposeyouhadmultiplecatalogitemscreatedbythesamevendor.Wherewouldyoustorethevendorinformation(thingssuchasvendorname,address,andcontactinformation)?Youwouldn’twanttostorethatdataalongwiththeproductsforseveralreasons:

Becausethevendorinformationisthesameforeachproductthatvendorproduces,repeatingtheinformationforeachproductisawasteoftimeandstoragespace.

Ifvendorinformationchanges(forexample,ifthevendormovesorhisareacodechanges),youwouldneedtoupdateeveryoccurrenceofthevendorinformation.

Whendataisrepeated(thatis,thevendorinformationisusedwitheachproduct),thereisahighlikelihoodthatthedatawillnotbeenteredexactlythesamewayeachtime.Inconsistentdataisextremelydifficulttouseinreporting.

Thekeyhereisthathavingmultipleoccurrencesofthesamedataisneveragoodthing,andthatprincipleisthebasisforrelationaldatabasedesign.Relationaltablesaredesignedsoinformationissplitintomultipletables,oneforeachdatatype.Thetablesarerelatedtoeachotherthroughcommonvalues(andthustherelationalinrelationaldesign).

Inourexample,youcancreatetwotables,oneforvendorinformationandoneforproductinformation.Thevendorstablecontainsallthevendorinformation,onetablerowpervendor,alongwithauniqueidentifierforeachvendor.Thisvalue,calledaprimarykey,canbeavendorID,oranyotheruniquevalue.(PrimarykeyswerefirstmentionedinLesson1,“UnderstandingSQL.”)

Theproductstablestoresonlyproductinformation,andnovendor-specificinformationotherthanthevendorID(thevendorstable’sprimarykey).Thiskey,calledaforeignkey,relatesthevendorstabletotheproductstable,andusingthisvendorIDenablesyoutousethevendorstabletofindthedetailsabouttheappropriatevendor.

ForeignKey

Acolumninonetablethatcontainstheprimarykeyvaluesfromanothertable,thusdefiningtherelationshipsbetweentables.

Whatdoesthisdoforyou?Well,considerthefollowing:

Vendorinformationisneverrepeated,andsotimeandspacearenotwasted.

Ifvendorinformationchanges,youcanupdateasinglerecordinthevendorstable.Datainrelatedtablesdoesnotchange.

Asnodataisrepeated,thedatausedisobviouslyconsistent,makingdatareportingandmanipulationmuchsimpler.

Thebottomlineisthatrelationaldatacanbestoredefficientlyandmanipulatedeasily.Becauseofthis,relationaldatabasesscalefarbetterthannon-relationaldatabases.

Scale

Abletohandleanincreasingloadwithoutfailing.Awell-designeddatabaseorapplicationissaidtoscalewell.

WhyUseJoins?Asjustexplained,breakingdataintomultipletablesenablesmoreefficientstorage,easiermanipulation,andgreaterscalability.However,thesebenefitscomewithaprice.

Ifdataisstoredinmultipletables,howcanyouretrievethatdatawithasingleSELECTstatement?

Theansweristouseajoin.Simplyput,ajoinisamechanismusedtoassociatetableswithinaSELECTstatement(andthusthenamejoin).Usingaspecialsyntax,multipletablescanbejoinedsoasinglesetofoutputisreturned,andthejoinassociatesthecorrectrowsineachtableon-the-fly.

Note:MaintainingReferentialIntegrity

Itisimportanttounderstandthatajoinisnotaphysicalentity—inotherwords,itdoesnotexistintheactualdatabasetables.AjoiniscreatedbyOracleasneeded,anditpersistsforthedurationofthequeryexecution.

Whenusingrelationaltables,itisimportantthatonlyvaliddataisinsertedintorelationalcolumns.Goingbacktotheexample,ifproductswerestoredintheproductstablewithaninvalidvendorID(onenotpresentinthevendorstable),thoseproductswouldbeinaccessiblebecausetheywouldnotberelatedtoanyvendor.

Topreventthisfromoccurring,Oraclecanbeinstructedtoonlyallowvalidvalues(onespresentinthevendorstable)inthevendorIDcolumnintheproductstable.Thisisknownasmaintainingreferentialintegrity,andisachievedbyspecifyingtheprimaryandforeignkeysaspartofthetabledefinitions(aswillbeexplainedinLesson20,“CreatingandManipulatingTables”).

Foranexampleofthis,seethecreate.sqlscriptusedtocreatethecrashcoursedatabasetables.TheALTERTABLEstatementsattheendofthefilearedefiningconstrainstoenforcereferentialintegrity.

CreatingaJoinCreatingajoinisverysimple.Youmustspecifyallthetablestobeincludedandhowtheyarerelatedtoeachother.Lookatthefollowingexample:

InputClickheretoviewcodeimage

SELECTvend_name,prod_name,prod_priceFROMvendors,productsWHEREvendors.vend_id=products.vend_idORDERBYvend_name,prod_name;

OutputClickheretoviewcodeimage

+––––-+–––––-+––––+|vend_name|prod_name|prod_price|+––––-+–––––-+––––+|ACME|Birdseed|10||ACME|Carrots|2.5||ACME|Detonator|13||ACME|Safe|50||ACME|Sling|4.49||ACME|TNT(1stick)|2.5||ACME|TNT(5sticks)|10||AnvilsRUs|.5tonanvil|5.99||AnvilsRUs|1tonanvil|9.99||AnvilsRUs|2tonanvil|14.99||JetSet|JetPack1000|35||JetSet|JetPack2000|55|

|LTSupplies|Fuses|3.42||LTSupplies|Oilcan|8.99|+––––-+–––––-+––––+

Analysis

Takealookattheprecedingcode.TheSELECTstatementstartsinthesamewayasallthestatementsyou’velookedatthusfar,byspecifyingthecolumnstoberetrieved.Thebigdifferencehereisthattwoofthespecifiedcolumns(prod_nameandprod_price)areinonetable,whereastheother(vend_name)isinanothertable.

NowlookattheFROMclause.UnlikeallthepriorSELECTstatements,thisonehastwotableslistedintheFROMclause,vendorsandproducts.ThesearethenamesofthetwotablesthatarebeingjoinedinthisSELECTstatement.ThetablesarecorrectlyjoinedwithaWHEREclausethatinstructsOracletomatchvend_idinthevendorstablewithvend_idintheproductstable.

You’llnoticethatthecolumnsarespecifiedasvendors.vend_idandproducts.vend_id.Thisfullyqualifiedcolumnnameisrequiredherebecauseifyoujustspecifiedvend_id,Oraclecannottellwhichvend_idcolumnsyouarereferringto(astherearetwoofthem,oneineachtable).

Caution:FullyQualifyingColumnNames

Youmustusethefullyqualifiedcolumnname(tableandcolumnseparatedbyaperiod)wheneverthereisapossibleambiguityabouttowhichcolumnyouarereferring.Oraclereturnsanerrormessageifyourefertoanambiguouscolumnnamewithoutfullyqualifyingitwithatablename.

TheImportanceofthe ClauseItmightseemstrangetouseaWHEREclausetosetthejoinrelationship,butactually,thereisaverygoodreasonforthis.Remember,whentablesarejoinedinaSELECTstatement,thatrelationshipisconstructedonthefly.NothinginthedatabasetabledefinitionscaninstructOraclehowtojointhetables.Youhavetodothatyourself.Whenyoujointwotables,whatyouareactuallydoingispairingeveryrowinthefirsttablewitheveryrowinthesecondtable.TheWHEREclauseactsasafiltertoonlyincluderowsthatmatchthespecifiedfiltercondition—thejoincondition,inthiscase.WithouttheWHEREclause,everyrowinthefirsttableispairedwitheveryrowinthesecondtable,regardlessofwhethertheylogicallygotogether.

CartesianProduct

Theresultsreturnedbyatablerelationshipwithoutajoincondition.Thenumberofrowsretrievedisthenumberofrowsinthefirsttablemultipliedbythenumberofrowsinthesecondtable.

Tounderstandthis,lookatthefollowingSELECTstatementandoutput:

InputClickheretoviewcodeimage

SELECTvend_name,prod_name,prod_priceFROMvendors,productsORDERBYvend_name,prod_name;

OutputClickheretoviewcodeimage

+–––––-+–––––-+––––+|vend_name|prod_name|prod_price|+–––––-+–––––-+––––+|ACME|.5tonanvil|5.99||ACME|1tonanvil|9.99||ACME|2tonanvil|14.99||ACME|Birdseed|10||ACME|Carrots|2.5||ACME|Detonator|13||ACME|Fuses|3.42||ACME|JetPack1000|35||ACME|JetPack2000|55||ACME|Oilcan|8.99||ACME|Safe|50||ACME|Sling|4.49||ACME|TNT(1stick)|2.5||ACME|TNT(5sticks)|10||AnvilsRUs|.5tonanvil|5.99||AnvilsRUs|1tonanvil|9.99||AnvilsRUs|2tonanvil|14.99||AnvilsRUs|Birdseed|10||AnvilsRUs|Carrots|2.5||AnvilsRUs|Detonator|13||AnvilsRUs|Fuses|3.42||AnvilsRUs|JetPack1000|35||AnvilsRUs|JetPack2000|55||AnvilsRUs|Oilcan|8.99||AnvilsRUs|Safe|50||AnvilsRUs|Sling|4.49||AnvilsRUs|TNT(1stick)|2.5||AnvilsRUs|TNT(5sticks)|10||FurballInc.|.5tonanvil|5.99||FurballInc.|1tonanvil|9.99||FurballInc.|2tonanvil|14.99||FurballInc.|Birdseed|10||FurballInc.|Carrots|2.5||FurballInc.|Detonator|13||FurballInc.|Fuses|3.42||FurballInc.|JetPack1000|35||FurballInc.|JetPack2000|55||FurballInc.|Oilcan|8.99||FurballInc.|Safe|50||FurballInc.|Sling|4.49||FurballInc.|TNT(1stick)|2.5||FurballInc.|TNT(5sticks)|10||JetSet|.5tonanvil|5.99||JetSet|1tonanvil|9.99||JetSet|2tonanvil|14.99||JetSet|Birdseed|10||JetSet|Carrots|2.5|

|JetSet|Detonator|13||JetSet|Fuses|3.42||JetSet|JetPack1000|35||JetSet|JetPack2000|55||JetSet|Oilcan|8.99||JetSet|Safe|50||JetSet|Sling|4.49||JetSet|TNT(1stick)|2.5||JetSet|TNT(5sticks)|10||JouetsEtOurs|.5tonanvil|5.99||JouetsEtOurs|1tonanvil|9.99||JouetsEtOurs|2tonanvil|14.99||JouetsEtOurs|Birdseed|10||JouetsEtOurs|Carrots|2.5||JouetsEtOurs|Detonator|13||JouetsEtOurs|Fuses|3.42||JouetsEtOurs|JetPack1000|35||JouetsEtOurs|JetPack2000|55||JouetsEtOurs|Oilcan|8.99||JouetsEtOurs|Safe|50||JouetsEtOurs|Sling|4.49||JouetsEtOurs|TNT(1stick)|2.5||JouetsEtOurs|TNT(5sticks)|10||LTSupplies|.5tonanvil|5.99||LTSupplies|1tonanvil|9.99||LTSupplies|2tonanvil|14.99||LTSupplies|Birdseed|10||LTSupplies|Carrots|2.5||LTSupplies|Detonator|13||LTSupplies|Fuses|3.42||LTSupplies|JetPack1000|35||LTSupplies|JetPack2000|55||LTSupplies|Oilcan|8.99||LTSupplies|Safe|50||LTSupplies|Sling|4.49||LTSupplies|TNT(1stick)|2.5||LTSupplies|TNT(5sticks)|10|+–––––-+–––––-+––––+

Analysis

Asyoucanseeintheprecedingoutput,theCartesianproductisseldomwhatyouwant.Thedatareturnedherehasmatchedeveryproductwitheveryvendor,includingproductswiththeincorrectvendor(andevenvendorswithnoproductsatall).

Caution:Don’tForgetthe Clause

MakesureallyourjoinshaveWHEREclauses,orOraclereturnsfarmoredatathanyouwant.Similarly,makesureyourWHEREclausesarecorrect.AnincorrectfilterconditioncausesOracletoreturnincorrectdata.

Tip:CrossJoins

Sometimesyou’llhearthetypeofjointhatreturnsaCartesianproductreferredtoasacrossjoin.

UsingInnerJoinsThejoinyouhavebeenusingsofariscalledanequijoin—ajoinbasedonthetestingofequalitybetweentwotables.Thiskindofjoinisalsocalledaninnerjoin.Infact,youmayuseaslightlydifferentsyntaxforthesejoins,specifyingthetypeofjoinexplicitly.ThefollowingSELECTstatementreturnstheexactsamedataastheprecedingexample:

InputClickheretoviewcodeimage

SELECTvend_name,prod_name,prod_priceFROMvendorsINNERJOINproductsONvendors.vend_id=products.vend_id;

Analysis

TheSELECTinthestatementisthesameastheprecedingSELECTstatement,buttheFROMclauseisdifferent.HeretherelationshipbetweenthetwotablesispartoftheFROMclausespecifiedasINNERJOIN.Whenusingthissyntax,thejoinconditionisspecifiedusingthespecialONclauseinsteadofaWHEREclause.TheactualconditionpassedtoONisthesameaswouldbepassedtoWHERE.

Note:WhichSyntaxtoUse?

PertheANSISQLspecification,useoftheINNERJOINsyntaxispreferable.Furthermore,althoughusingtheWHEREclausetodefinejoinsisindeedsimpler,usingexplicitjoinsyntaxensuresthatyouwillneverforgetthejoincondition,andcanimpactperformance,too(insomecases).

SomeSQLpuristswillinsistthatyouusetheFROMclausetodefineyourjoins.ButI’mahugefanofsimplifyingthings,andOracle(likeeveryotherDBMSvendor)hasimplementedsupportforthesimplersyntax,soIuseitextensively.

Regardless,you’relikelytorunacrossbothjoinsyntaxesintherealworld.Assuch,it’sworthwhiletobefamiliarwiththesimplifiedWHEREclausejoinsandtheANSIpreferredFROMclausejoins.

JoiningMultipleTablesSQLimposesnolimittothenumberoftablesthatmaybejoinedinaSELECTstatement.Thebasicrulesforcreatingthejoinremainthesame.Firstlistallthetables,andthendefinetherelationshipbetweeneach.Hereisanexample:

InputClickheretoviewcodeimage

SELECTprod_name,vend_name,prod_price,quantityFROMorderitems,products,vendorsWHEREproducts.vend_id=vendors.vend_idANDorderitems.prod_id=products.prod_id

ANDorder_num=20005;

OutputClickheretoviewcodeimage

+–––––-+––––-+––––+–––-+|prod_name|vend_name|prod_price|quantity|+–––––-+––––-+––––+–––-+|.5tonanvil|AnvilsRUs|5.99|10||1tonanvil|AnvilsRUs|9.99|3||TNT(5sticks)|ACME|10|5||Birdseed|ACME|10|1|+–––––-+––––-+––––+–––-+

Analysis

Thisexampledisplaystheitemsinordernumber20005.Orderitemsarestoredintheorderitemstable.EachproductisstoredbyitsproductID,whichreferstoaproductintheproductstable.TheproductsarelinkedtotheappropriatevendorinthevendorstablebythevendorID,whichisstoredwitheachproductrecord.TheFROMclausehereliststhethreetables,andtheWHEREclausedefinesbothofthosejoinconditions.AnadditionalWHEREconditionisthenusedtofilterjusttheitemsfororder20005.

Caution:PerformanceConsiderations

Oracleprocessesjoinsatruntime,relatingeachtableasspecified.Thisprocesscanbecomeveryresourceintensive,sobecarefulnottojointablesunnecessarily.Themoretablesyoujoin,themoreperformancedegrades.

NowwouldbeagoodtimetorevisitthefollowingexamplefromLesson14,“WorkingwithSubqueries.”Asyouwillrecall,thisSELECTstatementreturnsalistofcustomerswhoorderedproductTNT2:

InputClickheretoviewcodeimage

SELECTcust_name,cust_contactFROMcustomersWHEREcust_idIN(SELECTcust_idFROMordersWHEREorder_numIN(SELECTorder_numFROMorderitemsWHEREprod_id=‘TNT2’));

AsmentionedinLesson14,subqueriesmightnotalwaysthemostefficientwaytoperformcomplexSELECToperations,andsoaspromised,hereisthesamequeryusingjoins:

InputClickheretoviewcodeimage

SELECTcust_name,cust_contactFROMcustomers,orders,orderitems

WHEREcustomers.cust_id=orders.cust_idANDorderitems.order_num=orders.order_numANDprod_id=‘TNT2’;

OutputClickheretoviewcodeimage

+–––––-+––––—+|cust_name|cust_contact|+–––––-+––––—+|CoyoteInc.|YLee||YosemitePlace|YSam|+–––––-+––––—+

Analysis

AsexplainedinLesson14,returningthedataneededinthisqueryrequirestheuseofthreetables.Butinsteadofusingthemwithinnestedsubqueries,heretwojoinsareusedtoconnectthetables.TherearethreeWHEREclauseconditionshere.Thefirsttwoconnectthetablesinthejoin,andthelastonefiltersthedataforproductTNT2.

Hereisthesamestatement,thistimewiththejoinimplementedintheFROMclause:

InputClickheretoviewcodeimage

SELECTcust_name,cust_contactFROMcustomersINNERJOINordersONcustomers.cust_id=orders.cust_idINNERJOINorderitemsONorderitems.order_num=orders.order_numWHEREprod_id=‘TNT2’;

Analysis

Onceagain,threetablesarejoined.FROMspecifiesthefirsttable,andthentwoINNERJOINstatementsjointheadditionaltables,withanONclausedefiningtheirrelationship.Theoutputwouldbeexactlythesameasintheprecedingexample.

Tip:ItPaystoExperiment

Asyoucansee,thereisoftenmorethanonewaytoperformanygivenSQLoperation,andthereisrarelyadefinitiverightorwrongway.Performancecanbeaffectedbythetypeofoperation,theamountofdatainthetables,whetherindexesandkeysarepresent,andawholeslewofothercriteria.Therefore,itisoftenworthexperimentingwithdifferentselectionmechanismstofindtheonethatworksbestforyou.

SummaryJoinsareoneofthemostimportantandpowerfulfeaturesinSQL,andusingthemeffectivelyrequiresabasicunderstandingofrelationaldatabasedesign.Inthislesson,youlearnedsomeofthebasicsofrelationaldatabasedesignasanintroductiontolearningaboutjoins.Youalsolearnedhowtocreateanequijoin(alsoknownasaninnerjoin),whichisthemostcommonlyusedformofjoin.Inthenextlesson,you’lllearnhowtocreateothertypesofjoins.

Lesson16.CreatingAdvancedJoins

Inthislesson,you’lllearnallaboutadditionaljointypes—whattheyareandhowtousethem.You’llalsolearnhowtousetablealiasesandhowtouseaggregatefunctionswithjoinedtables.

UsingTableAliasesBackinLesson10,“CreatingCalculatedFields,”youlearnedhowtousealiasestorefertoretrievedtablecolumns.Thesyntaxtoaliasacolumnlookslikethis:

InputClickheretoviewcodeimage

SELECTRTrim(vend_name)||‘,(‘||RTrim(vend_country)||‘)’ASvend_titleFROMvendorsORDERBYvend_name;

Inadditiontousingaliasesforcolumnnamesandcalculatedfields,SQLalsoenablesyoutoaliastablenames.Therearetwoprimaryreasonstodothis:

ToshortentheSQLsyntax

ToenablemultipleusesofthesametablewithinasingleSELECTstatement

TakealookatthefollowingSELECTstatement.Itisbasicallythesamestatementasanexampleusedinthepreviouslesson,butithasbeenmodifiedtousealiases:

InputClickheretoviewcodeimage

SELECTcust_name,cust_contactFROMcustomersc,orderso,orderitemsoiWHEREc.cust_id=o.cust_idANDoi.order_num=o.order_numANDprod_id=‘TNT2’;

Analysis

NoticethatthethreetablesintheFROMclausesallhavealiases.customerscestablishescasanaliasforcustomers,andsoon.Thisenablesyoutousetheabbreviatedcinsteadofthefulltextcustomers.Inthisexample,thetablealiaseswereusedonlyintheWHEREclause,butaliasesarenotlimitedtojustWHERE.YoucanusealiasesintheSELECTlist,theORDERBYclause,andinanyotherpartofthestatementaswell.

Note:No

UnlikemostotherDBMSs,OracledoesnotusetheASkeywordfortablealiases;thus,customersciscorrect,butcustomersAScwouldthrowanerror.

Itisalsoworthnotingthattablealiasesareonlyusedduringqueryexecution.Unlikecolumnaliases,tablealiasesareneverreturnedtotheclient.

UsingDifferentJoinTypesSofar,youhaveusedonlysimplejoinsknownasinnerjoinsorequijoins.You’llnowtakealookatthreeadditionaljointypes:theselfjoin,thenaturaljoin,andtheouterjoin.

SelfJoinsAsmentionedearlier,oneoftheprimaryreasonstousetablealiasesistobeabletorefertothesametablemorethanonceinasingleSELECTstatement.Anexamplewilldemonstratethis.

Supposethataproblemwasfoundwithaproduct(itemidDTNTR),andyouthereforewantedtoknowalltheproductsmadebythesamevendortodeterminewhethertheproblemappliedtothem,too.ThisqueryrequiresthatyoufirstfindoutwhichvendorcreatesitemDTNTR,andnextfindwhichotherproductsaremadebythesamevendor.Thefollowingisonewaytoapproachthisproblem:

InputClickheretoviewcodeimage

SELECTprod_id,prod_nameFROMproductsWHEREvend_id=(SELECTvend_idFROMproductsWHEREprod_id=‘DTNTR’);

Output+–––+–––––-+|prod_id|prod_name|+–––+–––––-+|DTNTR|Detonator||FB|Birdseed||FC|Carrots||SAFE|Safe||SLING|Sling||TNT1|TNT(1stick)||TNT2|TNT(5sticks)|+–––+–––––-+

Analysis

Thisfirstsolutionusessubqueries.TheinnerSELECTstatementdoesasimpleretrievaltoreturnthevend_idofthevendorthatmakesitemDTNTR.ThatIDistheoneusedintheWHEREclauseoftheouterquerysoallitemsproducedbythatvendorareretrieved.(YoulearnedallaboutsubqueriesinLesson14,“WorkingwithSubqueries.”Refertothatlessonformoreinformation.)

Nowlookatthesamequeryusingajoin,andI’llpresentthecodeusingbothjoinformats:

Input

Clickheretoviewcodeimage

SELECTp1.prod_id,p1.prod_nameFROMproductsp1,productsp2WHEREp1.vend_id=p2.vend_idANDp2.prod_id=‘DTNTR’;

InputClickheretoviewcodeimage

SELECTp1.prod_id,p1.prod_nameFROMproductsp1INNERJOINproductsp2ONp1.vend_id=p2.vend_idWHEREp2.prod_id=‘DTNTR’;

Output+–––+–––––-+|prod_id|prod_name|+–––+–––––-+|DTNTR|Detonator||FB|Birdseed||FC|Carrots||SAFE|Safe||SLING|Sling||TNT1|TNT(1stick)||TNT2|TNT(5sticks)|+–––+–––––-+

Analysis

Thetwotablesneededinthisqueryareactuallythesametable,andsotheproductstableappearstwice.Althoughthisisperfectlylegal,anyreferencestotableproductswouldbeambiguousbecauseOraclecouldnotknowtowhichinstanceoftheproductstablesyouarereferring.

Toresolvethisproblem,tablealiasesareused.Thefirstoccurrenceofproductshasanaliasofp1,andthesecondhasanaliasofp2.Nowthosealiasescanbeusedastablenames.TheSELECTstatement,forexample,usesthep1prefixtoexplicitlystatethefullnameofthedesiredcolumns.Ifitdidnot,Oraclewouldreturnanerrorbecausetherearetwocolumnsnamedprod_idandprod_name.Itcannotknowwhichoneyouwant(eventhough,intruth,theyareoneandthesame).TheWHEREorONclausesjointhetables(bymatchingvend_idinp1tovend_idinp2),andresultsarefilteredbyprod_idinthesecondtabletoreturnonlythedesireddata.

Tip:SelfJoinsInsteadofSubqueries

Selfjoinsareoftenusedtoreplacestatementsusingsubqueriesthatretrievedatafromthesametableastheouterstatement.Althoughtheendresultisthesame,sometimesthesejoinsexecutefarmorequicklythantheydosubqueries.Itisusuallyworthexperimentingwithbothtodeterminewhichperformsbetter.

NaturalJoinsWhenevertablesarejoined,atleastonecolumnappearsinmorethanonetable(thecolumnsbeingjoined).Standardjoins(theinnerjoinsyoulearnedaboutinthepreviouslesson)returnalldata,evenmultipleoccurrencesofthesamecolumn.Anaturaljoinsimplyeliminatesthosemultipleoccurrencessoonlyoneofeachcolumnisreturned.

Howdoesitdothis?Theanswerisitdoesn’t—youdoit.Anaturaljoinisajoininwhichyouselectonlycolumnsthatareunique.Thisistypicallydoneusingawildcard(SELECT*)foronetableandexplicitsubsetsofthecolumnsforallothertables.Thefollowingisanexample,onceagain,presentedusingbothjoinsyntaxes:

InputClickheretoviewcodeimage

SELECTc.*,o.order_num,o.order_date,oi.prod_id,oi.quantity,OI.item_priceFROMcustomersc,orderso,orderitemsoiWHEREc.cust_id=o.cust_idANDoi.order_num=o.order_numANDprod_id=‘FB’;

InputClickheretoviewcodeimage

SELECTc.*,o.order_num,o.order_date,oi.prod_id,oi.quantity,OI.item_priceFROMcustomerscINNERJOINordersoONc.cust_id=o.cust_idINNERJOINorderitemsoiONoi.order_num=o.order_numWHEREprod_id=‘FB’;

Analysis

Intheseexamples,awildcardisusedforthefirsttableonly,andsoallcolumnsfromc(thecustomerstable)arereturned.Allothercolumnsareexplicitlylistedsonoduplicatecolumnsareretrieved.

Thetruthis,everyinnerjoinyouhavecreatedthusfarisactuallyanaturaljoin,andyouwillprobablyneverevenneedaninnerjointhatisnotanaturaljoin.

OuterJoinsMostjoinsrelaterowsinonetablewithrowsinanother.Butoccasionally,youwanttoincluderowsthathavenorelatedrows.Forexample,youmightusejoinstoaccomplishthefollowingtasks:

Counthowmanyorderseachcustomerplaced,includingcustomerswhohaveyettoplaceanorder

Listallproductswithorderquantities,includingproductsnotorderedbyanyone

Calculateaveragesalesizes,takingintoaccountcustomerswhohavenotyetplaced

anorder

Ineachoftheseexamples,thejoinincludestablerowsthathavenoassociatedrowsintherelatedtable.Thistypeofjoiniscalledanouterjoin.

ThefollowingSELECTstatementisasimpleinnerjoin.Itretrievesalistofallcustomersandtheirorders:

InputClickheretoviewcodeimage

SELECTcustomers.cust_id,orders.order_numFROMcustomersINNERJOINordersONcustomers.cust_id=orders.cust_id;

Outerjoinsyntaxissimilar.Toretrievealistofallcustomers,includingthosewhohaveplacednoorders,youcandothefollowing:

InputClickheretoviewcodeimage

SELECTcustomers.cust_id,orders.order_numFROMcustomersLEFTOUTERJOINordersONcustomers.cust_id=orders.cust_id;

Output+–––+–––—+|cust_id|order_num|+–––+–––—+|10001|20005||10001|20009||10002|||10003|20006||10004|20007||10005|20008|+–––+–––—+

Analysis

Liketheinnerjoinshowninthepreviouslesson,thisSELECTstatementusesthekeywordsOUTERJOINtospecifythejointype(insteadofspecifyingitintheWHEREclause).Butunlikeinnerjoins,whichrelaterowsinbothtables,outerjoinsalsoincluderowswithnorelatedrows.WhenusingOUTERJOINsyntax,youmustusetheRIGHTorLEFTkeywordstospecifythetablefromwhichtoincludeallrows(RIGHTfortheoneontherightofOUTERJOIN,andLEFTfortheoneontheleft).ThepreviousexampleusesLEFTOUTERJOINtoselectalltherowsfromthetableontheleftintheFROMclause(thecustomerstable).Toselectalltherowsfromthetableontheright,youuseaRIGHTOUTERJOIN,asshowninthisexample:

InputClickheretoviewcodeimage

SELECTcustomers.cust_id,orders.order_numFROMcustomersRIGHTOUTERJOINordersONorders.cust_id=customers.cust_id;

Note:No Or

Oracledoesnotsupporttheuseofthesimplified*=and=*OUTERJOINsyntaxpopularizedbyotherDBMSs.

Tip:OuterJoinTypes

Therearetwobasicformsofouterjoins—theleftouterjoinandtherightouterjoin.Theonlydifferencebetweenthemistheorderofthetablestheyarerelating.Inotherwords,aleftouterjoincanbeturnedintoarightouterjoinsimplybyreversingtheorderofthetablesintheFROMorWHEREclause.Assuch,thetwotypesofouterjoincanbeusedinterchangeably,andthedecisionaboutwhichonetouseisbasedpurelyonconvenience.

UsingJoinswithAggregateFunctionsAsyoulearnedinLesson12,“SummarizingData,”aggregatefunctionsareusedtosummarizedata.Althoughalltheexamplesofaggregatefunctionsthusfaronlysummarizeddatafromasingletable,thesefunctionscanalsobeusedwithjoins.

Todemonstratethis,let’slookatanexample.Youwanttoretrievealistofallcustomersandthenumberofordersthateachhasplaced.ThefollowingcodeusestheCOUNT()functiontoachievethis:

InputClickheretoviewcodeimage

SELECTcustomers.cust_name,COUNT(orders.order_num)ASnum_ordFROMcustomersINNERJOINordersONcustomers.cust_id=orders.cust_idGROUPBYcustomers.cust_name;

Output+–––––-+–––+|cust_name|num_ord|+–––––-+–––+|CoyoteInc.|2||Wascals|1||YosemitePlace|1||EFudd|1|+–––––-+–––+

Analysis

ThisSELECTstatementusesINNERJOINtorelatethecustomersandorderstablestoeachother.TheGROUPBYclausegroupsthedatabycustomer,andsothe

functioncallCOUNT(orders.order_num)countsthenumberofordersforeachcustomerandreturnsitasnum_ord.

Aggregatefunctionscanbeusedjustaseasilywithotherjointypes.Seethefollowingexample:

InputClickheretoviewcodeimage

SELECTcustomers.cust_name,COUNT(orders.order_num)ASnum_ordFROMcustomersLEFTOUTERJOINordersONcustomers.cust_id=orders.cust_idGROUPBYcustomers.cust_name;

Output+–––––-+–––+|cust_name|num_ord|+–––––-+–––+|CoyoteInc.|2||MouseHouse|0||Wascals|1||YosemitePlace|1||EFudd|1|+–––––-+–––+

Analysis

Thisexampleusesaleftouterjointoincludeallcustomers,eventhosewhohavenotplacedanyorders.TheresultsshowthatcustomerMouseHouse(with0orders)isalsoincludedthistime.

UsingJoinsandJoinConditionsBeforewrappingupthistwo-lessondiscussiononjoins,itisworthwhiletosummarizesomekeypointsregardingjoinsandtheiruse:

Paycarefulattentiontothetypeofjoinbeingused.Moreoftenthannot,you’llwantaninnerjoin,butthereareoftenvalidusesforouterjoins,too.

Makesureyouusethecorrectjoincondition,oryou’llreturnincorrectdata.

Makesureyoualwaysprovideajoincondition,oryou’llendupwiththeCartesianproduct.

Youmayincludemultipletablesinajoinandevenhavedifferentjointypesforeach.Althoughthisislegalandoftenuseful,makesureyoutesteachjoinseparatelybeforetestingthemtogether.Thismakestroubleshootingfarsimpler.

SummaryThislessonwasacontinuationofthepreviouslessononjoins.Thislessonstartedbyteachingyouhowandwhytousealiases,andthencontinuedwithadiscussionondifferentjointypesandvariousformsofsyntaxusedwitheach.Youalsolearnedhowtouseaggregatefunctionswithjoins,andsomeimportantdo’sanddon’tstokeepinmindwhenworkingwithjoins.

Lesson17.CombiningQueries

Inthislesson,you’lllearnhowtousetheUNIONoperatortocombinemultipleSELECTstatementsintooneresultset.

UnderstandingCombinedQueriesMostSQLqueriescontainasingleSELECTstatementthatreturnsdatafromoneormoretables.Oraclealsoenablesyoutoperformmultiplequeries(multipleSELECTstatements)andreturntheresultsasasinglequeryresultset.Thesecombinedqueriesareusuallyknownasunionsorcompoundqueries.

Therearebasicallytwoscenariosinwhichyouwouldusecombinedqueries:

Toreturnsimilarlystructureddatafromdifferenttablesinasinglequery

Toperformmultiplequeriesagainstasingletablereturningthedataasonequery

Tip:CombiningQueriesandMultiple Conditions

Forthemostpart,combiningtwoqueriestothesametableaccomplishesthesamethingasasinglequerywithmultipleWHEREclauseconditions.Inotherwords,anySELECTstatementwithmultipleWHEREclausescanalsobespecifiedasacombinedquery,asyou’llseeinthesectionthatfollows.However,theperformanceofeachofthetwotechniquescanvarybasedonthequeriesused.Assuch,itisalwaysgoodtoexperimenttodeterminewhichispreferableforspecificqueries.

CreatingCombinedQueriesSQLqueriesarecombinedusingtheUNIONoperator.UsingUNION,multipleSELECTstatementscanbespecified,andtheirresultscanbecombinedintoasingleresultset.

UsingUsingUNIONissimpleenough.AllyoudoisspecifyeachSELECTstatementandplacethekeywordUNIONbetweeneach.

Let’slookatanexample.Youneedalistofallproductscosting5orless.Youalsowanttoincludeallproductsmadebyvendors1001and1002,regardlessofprice.Ofcourse,youcancreateaWHEREclausethatwilldothis,butthistimeyou’lluseaUNIONinstead.

Asjustexplained,creatingaUNIONinvolveswritingmultipleSELECTstatements.First,lookattheindividualstatements:

InputClickheretoviewcodeimage

SELECTvend_id,prod_id,prod_priceFROMproductsWHEREprod_price<=5;

OutputClickheretoviewcodeimage

+–––+–––+––––+|vend_id|prod_id|prod_price|+–––+–––+––––+|1003|FC|2.5||1002|FU1|3.42||1003|SLING|4.49||1003|TNT1|2.5|+–––+–––+––––+

InputClickheretoviewcodeimage

SELECTvend_id,prod_id,prod_priceFROMproductsWHEREvend_idIN(1001,1002);

OutputClickheretoviewcodeimage

+–––+–––+––––+|vend_id|prod_id|prod_price|+–––+–––+––––+|1001|ANV01|5.99||1001|ANV02|9.99||1001|ANV03|14.99||1002|FU1|3.42||1002|OL1|8.99|+–––+–––+––––+

Analysis

ThefirstSELECTretrievesallproductswithapriceofnomorethan5.ThesecondSELECTusesINtofindallproductsmadebyvendors1001and1002.

Tocombinethesetwostatements,dothefollowing:

InputClickheretoviewcodeimage

SELECTvend_id,prod_id,prod_priceFROMproductsWHEREprod_price<=5UNIONSELECTvend_id,prod_id,prod_priceFROMproductsWHEREvend_idIN(1001,1002);

OutputClickheretoviewcodeimage

+–––+–––+––––+|vend_id|prod_id|prod_price|+–––+–––+––––+|1003|FC|2.5|

|1002|FU1|3.42||1003|SLING|4.49||1003|TNT1|2.5||1001|ANV01|5.99||1001|ANV02|9.99||1001|ANV03|14.99||1002|OL1|8.99|+–––+–––+––––+

Analysis

TheprecedingstatementsaremadeupofbothofthepreviousSELECTstatementsseparatedbytheUNIONkeyword.UNIONinstructsOracletoexecutebothSELECTstatementsandcombinetheoutputintoasinglequeryresultset.

Asapointofreference,hereisthesamequeryusingmultipleWHEREclausesinsteadofaUNION:

InputClickheretoviewcodeimage

SELECTvend_id,prod_id,prod_priceFROMproductsWHEREprod_price<=5ORvend_idIN(1001,1002);

Inthissimpleexample,theUNIONmightactuallybemorecomplicatedthanusingaWHEREclause.Butwithmorecomplexfilteringconditions,orifthedataisbeingretrievedfrommultipletables(andnotjustasingletable),theUNIONcouldhavemadetheprocessmuchsimpler.

RulesAsyoucansee,unionsareveryeasytouse,butafewrulesgovernexactlywhichqueriescanbecombined:

AUNIONmustbecomprisedoftwoormoreSELECTstatements,eachseparatedbythekeywordUNION(so,ifcombiningfourSELECTstatements,threeUNIONkeywordswouldbeused).

EachqueryinaUNIONmustcontainthesamecolumns,expressions,oraggregatefunctions(althoughcolumnsneednotbelistedinthesameorder).

Columndatatypesmustbecompatible.Theyneednotbetheexactsametype,buttheymustbeofatypethatOraclecanimplicitlyconvert(forexample,differentnumerictypesordifferentdatetypes).

Asidefromthesebasicrulesandrestrictions,unionscanbeusedforanydataretrievaltasks.

IncludingorEliminatingDuplicateRowsGobacktotheprecedingsectiontitled“UsingUNION”andlookatthesampleSELECTstatementsused.You’llnoticethatwhenexecutedindividually,thefirstSELECTstatementreturnsfourrows,andthesecondSELECTstatementreturnsfiverows.However,whenthetwoSELECTstatementsarecombinedwithaUNION,onlyeightrowsarereturned,notnine.

TheUNIONautomaticallyremovesanyduplicaterowsfromthequeryresultset(inotherwords,itbehavesjustasmultipleWHEREclauseconditionsinasingleSELECTwould).Becausevendor1002createsaproductthatcostslessthan5,thatrowwasreturnedbybothSELECTstatements.WhentheUNIONwasused,theduplicaterowwaseliminated.

ThisisthedefaultbehaviorofUNION,butyoucanchangethisifyousodesire.Ifyoudo,infact,wantalloccurrencesofallmatchesreturned,youcanuseUNIONALLinsteadofUNION.

Lookatthefollowingexample:

InputClickheretoviewcodeimage

SELECTvend_id,prod_id,prod_priceFROMproductsWHEREprod_price<=5UNIONALLSELECTvend_id,prod_id,prod_priceFROMproductsWHEREvend_idIN(1001,1002);

OutputClickheretoviewcodeimage

+–––+–––+––––+|vend_id|prod_id|prod_price|+–––+–––+––––+|1003|FC|2.5||1002|FU1|3.42||1003|SLING|4.49||1003|TNT1|2.5||1001|ANV01|5.99||1001|ANV02|9.99||1001|ANV03|14.99||1002|FU1|3.42||1002|OL1|8.99|+–––+–––+––––+

Analysis

UsingUNIONALL,Oracledoesnoteliminateduplicates.Therefore,theprecedingexamplereturnsninerows,oneofthemoccurringtwice.

Tip: versus

ThebeginningofthislessonsaidthatUNIONalmostalwaysaccomplishesthesamethingasmultipleWHEREconditions.UNIONALListheformofUNIONthataccomplisheswhatcannotbedonewithWHEREclauses.Ifyoudo,infact,wantalloccurrencesofmatchesforeverycondition(includingduplicates),youmustuseUNIONALLandnotWHERE.

SortingCombinedQueryResultsSELECTstatementoutputissortedusingtheORDERBYclause.WhencombiningquerieswithaUNION,onlyoneORDERBYclausemaybeused,anditmustoccurafterthefinalSELECTstatement.Thereisverylittlepointinsortingpartofaresultsetonewayandpartanotherway,andsomultipleORDERBYclausesarenotallowed.

ThefollowingexamplesortstheresultsreturnedbythepreviouslyusedUNION:

InputClickheretoviewcodeimage

SELECTvend_id,prod_id,prod_priceFROMproductsWHEREprod_price<=5UNIONSELECTvend_id,prod_id,prod_priceFROMproductsWHEREvend_idIN(1001,1002)ORDERBYvend_id,prod_price;

OutputClickheretoviewcodeimage

+–––+–––+––––+|vend_id|prod_id|prod_price|+–––+–––+––––+|1001|ANV01|5.99||1001|ANV02|9.99||1001|ANV03|14.99||1002|FU1|3.42||1002|OL1|8.99||1003|TNT1|2.5||1003|FC|2.5||1003|SLING|4.49|+–––+–––+––––+

Analysis

ThisUNIONtakesasingleORDERBYclauseafterthefinalSELECTstatement.EventhoughtheORDERBYappearstoonlybeapartofthatlastSELECTstatement,OraclewillinfactuseittosortalltheresultsreturnedbyalltheSELECTstatements.

Note:CombiningDifferentTables

Forthesakeofsimplicity,alltheexamplesinthislessoncombinedqueriesusingthesametable.However,everythingyoulearnedherealsoappliestousingUNIONtocombinequeriesofdifferenttables.

SummaryInthislesson,youlearnedhowtocombineSELECTstatementswiththeUNIONoperator.UsingUNION,youcanreturntheresultsofmultiplequeriesasonecombinedquery,eitherincludingorexcludingduplicates.TheuseofUNIONcangreatlysimplifycomplexWHEREclausesandretrievingdatafrommultipletables.

Lesson18.InsertingData

Inthislesson,youwilllearnhowtoinsertdataintotablesusingtheSQLINSERTstatement.

UnderstandingDataInsertionSELECTisundoubtedlythemostfrequentlyusedSQLstatement(whichiswhythepast15lessonswerededicatedtoit).ButtherearethreeotherfrequentlyusedSQLstatementsthatyoushouldlearn.ThefirstoneisINSERT.(You’llgettotheothertwo,UPDATEandDELETE,inthenextlesson.)

Asitsnamesuggests,INSERTisusedtoinsert(add)rowstoadatabasetable.Insertcanbeusedinseveralways:

Toinsertasinglecompleterow

Toinsertasinglepartialrow

Toinsertmultiplerows

Toinserttheresultsofaquery

You’llnowlookateachofthese.

Tip: andSystemSecurity

UseoftheINSERTstatementcanbedisabledpertableorperuserusingOraclesecurity,asexplainedinLesson26,“ManagingSecurity.”

InsertingCompleteRowsThesimplestwaytoinsertdataintoatableistousethebasicINSERTsyntax,whichrequiresthatyouspecifythetablenameandthevaluestobeinsertedintothenewrow.Hereisanexampleofthis:

Input

INSERTINTOCustomersVALUES(10006,‘PepE.LaPew’,‘100MainStreet’,‘LosAngeles’,‘CA’,‘90046’,‘USA’,NULL,NULL);

Note:NoOutput

INSERTstatementsusuallygeneratenooutput,butifyouexecutetheprecedingstatementinOracleSQLDeveloper,youshouldseea1rowinserted.message.

Analysis

Theprecedingexampleinsertsanewcustomerintothecustomerstable.ThedatatobestoredineachtablecolumnisspecifiedintheVALUESclause,andavaluemustbeprovidedforeverycolumn.Ifacolumnhasnovalue(forexample,thecust_contactandcust_emailcolumns),theNULLvalueshouldbeused(assumingthetableallowsnovaluetobespecifiedforthatcolumn).Thecolumnsmustbepopulatedintheorderinwhichtheyappearinthetabledefinition.

Althoughthissyntaxisindeedsimple,itisnotatallsafeandshouldgenerallybeavoidedatallcosts.ThepreviousSQLstatementishighlydependentontheorderinwhichthecolumnsaredefinedinthetable.Italsodependsoninformationaboutthatorderbeingreadilyavailable.Evenifitisavailable,thereisnoguaranteethatthecolumnswillbeintheexactsameorderthenexttimethetableisreconstructed.Therefore,writingSQLstatementsthatdependonspecificcolumnorderingisveryunsafe.Ifyoudoso,somethingwillinevitablybreakatsomepoint.

Thesafer(andunfortunatelymorecumbersome)waytowritetheINSERTstatementisasfollows:

InputClickheretoviewcodeimage

INSERTINTOcustomers(cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country)VALUES(10006,‘PepE.LaPew’,‘100MainStreet’,‘LosAngeles’,‘CA’,‘90046’,‘USA’);

Note:Can’t Twice

IfyouexecutedthislatestINSERTstatement,youwouldhaveseenanerrormessagecomplaininguniqueconstraintviolated.Thisisbecausethecust_idfieldisaprimarykeyandsoeverycustomermusthaveauniquecust_id.Asbothexamplesusedthesame10006value,Oraclecan’tacceptthesecondinsertion.Youcansimplyaddressthisproblembyusing10007asthecust_id,andifyouaregoingtoinsertadditionalrows,keepincrementingthatnumber.

Analysis

ThisexampledoestheexactsamethingasthepreviousINSERTstatement,butthistime,thecolumnnamesareexplicitlystatedinparenthesesafterthetablename.Whentherowisinserted,OraclematcheseachiteminthecolumnslistwiththeappropriatevalueintheVALUESlist.ThefirstentryinVALUEScorrespondstothefirstspecifiedcolumnname.Thesecondvaluecorrespondstothesecondcolumnname,andsoon.

Note:AutomaticPrimaryKeys

Sometablecolumnsneeduniquevalues;forexample,ordernumbers,employeeIDs,or(asintheexamplejustshown)customerIDs.Ratherthanhavetoassignuniquevaluesmanuallyeachtimearowisadded(andhavingtokeeptrackofwhatvaluewaslastused),mostDBMSsprovideawaytoautomaticallyassignthenextavailablenumberforyoueachtimearowisaddedtoatable.Thisfunctionalityisknownasautoincrement.Unfortunately,Oracleonlyaddedsupportforautoincrementinversion12c;usersofpriorversions(includingOracleExpressEdition)can’tuseautoincrementandhavetoresorttoothertechniquestokeeptrackofthenextavailableidentifier.AsthisbookisintendedtobeusedbyOracle10g,11g,and12cusers,IoptednottouseOracle’snewautoincrementfunctionality.However,ifyouareusingOracle12c,feelfreetotakeadvantageofthislong-awaitedenhancement.

Becausecolumnnamesareprovided,theVALUESmustmatchthespecifiedcolumnnamesintheorderinwhichtheyarespecified,andnotnecessarilyintheorderthatthecolumnsappearintheactualtable.Theadvantageofthisisthat,evenifthetablelayoutchanges,theINSERTstatementstillworkscorrectly.You’llalsonoticethatthecolumnswithNULLvalues(thefinaltwo)werenotlistedinthecolumnlistandsonovalueswereneeded.

ThefollowingINSERTstatementpopulatesalltherowcolumns(justasbefore),butitdoessoinadifferentorder.Becausethecolumnnamesarespecified,theinsertionworkscorrectly:

InputClickheretoviewcodeimage

INSERTINTOcustomers(cust_id,cust_name,cust_contact,cust_email,cust_address,cust_city,cust_state,cust_zip,cust_country)VALUES(10006,‘PepE.LaPew’,NULL,NULL,‘100MainStreet’,‘LosAngeles’,‘CA’,‘90046’,‘USA’);

Tip:AlwaysUseaColumnList

Asarule,neveruseINSERTwithoutexplicitlyspecifyingthecolumnlist.ThisgreatlyincreasestheprobabilitythatyourSQLwillcontinuetofunctionintheeventthattablechangesoccur.

Caution:Use Carefully

RegardlessoftheINSERTsyntaxbeingused,thecorrectnumberofVALUESmustbespecified.Ifnocolumnnamesareprovided,avaluemustbepresentforeverytablecolumn.Ifcolumnnamesareprovided,avaluemustbepresentforeachlistedcolumn.Ifnoneispresent,anerrormessagewillbegenerated,andtherowwillnotbeinserted.

Usingthissyntax,youcanalsoomitcolumns.Thismeansyouonlyprovidevaluesforsomecolumns,butnotforothers.(You’veactuallyalreadyseenanexampleofthis:cust_idwasomittedwhencolumnnameswereexplicitlylisted.)

Caution:OmittingColumns

YoumayomitcolumnsfromanINSERToperationifthetabledefinitionsoallows.Oneofthefollowingconditionsmustexist:

ThecolumnisdefinedasallowingNULLvalues(novalueatall).

Adefaultvalueisspecifiedinthetabledefinition.Thismeansthedefaultvaluewillbeusedifnovalueisspecified.

IfyouomitavaluefromatablethatdoesnotallowNULLvaluesanddoesnothaveadefault,Oraclegeneratesanerrormessage,andtherowisnotinserted.

Tip:InsertingMultipleRows

UnlikemostotherDBMSs,Oracledoesn’tsupportaversionofINSERTthatcaninsertmultiplerowsatonce.Thereareworkarounds(usingthedualtableI’vementionedpreviously),butinpracticeyou’llprobablyjustusemultipleINSERTstatements(aswedidinthepopulate.sqlfilebackinLesson3,“WorkingwithOracle”).

InsertingRetrievedDataINSERTisusuallyusedtoaddarowtoatableusingspecifiedvalues.ThereisanotherformofINSERTthatcanbeusedtoinserttheresultofaSELECTstatementintoatable.ThisisknownasINSERTSELECT,and,asitsnamesuggests,itismadeupofanINSERTstatementandaSELECTstatement.

Supposeyouwanttomergealistofcustomersfromanothertableintoyourcustomerstable.InsteadofreadingonerowatatimeandinsertingitwithINSERT,youcandothefollowing:

Note:InstructionsNeededfortheNextExample

Thefollowingexampleimportsdatafromatablenamedcustnewintothecustomerstable.Totrythisexample,createanewtablenamedcustnewusingtheCREATETABLEcustomersstatementincreate.sql,andobviouslyreplacingcustomerswithcustnew.Thenaddafewcustomersofyourown,beingcarefultonotusecust_idvaluesthatwerealreadyusedincustomers(thesubsequentINSERToperationwillfailifprimarykeyvaluesareduplicated).Theeasiestwaytodothisisjuststartthenumbersmuchhigher,perhapsat20000.

InputClickheretoviewcodeimage

INSERTINTOcustomers(cust_id,cust_contact,cust_email,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country)SELECTcust_id,cust_contact,cust_email,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country

FROMcustnew;

Analysis

ThisexampleusesINSERTSELECTtoimportallthedatafromcustnewintocustomers.InsteadoflistingtheVALUEStobeinserted,theSELECTstatementretrievesthemfromcustnew.EachcolumnintheSELECTcorrespondstoacolumninthespecifiedcolumnslist.Howmanyrowswillthisstatementinsert?Thatdependsonhowmanyrowsareinthecustnewtable.Ifthetableisempty,norowsareinserted(andnoerrorwillbegeneratedbecausetheoperationisstillvalid).Ifthetabledoes,infact,containdata,allthatdataisinsertedintocustomers.

Tip:ColumnNamesin

ThisexampleusesthesamecolumnnamesinboththeINSERTandSELECTstatementsforsimplicity’ssake,butthereisnorequirementthatthecolumnnamesmatch.Infact,OracledoesnotevenpayattentiontothecolumnnamesreturnedbytheSELECT.Rather,thecolumnpositionisused,sothefirstcolumnintheSELECT(regardlessofitsname)willbeusedtopopulatethefirstspecifiedtablecolumn,andsoon.Thisisveryusefulwhenimportingdatafromtablesthatusedifferentcolumnnames.

TheSELECTstatementusedinanINSERTSELECTcanincludeaWHEREclausetofilterthedatatobeinserted.

Tip:MoreExamples

LookingformoreexamplesofINSERTuse?SeetheexampletablepopulationscriptsusedbackinLesson3topopulatetheexampletablesusedinthisbook.

SummaryInthislesson,youlearnedhowtouseINSERTtoinsertrowsintoadatabasetable.YoulearnedseveralotherwaystouseINSERT,andwhyexplicitcolumnspecificationispreferred.YoualsolearnedhowtouseINSERTSELECTtoimportrowsfromanothertable.Inthenextlesson,you’lllearnhowtouseUPDATEandDELETEtofurthermanipulatetabledata.

Lesson19.UpdatingandDeletingData

Inthislesson,youwilllearnhowtousetheUPDATEandDELETEstatementstoenableyoutofurthermanipulateyourtabledata.

UpdatingDataToupdate(modify)datainatable,theUPDATEstatementisused.UPDATEcanbeusedintwoways:

Toupdatespecificrowsinatable

Toupdateallrowsinatable

Let’stakealookateachoftheseuses.

Caution:Don’tOmitthe Clause

SpecialcaremustbeexercisedwhenusingUPDATEbecauseitisalltooeasytomistakenlyupdateeveryrowinyourtable.PleasereadthisentiresectiononUPDATEbeforeusingthisstatement.

Tip: andSecurity

UseoftheUPDATEstatementcanberestrictedandcontrolled.MoreonthisinLesson26,“ManagingSecurity.”

TheUPDATEstatementisveryeasytouse—somewouldsaytooeasy.ThebasicformatofanUPDATEstatementismadeupofthreeparts:

Thetabletobeupdated

Thecolumnnamesandtheirnewvalues

Thefilterconditionthatdetermineswhichrowsshouldbeupdated

Let’stakealookatasimpleexample.Customer10005nowhasanemailaddress,andsohisrecordneedsupdating.Thefollowingstatementperformsthisupdate:

InputClickheretoviewcodeimage

UPDATEcustomersSETcust_email=‘elmer@fudd.com’WHEREcust_id=10005;

TheUPDATEstatementalwaysbeginswiththenameofthetablebeingupdated.Inthisexample,itisthecustomerstable.TheSETcommandisthenusedtoassignthenewvaluetoacolumn.Asusedhere,theSETclausesetsthecust_emailcolumntothespecifiedvalue:

ClickheretoviewcodeimageSETcust_email=‘elmer@fudd.com’

TheUPDATEstatementfinisheswithaWHEREclausethattellsOraclewhichrowtoupdate.WithoutaWHEREclause,Oraclewouldupdatealltherowsinthecustomerstablewiththisnewemailaddress—definitelynotthedesiredeffect.

Note:NoOutput

UPDATEstatementsusuallygeneratenooutput,butifyouexecutetheprecedingstatementinOracleSQLDeveloper,youshouldseea1rowupdated.message.Ifmorethanonerowwasupdated,well,thatprobablymeansthatyouomitted(ormistyped)theWHEREclause.

Updatingmultiplecolumnsrequiresaslightlydifferentsyntax:

InputClickheretoviewcodeimage

UPDATEcustomersSETcust_name=‘TheFudds’,cust_email=‘elmer@fudd.com’WHEREcust_id=10005;

Whenupdatingmultiplecolumns,onlyasingleSETcommandisused,andeachcolumn=valuepairisseparatedbyacomma.(Nocommaisspecifiedafterthelastcolumn.)Inthisexample,columnscust_nameandcust_emailwillbothbeupdatedforcustomer10005.

Tip:UsingSubqueriesinan Statement

SubqueriesmaybeusedinUPDATEstatements,enablingyoutoupdatecolumnswithdataretrievedwithaSELECTstatement.ReferbacktoLesson14,“WorkingwithSubqueries,”formoreinformationonsubqueriesandtheiruses.

Todeleteacolumn’svalue,youcansetittoNULL(assumingthetableisdefinedtoallowNULLvalues).Youcandothisasfollows:

Input

UPDATEcustomersSETcust_email=NULLWHEREcust_id=10005;

HeretheNULLkeywordisusedtosavenovaluetothecust_emailcolumn.

DeletingDataTodelete(remove)datafromatable,theDELETEstatementisused.DELETEcanbeusedintwoways:

Todeletespecificrowsfromatable

Todeleteallrowsfromatable

You’llnowtakealookateachofthese.

Caution:Don’tOmitthe Clause

SpecialcaremustbeexercisedwhenusingDELETEbecauseitisalltooeasytomistakenlydeleteeveryrowfromyourtable.PleasereadthisentiresectiononDELETEbeforeusingthisstatement.

Tip: andSecurity

UseoftheDELETEstatementcanberestrictedandcontrolled.MoreonthisinLesson26.

IalreadystatedthatUPDATEisveryeasytouse.Thegood(andbad)newsisthatDELETEiseveneasiertouse.

Thefollowingstatementdeletesasinglerowfromthecustomerstable:

Input

DELETEFROMcustomersWHEREcust_id=10006;

Thisstatementshouldbeself-explanatory.DELETEFROMrequiresthatyouspecifythenameofthetablefromwhichtodeletethedata.TheWHEREclausefilterswhichrowstodelete.Inthisexample,onlycustomer10006willbedeleted.IftheWHEREclausewereomitted,thisstatementwouldhavedeletedeverycustomerinthetable.

Note:NoOutput

DELETEstatementsusuallygeneratenooutput,butifyouexecutethepreviousstatementinOracleSQLDeveloper,youshouldseea1rowdeleted.message—andyes,thatmeansthatifmorethanonerowwasdeleted,youprobablyomitted(ormistyped)theWHEREclause.

DELETEtakesnocolumnnamesorwildcardcharacters.DELETEdeletesentirerows,notcolumns.Todeletespecificcolumns,useanUPDATEstatement(asshownearlierinthislesson).

Note:TableContents,NotTables

TheDELETEstatementdeletesrowsfromtables,evenallrowsfromtables,butDELETEneverdeletesthetableitself.

GuidelinesforUpdatingandDeletingDataTheUPDATEandDELETEstatementsusedintheprevioussectionsallhaveWHEREclauses,andthereisaverygoodreasonforthis.IfyouomittheWHEREclause,theUPDATEorDELETEisappliedtoeveryrowinthetable.Inotherwords,ifyouexecuteanUPDATEwithoutaWHEREclause,everyrowinthetableisupdatedwiththenewvalues.Similarly,ifyouexecuteDELETEwithoutaWHEREclause,allthecontentsofthetablearedeleted.

HerearesomebestpracticesthatmanySQLprogrammersfollow:

NeverexecuteanUPDATEoraDELETEwithoutaWHEREclauseunlessyoureallydointendtoupdateanddeleteeveryrow.

Makesureeverytablehasaprimarykey(refertoLesson15,“JoiningTables,”ifyouhaveforgottenwhatthisis),anduseitastheWHEREclausewheneverpossible.(Youmayspecifyindividualprimarykeys,multiplevalues,orvalueranges.)

BeforeyouuseaWHEREclausewithanUPDATEoraDELETE,firsttestitwithaSELECTtomakesureitisfilteringtherightrecords—itisfartooeasytowriteincorrectWHEREclauses.

Usedatabase-enforcedreferentialintegrity(refertoLesson15forthisone,too)soOraclewillnotallowthedeletionofrowsthathavedatainothertablesrelatedtothem.

Caution:UsewithCaution

ThebottomlineisthatOraclehasnoUndobutton.BeverycarefulusingUPDATEandDELETE,oryou’llfindyourselfupdatinganddeletingthewrongdata.

SummaryInthislesson,youlearnedhowtousetheUPDATEandDELETEstatementstomanipulatethedatainyourtables.Youlearnedthesyntaxforeachofthesestatements,aswellastheinherentdangerstheyexpose.YoualsolearnedwhyWHEREclausesaresoimportantinUPDATEandDELETEstatements,andyouweregivenguidelinesthatshouldbefollowedtohelpensurethatdatadoesnotgetdamagedinadvertently.

Lesson20.CreatingandManipulatingTables

Inthislesson,you’lllearnthebasicsoftablecreation,alteration,anddeletion.

CreatingTablesOraclePL/SQLstatementsarenotusedjustfortabledatamanipulation.Indeed,SQLstatementscanbeusedtoperformalldatabaseandtableoperations,includingthecreationandmanipulationoftablesthemselves.

Therearegenerallytwowaystocreatedatabasetables:

Usingadatabaseclient(liketheonesdiscussedinLesson2,“GettingStartedwithOracleandPL/SQL”)thatcanbeusedtocreateandmanagedatabasetablesinteractively

ManipulatingtablesdirectlywithOraclePL/SQLstatements

Tocreatetablesprogrammatically,theCREATETABLESQLstatementisused.Itisworthnotingthatwhenyouuseinteractivetools,youareactuallyusingOracleSQLstatements.Insteadofyourwritingthesestatements,however,theinterfacegeneratesandexecutestheSQLseamlesslyforyou(thesameistrueforchangestoexistingtables).

Tip:AdditionalExamples

Foradditionalexamplesoftablecreationscripts,seethecodeusedtocreatethesampletablesusedinthisbook.

Note:JusttheBasics

Oraclesupportsavastarrayoftablecreationoptions,farmorethanasinglelessoncandojusticeto.Inthislesson,wecoverthebasics,justsoyoucangetafeelforwhat’sinvolvedintablecreation,andsothattheaccompanyingtablecreationscriptsmakesense.TolearnmoreaboutallthatCREATETABLEcando,you’llwanttoconsulttheOracledocumentation.

TheBasicsofTableCreationTocreateatableusingCREATETABLE,youmustspecifythefollowinginformation:

ThenameofthenewtablespecifiedafterthekeywordsCREATETABLE

Thenameanddefinitionofthetablecolumnsseparatedbycommas

TheCREATETABLEstatementmayalsoincludeotherkeywordsandoptions,butataminimumyouneedthetablenameandcolumndetails.ThefollowingOracleSQLstatementcreatesthecustomerstableusedthroughoutthisbook:

InputClickheretoviewcodeimage

–––––––––––––––—Createcustomerstable–––––––––––––––CREATETABLEcustomers(cust_idintNOTNULL,cust_namechar(50)NOTNULL,cust_addresschar(50)NULL,cust_citychar(50)NULL,cust_statechar(5)NULL,cust_zipchar(10)NULL,cust_countrychar(50)NULL,cust_contactchar(50)NULL,cust_emailchar(255)NULL);

Analysis

Thefirstfewlinesinthisexamplearecomments,andarethusignoredbyOracle.ThenewtablenameisspecifiedimmediatelyfollowingtheCREATETABLEkeywords.Theactualtabledefinition(allthecolumns)isenclosedwithinparentheses.Thecolumnsthemselvesareseparatedbycommas.Thisparticulartableismadeupofninecolumns.Eachcolumndefinitionstartswiththecolumnname(whichmustbeuniquewithinthetable),followedbythecolumn’sdatatype.(RefertoLesson1,“UnderstandingSQL,”foranexplanationofdatatypes.)

WhatarenotinthepreviousCREATETABLEstatementaretheprimaryandforeignkeydefinitions.Althoughitispossibletodefineprimarykeysattablecreationtime,thecodeisoftencleanerandeasiertomaintainwhenthoseareaddedaftertablecreation.We’llrevisitthiswhenweintroduceALTERTABLEshortly.

Tip:StatementFormatting

Asyoumayrecall,whitespaceisignoredinSQLstatements.Statementscanbetypedononelonglineorbrokenupovermanylines.Itmakesnodifferenceatall.ThisenablesyoutoformatyourSQLasbestsuitsyou.TheprecedingCREATETABLEstatementisagoodexampleofSQLstatementformatting—thecodeisspecifiedovermultiplelines,withthecolumndefinitionsindentedforeasierreadingandediting.FormattingyourSQLinthiswayisentirelyoptional,buthighlyrecommended.

Workingwith ValuesBackinLesson6,“FilteringData,”youlearnedthatNULLvaluesarenovaluesorthelackofavalue.AcolumnthatallowsNULLvaluesalsoallowsrowstobeinsertedwithnovalueatallinthatcolumn.AcolumnthatdoesnotallowNULLvaluesdoesnotacceptrowswithnovalue—inotherwords,thatcolumnwillalwaysberequiredwhenrowsareinsertedorupdated.

EverytablecolumniseitheraNULLcolumnoraNOTNULLcolumn,andthatstateisspecifiedinthetabledefinitionatcreationtime.Takealookatthefollowingexample:

InputClickheretoviewcodeimage

–––––––––––––––—Createorderstable–––––––––––––––CREATETABLEorders(order_numintNOTNULL,order_datedateNOTNULL,cust_idintNOTNULL);

Analysis

Thisstatementcreatestheorderstableusedthroughoutthisbook.orderscontainsthreecolumns:ordernumber,orderdate,andthecustomerID.Allthreecolumnsarerequired,andsoeachcontainsthekeywordNOTNULL.Thispreventstheinsertionofcolumnswithnovalue.Ifsomeonetriestoinsertnovalue,anerrorwillbereturned,andtheinsertionwillfail.

ThisnextexamplecreatesatablewithamixtureofNULLandNOTNULLcolumns:

InputClickheretoviewcodeimage

–––––––––––––––—Createvendorstable–––––––––––––––CREATETABLEvendors(vend_idintNOTNULL,vend_namechar(50)NOTNULL,vend_addresschar(50)NULL,vend_citychar(50)NULL,vend_statechar(5)NULL,vend_zipchar(10)NULL,vend_countrychar(50)NULL);

Analysis

Thisstatementcreatesthevendorstableusedthroughoutthisbook.ThevendorIDandvendornamecolumnsarebothrequired,andare,therefore,specifiedasNOTNULL.ThefiveremainingcolumnsallallowNULLvalues,andsoNOTNULLisnotspecified.NULListhedefaultsetting,soifNOTNULLisnotspecified,NULLisassumed.

Caution:Understanding

Don’tconfuseNULLvalueswithemptystrings.ANULLvalueisthelackofavalue;itisnotanemptystring.Ifyouweretospecify''(twosinglequoteswithnothinginbetweenthem),thatwouldbeallowedinaNOTNULLcolumn.Anemptystringisavalidvalue;itisnotnovalue.NULLvaluesarespecifiedwiththekeywordNULL,notwithanemptystring.

SpecifyingDefaultValuesOracleallowsyoutospecifydefaultvaluestobeusedifnovalueisspecifiedwhenarowisinserted.DefaultvaluesarespecifiedusingtheDEFAULTkeywordinthecolumndefinitionsintheCREATETABLEstatement.

Lookatthefollowingexample(nottheoneweactuallyuseinthisbook):

InputClickheretoviewcodeimage

–––––––––––––––—Createorderitemstable–––––––––––––––CREATETABLEorderitems(order_numintNOTNULL,order_itemintNOTNULL,prod_idchar(10)NOTNULL,quantityintDEFAULT1NOTNULL,item_pricedecimal(8,2)NOTNULL);

Analysis

Thisstatementcreatestheorderitemstablethatcontainstheindividualitemsthatmakeupanorder.(Theorderitselfisstoredintheorderstable.)Thequantitycolumncontainsthequantityforeachiteminanorder.Inthisexample,addingthetextDEFAULT1tothecolumndescriptioninstructsOracletouseaquantityof1ifnoquantityisspecified.

Tip:Using Insteadof Values

ManydatabasedevelopersuseDEFAULTvaluesinsteadofNULLcolumns,especiallyincolumnsthatwillbeusedincalculationsordatagroupings.

UpdatingTablesToupdatetabledefinitions,theALTERTABLEstatementisused,butideally,tablesshouldneverbealteredaftertheycontaindata.Youshouldspendsufficienttimeanticipatingfutureneedsduringthetabledesignprocesssoextensivechangesarenotrequiredlateron.

TochangeatableusingALTERTABLE,youmustspecifythefollowinginformation:

ThenameofthetabletobealteredafterthekeywordsALTERTABLE.(Thetablemustexistoranerrorwillbegenerated.)

Thelistofchangestobemade.

Thefollowingexampleaddsacolumntoatable:

Input

ALTERTABLEvendorsADDvend_phoneCHAR(20);

Analysis

Thisstatementaddsacolumnnamedvend_phonetothevendorstable.Thedatatypemustbespecified.

Toremovethisnewlyaddedcolumn,youcandothefollowing:

Input

ALTERTABLEvendorsDROPCOLUMNvend_phone;

PrimaryKeysRevisitedAsalreadyexplained,primarykeyvaluesmustbeunique.Thatis,everyrowinatablemusthaveauniqueprimarykeyvalue.Ifasinglecolumnisusedfortheprimarykey,itmustbeunique;ifmultiplecolumnsareused,thecombinationofthemmustbeunique.

PrimarykeyscanbedefinedwithinCREATETABLEstatements.However,manydevelopersprefertocreatetheirtablesandthenaddallkeys.Addingkeysisatableupdate,andsotheALTERTABLEcommandisused.

Here’sanexample:

InputClickheretoviewcodeimage

–––––––-—Defineprimarykeys–––––––-ALTERTABLEcustomersADDCONSTRAINTpk_customersPRIMARYKEY(cust_id);ALTERTABLEorderitemsADDCONSTRAINTpk_orderitemsPRIMARYKEY(order_num,order_item);ALTERTABLEordersADDCONSTRAINTpk_ordersPRIMARYKEY(order_num);ALTERTABLEproductsADDCONSTRAINTpk_productsPRIMARYKEY(prod_id);ALTERTABLEvendorsADDCONSTRAINTpk_vendorsPRIMARYKEY(vend_id);ALTERTABLEproductnotesADDCONSTRAINTpk_productnotesPRIMARYKEY(note_id);

Analysis

Theprecedingblockofcodeisfromourcreate.sqlfile,anditdefinestheprimarykeysforallsixtables.ALTERTABLEisusedtoupdateatable,andADDCONSTRAINTPRIMARYKEYspecifiesthatthetablechangeistheadditionofaprimarykey.Allkeysmustbenamedwithuniquenames;hereIusedpk_followedbythetablename.Finally,thecolumn(orcolumns)thatcomprisetheprimarykeyareidentified.

DefiningForeignKeysALTERTABLEisalsousedtodefineforeignkeys.Thefollowingisthecodeusedtodefinetheforeignkeysusedbythetablesinthisbook:

InputClickheretoviewcodeimage

–––––––––––––––—Defineforeignkeys–––––––––––––––ALTERTABLEorderitemsADDCONSTRAINTfk_orderitems_ordersFOREIGNKEY(order_num)REFERENCESorders(order_num);ALTERTABLEorderitemsADDCONSTRAINTfk_orderitems_productsFOREIGNKEY(prod_id)REFERENCESproducts(prod_id);ALTERTABLEordersADDCONSTRAINTfk_orders_customersFOREIGNKEY(cust_id)REFERENCEScustomers(cust_id);ALTERTABLEproductsADDCONSTRAINTfk_products_vendorsFOREIGNKEY(vend_id)REFERENCESvendors(vend_id);ALTERTABLEproductnotesADDCONSTRAINTfk_productnotes_productsFOREIGNKEY(prod_id)REFERENCESproducts(prod_id);

Analysis

HerefiveALTERTABLEstatementsareused,becausefivedifferenttablesarebeingaltered.Aswedidwhentheprimarykeysweredefined,ADDCONSTRAINTisusedthistimespecifyingFOREIGNKEY,theconstraintisnamed,andtheimpactedtableisdefined.Becausethisisaforeignkey,wealsoneedtodefinethetableandcolumnthatitisdependenton,andthatgetspassedtoREFERENCES.REFERENCEScustomers(cust_id)meansthattheonlyvaluesinthiscolumnareonesinthecust_idcolumninthecustomerstable.

Tomakemultiplealterationstoasingletable,asingleALTERTABLEstatementcouldbeusedwitheachofthealterationsspecifiedanddelimitedbycommas.

Caution:Use Carefully

UseALTERTABLEwithextremecaution,andbesureyouhaveacompletesetofbackups(bothschemaanddata)beforeproceeding.Databasetablechangescannotbeundone—andifyouaddcolumnsyoudon’tneed,youmightnotbeabletoremovethem.Similarly,ifyoudropacolumnthatyoudoneed,youmightloseallthedatainthatcolumn.

DeletingTablesDeletingtables(actuallyremovingtheentiretable,notjustthecontents)isveryeasy—arguablytooeasy.TablesaredeletedusingtheDROPTABLEstatement:

Input

DROPTABLEcustomers2;

Analysis

Thisstatementdeletesthecustomers2table(assumingitexists).Thereisnoconfirmation,noristhereanundo—executingthestatementpermanentlyremovesthetable.

RenamingTablesTorenameatable,usetheALTERTABLEstatementasfollows:

InputClickheretoviewcodeimage

ALTERTABLEcustomers2RENAMETOcustomers;

Analysis

RENAMETABLEdoesjustthat—itrenamesatable.

SummaryInthislesson,youlearnedseveralnewSQLstatements.CREATETABLEisusedtocreatenewtables,ALTERTABLEisusedtochangetablecolumns(orotherobjectslikeconstraintsorindexes),andDROPTABLEisusedtocompletelydeleteatable.Thesestatementsshouldbeusedwithextremecaution,andonlyafterbackupshavebeenmade.Youalsolearnedaboutdatabaseengines,definingprimaryandforeignkeys,andotherimportanttableandcolumnoptions.

Lesson21.UsingViews

Inthislesson,you’lllearnexactlywhatviewsare,howtheywork,andwhentheyshouldbeused.You’llalsoseehowviewscanbeusedtosimplifysomeoftheSQLoperationsperformedinearlierlessons.

UnderstandingViewsViewsarevirtualtables.Unliketablesthatcontaindata,viewssimplycontainqueriesthatdynamicallyretrievedatawhenused.

Thebestwaytounderstandviewsistolookatanexample.BackinLesson15,“JoiningTables,”youusedthefollowingSELECTstatementtoretrievedatafromthreetables:

InputClickheretoviewcodeimage

SELECTcust_name,cust_contactFROMcustomers,orders,orderitemsWHEREcustomers.cust_id=orders.cust_idANDorderitems.order_num=orders.order_numANDprod_id=‘TNT2’;

Thatquerywasusedtoretrievethecustomerswhohadorderedaspecificproduct.Anyoneneedingthisdatawouldhavetounderstandthetablestructure,aswellashowtocreatethequeryandjointhetables.Toretrievethesamedataforanotherproduct(orformultipleproducts),thelastWHEREclausewouldhavetobemodified.

Nowimaginethatyoucouldwrapthatentirequeryinavirtualtablecalledproductcustomers.Youcouldthensimplydothefollowingtoretrievethesamedata:

InputClickheretoviewcodeimage

SELECTcust_name,cust_contactFROMproductcustomersWHEREprod_id=‘TNT2’;

Thisiswhereviewscomeintoplay.productcustomersisaview,andasaview,itdoesnotcontainanyactualcolumnsordataasatablewould.Instead,itcontainsaSQLquery—thesamequeryusedpreviouslytojointhetablesproperly.

WhyUseViewsYou’vealreadyseenoneuseforviews.Herearesomeothercommonuses:

ToreuseSQLstatements.

TosimplifycomplexSQLoperations.Afterthequeryiswritten,itcanbereusedeasily,withoutyourhavingtoknowthedetailsoftheunderlyingqueryitself.

Toexposepartsofatableinsteadofcompletetables.

Tosecuredata.Userscanbegivenaccesstospecificsubsetsoftablesinsteadoftoentiretables.

Tochangedataformattingandrepresentation.Viewscanreturndataformattedandpresenteddifferentlyfromtheirunderlyingtables.

Forthemostpart,afterviewsarecreated,theycanbeusedinthesamewayastables.YoucanperformSELECToperations,filterandsortdata,joinviewstootherviewsortables,andpossiblyevenaddandupdatedata.(Therearesomerestrictionsonthislastitem.Moreonthatinamoment.)

Theimportantthingtorememberisviewsarejustthat—viewsintodatastoredelsewhere.Viewscontainnodatathemselves,sothedatatheyreturnisretrievedfromothertables.Whendataisaddedorchangedinthosetables,theviewsreturnthatchangeddata.

Caution:PerformanceIssues

Becauseviewscontainnodata,anyretrievalneededtoexecuteaquerymustbeprocessedeverytimetheviewisused.Ifyoucreatecomplexviewswithmultiplejoinsandfilters,orifyounestviews,youmayfindthatperformanceisdramaticallydegraded.Besureyoutestexecutionbeforedeployingapplicationsthatuseviewsextensively.

ViewRulesandRestrictionsHerearesomeofthemostcommonrulesandrestrictionsgoverningviewcreationandusage:

Liketables,viewsmustbeuniquelynamed.(Theycannotbenamedwiththenameofanyothertableorview.)

Thereisnolimittothenumberofviewsthatcanbecreated.

Tocreateviews,youmusthavesecurityaccess.Thisisusuallygrantedbythedatabaseadministrator.

Viewscanbenested;thatis,aviewmaybebuiltusingaquerythatretrievesdatafromanotherview.

ORDERBYmaybeusedinaview,butitwillbeoverriddenifORDERBYisalsousedintheSELECTthatretrievesdatafromtheview.

Viewscannotbeindexed,norcantheyhavetriggersordefaultvaluesassociatedwiththem.

Viewscanbeusedinconjunctionwithtables;forexample,tocreateaSELECTstatementwhichjoinsatableandaview.

UsingViewsSonowthatyouknowwhatviewsare(andtherulesandrestrictionsthatgovernthem),let’slookatviewcreation:

ViewsarecreatedusingtheCREATEVIEWstatement.

Toremoveaview,theDROPstatementisused.ThesyntaxissimplyDROPVIEWviewname;.

Toupdateaview,youmayusetheDROPstatementandthentheCREATEstatementagain,orjustuseCREATEORREPLACEVIEW,whichcreatesitifitdoesnotexistandreplaceitifitdoes.

UsingViewstoSimplifyComplexJoinsOneofthemostcommonusesofviewsistohidecomplexSQL,andthisofteninvolvesjoins.Lookatthefollowingstatement:

InputClickheretoviewcodeimage

CREATEVIEWproductcustomersASSELECTcust_name,cust_contact,prod_idFROMcustomers,orders,orderitemsWHEREcustomers.cust_id=orders.cust_idANDorderitems.order_num=orders.order_num;

Note:NoOutput

CREATEVIEWstatementsgeneratenooutput,butifyouexecutetheprecedingstatementinOracleSQLDeveloper,youshouldseeaviewPRODUCTCUSTOMERScreatedmessage.

Analysis

Thisstatementcreatesaviewnamedproductcustomers,whichjoinsthreetablestoreturnalistofallcustomerswhohaveorderedanyproduct.IfyouweretoSELECT*FROMproductcustomers,youwouldlisteverycustomerwhoorderedanything.

ToretrievealistofcustomerswhoorderedproductTNT2,youcandothefollowing:

InputClickheretoviewcodeimage

SELECTcust_name,cust_contactFROMproductcustomersWHEREprod_id=‘TNT2’;

OutputClickheretoviewcodeimage

+–––––-+––––—+|cust_name|cust_contact|+–––––-+––––—+|CoyoteInc.|YLee||YosemitePlace|YSam|+–––––-+––––—+

Analysis

ThisstatementretrievesspecificdatafromtheviewbyissuingaWHEREclause.WhenOracleprocessestherequest,itaddsthespecifiedWHEREclausetoanyexistingWHEREclausesintheviewquerysothedataisfilteredcorrectly.

Asyoucansee,viewscanbeusedinSELECTstatementsjustlikeanyothertables.UsingthemcangreatlysimplifytheuseofcomplexSQLstatements.Usingviews,youcanwritetheunderlyingSQLonceandthenreuseitasneeded.

Tip:CreatingReusableViews

Itisagoodideatocreateviewsthatarenottiedtospecificdata.Forexample,theviewcreatedinthisexamplereturnscustomersforallproducts,notjustproductTNT2(forwhichtheviewwasfirstcreated).Expandingthescopeoftheviewenablesittobereused,makingitevenmoreuseful.Italsoeliminatestheneedforyoutocreateandmaintainmultiplesimilarviews.

UsingViewstoReformatRetrievedDataAsmentionedpreviously,anothercommonuseofviewsisforreformattingretrieveddata.ThefollowingSELECTstatement(fromLesson10,“CreatingCalculatedFields”)returnsvendornameandlocationinasinglecombinedcalculatedcolumn:

InputClickheretoviewcodeimage

SELECTRTrim(vend_name)||‘,(‘||RTrim(vend_country)||‘)’ASvend_titleFROMvendorsORDERBYvend_name;

Output+––––––––-+|vend_title|+––––––––-+|ACME(USA)||AnvilsRUs(USA)||FurballInc.(USA)||JetSet(England)||JouetsEtOurs(France)||LTSupplies(USA)|+––––––––-+

Nowsupposethatyouregularlyneededresultsinthisformat.Ratherthanperformtheconcatenationeachtimeitwasneeded,youcouldcreateaviewandusethatinstead.To

turnthisstatementintoaview,youcandothefollowing:

InputClickheretoviewcodeimage

CREATEVIEWvendorlocationsASSELECTRTrim(vend_name)||‘,(‘||RTrim(vend_country)||‘)’ASvend_titleFROMvendorsORDERBYvend_name;

Analysis

ThisstatementcreatesaviewusingtheexactsamequeryasthepreviousSELECTstatement.Toretrievethedatatocreateallmailinglabels,simplydothefollowing:

Input

SELECT*FROMvendorlocations;

Output+––––––––-+|vend_title|+––––––––-+|ACME(USA)||AnvilsRUs(USA)||FurballInc.(USA)||JetSet(England)||JouetsEtOurs(France)||LTSupplies(USA)|+––––––––-+

UsingViewstoFilterUnwantedDataViewsarealsousefulforapplyingcommonWHEREclauses.Forexample,youmightwanttodefineacustomeremaillistviewsoitfiltersoutcustomerswithoutemailaddresses.Todothis,youcanusethefollowingstatement:

InputClickheretoviewcodeimage

CREATEVIEWcustomeremaillistASSELECTcust_id,cust_name,cust_emailFROMcustomersWHEREcust_emailISNOTNULL;

Analysis

Obviously,whensendingemailtoamailinglist,youwanttoignoreuserswhohavenoemailaddress.TheWHEREclauseherefiltersoutthoserowsthathaveNULLvaluesinthecust_emailcolumnssotheywon’tberetrieved.

Viewcustomeremaillistcannowbeusedfordataretrievaljustlikeanytable.

Input

SELECT*FROMcustomeremaillist;

OutputClickheretoviewcodeimage

+–––+–––––-+–––––––+|cust_id|cust_name|cust_email|+–––+–––––-+–––––––+|10001|CoyoteInc.|ylee@coyote.com||10003|Wascals|rabbit@wascally.com||10004|YosemitePlace|sam@yosemite.com|+–––+–––––-+–––––––+

Note: Clausesand Clauses

IfaWHEREclauseisusedwhenretrievingdatafromtheview,thetwosetsofclauses(theoneintheviewandtheonepassedtoit)willbecombinedautomatically.

UsingViewswithCalculatedFieldsViewsareexceptionallyusefulforsimplifyingtheuseofcalculatedfields.ThefollowingisaSELECTstatementintroducedinLesson10.Itretrievestheorderitemsforaspecificorder,calculatingtheexpandedpriceforeachitem:

InputClickheretoviewcodeimage

SELECTprod_id,quantity,item_price,quantity*item_priceASexpanded_priceFROMorderitemsWHEREorder_num=20005;

OutputClickheretoviewcodeimage

+–––+–––-+––––+–––––-+|prod_id|quantity|item_price|expanded_price|+–––+–––-+––––+–––––-+|ANV01|10|5.99|59.90||ANV02|3|9.99|29.97||TNT2|5|10|50||FB|1|10|10|+–––+–––-+––––+–––––-+

Tocreateaviewthatcanreturnthesamedataforanyorder,dothefollowing:

InputClickheretoviewcodeimage

CREATEVIEWorderitemsexpandedASSELECTorder_num,prod_id,quantity,item_price,quantity*item_priceASexpanded_priceFROMorderitems;

Toretrievethedetailsfororder20005(thepreviousoutput),dothefollowing:

Input

SELECT*FROMorderitemsexpandedWHEREorder_num=20005;

OutputClickheretoviewcodeimage

+–––—+–––+–––-+––––+–––––-+|order_num|prod_id|quantity|item_price|expanded_price|+–––—+–––+–––-+––––+–––––-+|20005|ANV01|10|5.99|59.9||20005|ANV02|3|9.99|29.97||20005|TNT2|5|10|50||20005|FB|1|10|10|+–––—+–––+–––-+––––+–––––-+

Asyoucansee,viewsareeasytocreateandeveneasiertouse.Usedcorrectly,viewscangreatlysimplifycomplexdatamanipulation.

UpdatingViewsAlltheviewsthusfarhavebeenusedwithSELECTstatements.Butcanviewdatabeupdated?Theansweristhatitdepends.

Asarule,yes,viewsareupdateable(thatis,youcanuseINSERT,UPDATE,andDELETEonthem).Updatingaviewupdatestheunderlyingtable(theview,ifyourecall,hasnodataofitsown);ifyouaddorremoverowsfromaview,youareactuallyremovingthemfromtheunderlyingtable.

However,notallviewsareupdateable.Basically,ifOracleisunabletocorrectlyascertaintheunderlyingdatatobeupdated,updates(thisincludesinsertsanddeletes)arenotallowed.Inpractice,thismeansthatifanyofthefollowingareused,you’llnotbeabletoupdatetheview:

Grouping(usingGROUPBYandHAVING)

Joins

Subqueries

Unions

Aggregatefunctions(Min(),Count(),Sum(),andsoforth)

DISTINCT

Derived(calculated)columns

Inotherwords,manyoftheexamplesusedinthislessonwouldnotbeupdateable.Thismightsoundslikeaseriousrestriction,butinrealityitisn’tbecauseviewsareprimarilyusedfordataretrievalanyway.

Tip:UseViewsforRetrieval

Asarule,useviewsfordataretrieval(SELECTstatements)andnotforupdates(INSERT,UPDATE,andDELETE).

SummaryViewsarevirtualtables.Theydonotcontaindata,buttheycontainqueriesthatretrievedataasneeded,instead.ViewsprovidealevelofencapsulationaroundOracleSELECTstatementsandcanbeusedtosimplifydatamanipulation,aswellastoreformatorsecureunderlyingdata.

Lesson22.WorkingwithStoredProcedures

Inthislesson,you’lllearnwhatstoredproceduresare,whytheyareused,andhowtheyareused.You’llalsolookatthebasicsyntaxforcreatingandusingthem.

UnderstandingStoredProceduresMostoftheSQLstatementsthatwe’veusedthusfararesimpleinthattheyuseasinglestatementagainstoneormoretables.Notalloperationsarethatsimple—often,multiplestatementsareneededtoperformacompleteoperation.Forexample,considerthefollowingscenario:

Toprocessanorder,checksmustbemadetoensurethatitemsareinstock.

Ifitemsareinstock,theyneedtobereservedsotheyarenotsoldtoanyoneelse,andtheavailablequantitymustbereducedtoreflectthecorrectamountinstock.

Anyitemsnotinstockneedtobeordered;thisrequiressomeinteractionwiththevendor.

Thecustomerneedstobenotifiedastowhichitemsareinstock(andcanbeshippedimmediately)andwhicharebackordered.

Thisisobviouslynotacompleteexample,anditisevenbeyondthescopeoftheexampletablesthatwehavebeenusinginthisbook,butitsufficestohelpmakeapoint.PerformingthisprocessrequiresmanyPL/SQLstatementsagainstmanytables.Inaddition,theexactstatementsthatneedtobeperformedandtheirorderarenotfixed;theycan(andwill)varyaccordingtowhichitemsareinstockandwhicharenot.

Howwouldyouwritethiscode?Youcouldwriteeachofthestatementsindividuallyandexecuteotherstatementsconditionally,basedontheresult.Youwouldhavetodothiseverytimethisprocessingwasneeded(andineveryapplicationthatneededit).

Youcouldalsocreateastoredprocedure.StoredproceduresaresimplycollectionsofoneormoreOraclePL/SQLstatementssavedforfutureuse.Youcanthinkofthemasbatchfiles,althoughintruththeyaremorethanthat.

ThelanguageusedtowritestoredproceduresinOracleisPL/SQL,andthePLisimportant,becauseit’stheprocedurallanguagethatprovideseverythingfromifstatementstoloopsandmore.

Note:JustanIntroduction

Oraclestoredproceduresarepowerfulandcapable,andthere’salottolearnandmaster.Thereareentirebooks,booksfarbiggerthanthisone,justonthesubject.Thislessonisnotgoingtoteachyouallyouneedtoknowaboutfunctionsandstoredprocedures.Rather,Iwanttousethislessontohelpyouunderstandwhattheyare,whattheylooklike,andwhattheycando.Then,whenyourunintoanopportunitythatcallsforone,you’llknowwhichdirectiontoheadin.

WhyUseStoredProceduresNowthatyouknowwhatstoredproceduresare,whyusethem?Therearemanyreasons,butherearetheprimaryones:

Tosimplifycomplexoperations(asshowninthepreviousexample)byencapsulatingprocessesintoasingleeasy-to-useunit.

Toensuredataintegritybynotrequiringthataseriesofstepsbecreatedoverandover.Ifalldevelopersandapplicationsusethesame(tried-and-tested)storedprocedure,thesamecodewillbeusedbyall.

Anextensionofthisconceptistopreventerrors.Themorestepsthatmustbeperformed,themorelikelyitisthaterrorswillbeintroduced.Preventingerrorsensuresdataconsistency.

Tosimplifychangemanagement.Iftables,columnnames,orbusinesslogic(orjustaboutanything)changes,onlythestoredprocedurecodeneedstobeupdated,andnooneelseneedseventobeawarethatchangesweremade.

Anextensionofthisconceptissecurity.Restrictingaccesstounderlyingdataviastoredproceduresreducesthechanceofdatacorruption(unintentionalorotherwise).

Toimproveperformance,becausestoredprocedurestypicallyexecutequickerthanindividualSQLstatementsdo.

Inotherwords,therearethreeprimarybenefits—simplicity,security,andperformance.Obviouslyallareextremelyimportant.BeforeyourunofftoturnallyourSQLcodeintostoredprocedures,herearethedownsides:

StoredprocedurestendtobemorecomplextowritethanbasicSQLstatements,andwritingthemrequiresagreaterdegreeofskillandexperience.

Youmightnothavethesecurityaccessneededtocreatestoredprocedures.Manydatabaseadministratorsrestrictstoredprocedurecreationrights,allowinguserstoexecutethembutnotnecessarilycreatethem.

Nonetheless,storedproceduresareveryusefulandshouldbeusedwheneverpossible.

UsingStoredProceduresWe’regoingtolookatseveralstoredprocedures,increasinginsophisticationandcomplexityaswego.

Note:WhatAboutFunctions?

Inadditiontostoredprocedures,Oraclealsosupportsfunctions.Functionsandstoredproceduresareverysimilar;theyallowyoutoencapsulateblocksoffunctionality.Themaindifferencebetweenfunctionsandstoredproceduresisinwhattheyreturn:Functionsalwaysreturnasinglevalue(muchliketheSQLfunctionswe’vebeenusingthroughoutthisbook).Storedproceduresdon’treturnvalues,buttheydoacceptparametersthatcanbeusedtopassdatabothinandout.Withinthebodyoffunctionsandstoredprocedures,thecodeyoucanwriteandtheoperationsyoucanperformaremuchthesame.Thedifferenceisinhowthecodewillbeusedandexecuted.Assuch,whatyou’lllearnherealsoappliestofunctions,eventhoughwedon’tfocusonthemexplicitly.

BasicStoredProcedureSyntaxWe’llstartwithasimpleexample—theOraclestoredprocedureequivalentofHelloWorld.Here’sthecode:

InputClickheretoviewcodeimage

CREATEORREPLACEPROCEDUREHelloISBEGINDBMS_OUTPUT.PUT_LINE(‘HelloWorld’);END;

Analysis

StoredproceduresarecreatedusingtheCREATEPROCEDUREstatement,andheretheprocedureisnamedHello.ThebodyofastoredprocedureisplacedbetweenBEGINandENDstatements,andthebodyofthisstoredproceduresimplydisplaysHelloWorldintheoutputwindow.

Tip:Use

Toupdateastoredprocedure,youmustdeleteitandthencreateitagain.Or,insteadofusingCREATEPROCEDURE,useCREATEORREPLACEPROCEDUREaswedidhere.Thiswayifthestoredproceduredoesn’texistit’llbecreated,butifitdoesexistit’llbeupdated.

Sohowdoyouexecutethisstoredprocedure?YouusetheEXECUTEstatement,likethis:

Input

EXECUTEHello

OutputHelloWorld

Analysis

EXECUTEdoesjustthat—itexecutesastoredprocedure,whichinthiscasesimplydisplaysHelloWorld.Okay,sothat’sabitanti-climactic,butit’llgetbetterinamoment.

UsingProgrammingConstructsinStoredProceduresThingsbecomealittlemoreinterestingwhenstoredproceduresemployprogrammingconstructs.Here’sanexample:

InputClickheretoviewcodeimage

CREATEORREPLACEPROCEDUREGreetingIS

hnumber;gchar(20);

BEGIN

SELECTEXTRACT(HOURFROMCURRENT_TIMESTAMP)INTOhFROMdual;

IFh>=20ORh<=5THENg:=‘Goodnight!’;ELSIFh>5ANDh<=12THENg:=‘Goodmorning!’;ELSIFh>12ANDh<=17THENg:=‘Goodafternoon!’;ELSEg:=‘Goodevening!’;ENDIF;

DBMS_OUTPUT.PUT_LINE(g);END;

Analysis

ThisstoredproceduredisplaysGoodmorning!,Goodafternoon!,Goodevening!,orGoodnight!dependingonthetimeofday.Asinthepreviousexample,CREATEORREPLACEPROCEDUREisusedtocreateaprocedure,thistimenamedGreeting.Next,twovariablesarecreated,h(anumber)toholdthecurrenthour,andg(text)toholdthegreetingtext.BEGINstartsthebody,aSELECTstatementobtainsthecurrentsystemhour,andINTOhtellstheSELECTtosavetheresultinvariableh.NextcomesanIFblockthatsimplylooksatthehourandsavesanappropriategreetingintovariableg.Finally,gisdisplayed(justlikewedisplayedHelloWorldpreviously).

Torunthisstoredprocedure,justdothefollowing:

Input

EXECUTEGreeting

BuildingIntelligentStoredProceduresNowthatyou’veseensomeofwhatstoredprocedurescando,let’slookatamoreusefulexample,onethatsolvesanactualbusinessproblem.BackinLesson18,“InsertingData,”youlearnedhowtoaddrowstoatable.Forourexample,weaddedacustomer,andyouhadtomakesurethatthecustomerwasassignedanewanduniqueid;otherwise,akeyconstrainterrorwouldbethrown.Therefore,youhadtopickanewnumberyourself,makingsurethatitwasnotalreadyinuse.Obviously,intherealworld,youwouldnotwanttoaskuserstodothis.Customeridassignmentshouldhappensafely,reliably,andautomatically.

Thisnextstoredproceduredemonstratesonewaytoaccomplishthis.RatherthanuseINSERTtoaddacustomer,youcancreateastoredprocedurethatdoestheinsertionforyou.Yousimplypassitthecustomerinfo,anditfindsthenextavailableidtouseandtheninsertsthenewcustomer.

Here’sthecode:

InputClickheretoviewcodeimage

—AddanewcustomerCREATEORREPLACEPROCEDURECustomerAdd(v_cust_nameINcustomers.cust_name%TYPE,v_cust_addressINcustomers.cust_address%TYPE,v_cust_cityINcustomers.cust_city%TYPE,v_cust_stateINcustomers.cust_state%TYPE,v_cust_zipINcustomers.cust_zip%TYPE,v_cust_countryINcustomers.cust_country%TYPE,v_cust_contactINcustomers.cust_contact%TYPE,v_cust_emailINcustomers.cust_email%TYPE)IS

—Variableforcustomeridv_cust_idnumber;

BEGIN

—GetcurrenthighestcustomeridSELECTMAX(cust_id)INTOv_cust_idFROMcustomers;

—Incrementcustomeridv_cust_id:=v_cust_id+1;

—InsertnewcustomerINSERTINTOcustomers(cust_id,cust_name,cust_address,cust_city,cust_state,cust_zip,cust_country,cust_contact,cust_email)VALUES(v_cust_id,v_cust_name,

v_cust_address,v_cust_city,v_cust_state,v_cust_zip,v_cust_country,v_cust_contact,v_cust_email);

COMMIT;

END;

Analysis

Thisexampleismorecomplicated,soI’veaddedcomments(somethingyoushouldalwaysdoinallofyourstoredprocedures).Onceagain,CREATEORREPLACEPROCEDUREisusedtocreateastoredprocedurenamedCustomerAdd.Thisstoredprocedureneedstoacceptcustomerdata,andeachpieceofdataisspecifiedasaparametertothestoredprocedure.

Becauseeightpiecesofdatamustbepassedin,thereareeightparametersdefined,thefirstofwhichisv_cust_nameINcustomers.cust_name%TYPE.Thefirstpartoftheparameterdefinitioncreatesavariablenamedv_cust_name(Iliketonamemyvariablesv_followedbytheassociatedtablecolumn).INspecifiesthatthisparameterisbeingusedtopassdataintothestoredprocedure(asopposedtoOUTofit).customers.cust_name%TYPEspecifiesthatthisparameterisassociatedwiththecust_namecolumninthecustomerstable.Thissamepatternisrepeatedforalleightparameters.

Next,thecodecreatesavariabletostorethecustomeridwe’llbeusing.

BEGINstartsthestoredprocedurebody,andthefirstthingweneedtodoistodeterminethecurrenthighestcustomerid.AsyoumightrecallfromLesson12,“SummarizingData,”MAX()canfindthegreatestvalueinacolumn,andsoweSELECTMAX(cust_id)fromthecustomerstable,andsaveitINTOv_cust_id.Nowvariablev_cust_idcontainsthecurrenthighestcustomerid,butweneedavaluegreaterthanthat,andsov_cust_id:=v_cust_id+1;incrementsv_cust_idby1.

NextcomestheINSERTstatement,whichisjustliketheoneyousawinLesson18,exceptthatthistimetheVALUESareallvariables,alocalvariableforcust_id,andthepassedparametersforalltheothers.

Finally,COMMITisusedtosavethechanges,andthestoredprocedureisclosedwithEND;.

Totrythisexample,usethefollowingEXECUTEstatement:

InputClickheretoviewcodeimage

EXECUTECustomerAdd(‘PepE.LaPew’,

‘100MainStreet’,‘LosAngeles’,‘CA’,‘90046’,‘USA’,NULL,NULL)

Analysis

Bynow,thecodeshouldbeself-explanatory.EXECUTErunsthestoredprocedure,andallnecessaryvaluesarepassedasparameters.Thestoredprocedurethendefinesanewcustomerid,andINSERTsthenewcustomer.

DroppingStoredProceduresAftertheyarecreated,storedproceduresremainontheserver,readyforuse,untildropped.TheDROPcommand(similartothestatementshowninLesson20,“CreatingandManipulatingTables”)removesthestoredprocedurefromtheserver.

Toremovethestoredprocedurewejustcreated,usethefollowingstatement:

Input

DROPPROCEDUREGreeting;

Analysis

Thisremovestherecentlycreatedstoredprocedure.

SummaryInthislesson,youlearnedwhatstoredproceduresareandwhytheyareused.Youalsolearnedthebasicsofstoredprocedureexecutionandcreationsyntax,andyousawsomeofthewaysthesecanbeused.We’llcontinuethissubjectinthenextlesson.

Lesson23.UsingCursors

Inthislesson,you’lllearnwhatcursorsareandhowtousethem.

UnderstandingCursorsAsyouhaveseeninpreviouslessons,Oracleretrievaloperationsworkwithsetsofrowsknownasresultsets.TherowsreturnedarealltherowsthatmatchaSQLstatement—zeroormoreofthem.UsingsimpleSELECTstatements,thereisnowaytogetthefirstrow,thenextrow,ortheprevious10rows,forexample.Noristhereaneasywaytoprocessallrows,oneatatime(asopposedtoalloftheminabatch).

Sometimesyouneedtostepthroughrowsforwardorbackwardandoneormoreatatime.Thisiswhatcursorsareusedfor.AcursorisadatabasequerystoredontheOracleserver—notaSELECTstatement,buttheresultsetretrievedbythatstatement.Afterthecursorisstored,applicationscanscrollorbrowseupanddownthroughthedataasneeded.

Tohelpdemonstratethis,considerthefollowingscenario.Ourvendorstablecontainsvendornamesandaddresses.Intherealworld,addressdatacanbecomeinconsistentveryquickly;someusersmightcapitalizestreetsandothersmightnot,somemightenterRdandothersRd.andyetotherRoad;stateandprovincenamesmightbecapitalizedornot(orworse,mightbemixedcase);UKandCanadianstylepostalcodesmighthavespacesinthemornot;andsoon.CleaningupthedatatoensureuniformityandconsistencyistoocomplexataskforaSQLUPDATEstatement;convertingacolumntouppercaseforall(orsome)rowsiseasyenough,butapplyingdifferentrulesbasedoncountry,forexample,requiresthateachrowbeprocessedindividually.Thisisagreattaskforcursors.

Note:ExplicitandImplicitCursors

InOracle,everytimeyouexecuteaSQLstatement,acursoriscreatedinternally;that’showOracleitselfprocesstheSQLstatement.Thistypeofcursoriscalledanimplicitcursor,asopposedtotheexplicitcursor,which,asitsnamesuggests,isoneyouexplicitlycreate.Whenyouworkwithcursors,youwillalmostexclusivelybeusingexplicitcursors,andsoalltheexamplesinthislessonareexactlythat.However,althoughtheyarenotcoveredinthislesson,ifneeded,youcanworkwiththeimplicitcursorsthatOraclecreates,andthetechniquesdiscussedhereapplyequallytoallcursors.

WorkingwithCursorsUsingcursorsinvolvesseveraldistinctsteps:

1.Beforeacursorcanbeused,itmustbedeclared(defined).Thisprocessdoesnotactuallyretrieveanydata;itmerelydefinestheSELECTstatementtobeused.

2.Afteritisdeclared,thecursormustbeopenedforuse.ThisprocessactuallyretrievesthedatausingthepreviouslydefinedSELECTstatement.

3.Withthecursorpopulatedwithdata,individualrowscanbefetched(retrieved)asneeded.

4.Whenitisdone,thecursormustbeclosed.

CreatingCursorsCursorsarecreatedusingtheDECLARECURSORstatement.CURSORnamesthecursorandtakesaSELECTstatement,completewithWHEREandotherclausesifneeded.Forexample,thisstatementdefinesacursornamedordernumbersusingaSELECTstatementthatretrievesallorders:

InputClickheretoviewcodeimage

DECLARECURSORc_vendorsISSELECTvend_id,vend_name,vend_address,vend_city,vend_state,vend_zip,vend_countryFROMvendors;

Analysis

Don’trunthiscodeyet;it’snotcompleteenoughforOracleandwillgenerateerrors,butlet’slookatit.DECLARECURSORdoesjustwhatitsnameimplies—itcreatesanewcursor,herenamedc_vendors.TheonlycodeinthecursorisaSELECTstatement,whichdefinesthedatathatwillbeusedwithinthecursor.

Nowthatthecursorisdefined,itisreadytobeopened.

OpeningandClosingCursorsCursorsareopenedusingtheOPENstatement,likethis:

Input

OPENc_vendors;

Aftercursorprocessingiscomplete,thecursorshouldbeclosedusingtheCLOSEstatement,asfollows:

Input

CLOSEc_vendors;

Hereisamorecompleteexample,andthisonerunswithoutanyerrors:

InputClickheretoviewcodeimage

DECLARECURSORc_vendorsIS

SELECTvend_id,vend_name,vend_address,vend_city,vend_state,vend_zip,vend_countryFROMvendors;

BEGIN

OPENc_vendors;CLOSEc_vendors;

END;

Analysis

Here,thecursorisdefined,itisthenopened,andrightawayclosed,butnothingisdonewiththeretrieveddata.

FetchingCursorDataAfteracursorisopened,eachrowcanbeaccessedindividuallyusingaFETCHstatement.FETCHspecifieswhatistoberetrieved(thedesiredcolumns)andwhereretrieveddatashouldbestored.ItalsoadvancestheinternalrowpointerwithinthecursorsothenextFETCHstatementretrievesthenextrow(andnotthesameoneoverandover).

Here’sanupdatetoourpriorcursor:

InputClickheretoviewcodeimage

DECLARE—Declarevariablesv_vend_idvendors.vend_id%TYPE;v_vend_namevendors.vend_name%TYPE;v_vend_addressvendors.vend_address%TYPE;v_vend_cityvendors.vend_city%TYPE;v_vend_statevendors.vend_state%TYPE;v_vend_zipvendors.vend_zip%TYPE;v_vend_countryvendors.vend_country%TYPE;

—DeclarecursorCURSORc_vendorsISSELECTvend_id,vend_name,vend_address,vend_city,vend_state,vend_zip,vend_countryFROMvendors;

BEGIN

—OpencursorOPENc_vendors;

—LoopthroughcursorLOOP

—GetarowFETCHc_vendorsINTOv_vend_id,v_vend_name,v_vend_address,v_vend_city,v_vend_state,

v_vend_zip,v_vend_country;

—Whennomorerows,exitEXITWHENc_vendors%notfound;

ENDLOOP;

—ClosecursorCLOSEc_vendors;

END;

Tip:It’sPL/SQL

Ifthebasiccodeandstructureofthiscursorlooksfamiliar,that’sbecauseit’swritteninPL/SQL,thesamelanguageusedinLesson22,“WorkingwithStoredProcedures,”whenwelookedatstoredprocedures.ThemoreyoulearnaboutthePL(procedurallanguage)partofPL/SQL,themoreyoucantakeadvantageofOracle’smoreadvancedfunctionality.

Analysis

Thecursorhasgottenfarmorecomplex,solet’swalkthroughit.(NoticethatIhavecommentedthecode,somethingthatIrecommendyoualwaysdo.)

Onceagain,westartwithaDECLAREstatement,butthistimeitisdoingmorethandeclarethecursor;it’salsodeclaringaseriesofvariablesthatareneededtocontainretrieveddata(moreonthatinamoment).Thevariablesaredefinedinmuchthesamewayaswedefinedstoredprocedureparameters—theyarenamed,andthenassociatedwithspecifictablecolumns.

Nextcomesthecursordefinitionitself,justaswesawin“CreatingCursors”previously,andthecursoristhenopened.

NewtothisexampleistheLOOPinstruction,whichdefinesablockofcodethatgetsrepeated.EverythingbetweenLOOPandENDLOOPgetsrepeatedoverandover,untilsomethingwithintheloopforcesanexit.

FETCHisthenusedtofetchonerowfromthecursorINTOspecifiedvariables.You’llnoticethatcolumnnamesarenotspecified,andsocursorcolumnorderisimportant.Thefirstcolumndefinedinthecursor’sSELECTstatementwillbestoredinthefirstvariable,thesecondinthesecond,andsoon.ThisiswhyIliketonamemyvariablesv_(forvariable)followedbythenameofthecolumnwithwhichthey’llbeused;itmakesworkingwiththemawholeloteasier.

FETCHfetchesonerowatatime,andsoeachtimethroughtheloop,adifferentrowisfetched,andthevariablesareupdatedwithnewvalues.Sohowdoestheloopeverterminate?That’swhatEXITdoes—itexitstheloop,terminatingloopprocessing.YoucanuseEXITanytime;youcouldhaveputitatthetopoftheloopandtheloopwouldthenimmediatelyterminate.HereweuseEXITWHENc_vendors%notfound,whichtellsOracletoEXITWHENthec_vendorscursorreturnsanotfoundstate

indicatingthatnomorerowsarelefttoFETCH.

Ourcursorisn’tactuallydoinganythingwiththefetcheddata,butitisloopingthroughretrievedrowsandstoringcolumnsintovariables.

UsingCursorDataNowthatwecanFETCHonerowatatime,wecanworkwiththatdata.Lookatthisnextexample:

InputClickheretoviewcodeimage

DECLARE—Declarevariablesv_vend_idvendors.vend_id%TYPE;v_vend_namevendors.vend_name%TYPE;v_vend_addressvendors.vend_address%TYPE;v_vend_cityvendors.vend_city%TYPE;v_vend_statevendors.vend_state%TYPE;v_vend_zipvendors.vend_zip%TYPE;v_vend_countryvendors.vend_country%TYPE;

—DeclarecursorCURSORc_vendorsISSELECTvend_id,vend_name,vend_address,vend_city,vend_state,vend_zip,vend_countryFROMvendors;

BEGIN

—OpencursorOPENc_vendors;

—LoopthroughcursorLOOP

—GetarowFETCHc_vendorsINTOv_vend_id,v_vend_name,v_vend_address,v_vend_city,v_vend_state,v_vend_zip,v_vend_country;

—IsthisaddressinUSA?IFTrim(v_vend_country)=‘USA’THEN—Makesurestateabbreviationisuppercasev_vend_state:=Upper(v_vend_state);—UpdatethevendorUPDATEvendorsSETvend_state=v_vend_stateWHEREvend_id=v_vend_id;ENDIF;

—Whennomorerows,exitEXITWHENc_vendors%notfound;

ENDLOOP;

—ClosecursorCLOSEc_vendors;

END;

Analysis

Thisexampleisexactlythesameasthepriorexample,untilyougettothecodewithintheLOOP.PreviouslyweusedFETCHtoretrievedataandthendidnothingwithit.Herewe’veaddedsomeprocessing.

TheIFstatementscheckstoseewhethertherowthathasbeenfetchedisintheUSA.Ifyes,itusestheUpper()functiontoconvertthestate(storedinvariablev_vend_state)touppercase.

Next,anUPDATEstatementisusedtoupdatethevendorstablewiththecorrectedstate,usingvariablesbothastheSETvalueandintheWHEREclause.

Andthenit’sontothenextrow.

Tokeepthingssimple,thisexamplefixesonethingonly—itmakessurethatUSAstateabbreviationsareinuppercase.Intherealworld,additionalprocessingwouldbeneeded,andallsortsofrulescouldbeprovided,includingadditionalIFblocksforothercountries.Inaddition,thiscodeisratherinefficientinthatitupdatesthevendorunconditionally;ifthestatewasalreadyuppercase,thenthisUPDATEwouldn’tbeneeded,andsoabetterimplementationwouldonlyissueUPDATEstatementsiftherewereactuallysomethingtoupdate.Butyougettheidea,andwiththisbasicstructureinplace,it’seasytoaddextraprogramminglogicandintelligencetothecode.

Note: or ?

InadditiontotheLOOPstatementusedhere,OraclealsosupportsaREPEATUNTILstatementthatcanbeusedtorepeatcode(includingcursors)untilaconditionismet.Ingeneral,you’llfindthesyntaxoftheLOOPstatementmakesitbettersuitedforloopingthroughcursors.

Thereyouhaveit—acompleteworkingexampleofcursorsandrow-by-rowprocessing.

SummaryInthislesson,youlearnedwhatcursorsareandwhytheyareused.Youalsosawexamplesdemonstratingbasiccursoruse,aswellastechniquesforloopingthroughcursorresultsandforrow-by-rowprocessing.

Lesson24.UsingTriggers

Inthislesson,you’lllearnwhattriggersare,whytheyareused,andhow.You’llalsolookatthesyntaxforcreatingandusingthem.

UnderstandingTriggersOraclestatementsareexecutedwhenneeded,asarestoredprocedures.Butwhatifyouwantedastatement(orstatements)tobeexecutedautomaticallywheneventsoccur?Forexample:

Everytimeacustomerisaddedtoadatabasetable,checkthatthephonenumberisformattedcorrectlyandthatthestateabbreviationisinuppercase.

Everytimeaproductisordered,subtracttheorderedquantityfromthenumberinstock.

Wheneverarowisdeleted,saveacopyinanarchivetable.

Whatalltheseexampleshaveincommonisthattheyneedtobeprocessedautomaticallywheneveraneventoccurs.Thatisexactlywhattriggersare.AtriggerisanOraclestatement(oragroupofstatementsenclosedwithinBEGINandENDstatements)thatareautomaticallyexecutedbyOracleinresponsetoanyofthesestatements:

ALTER

CREATE

DROP

DELETE

INSERT

UPDATE

Thelastthreeareofthegreatestinterest—triggersthatareexecutedinresponsetotablerowchanges.

Note:TriggersonDatabaseOperations

Oraclealsosupportstriggersonserverstartupandshutdown,userloginandlogoff,andmore.Thesearebeyondthescopeofthisbook,andareprimarilyofinteresttodatabaseadministrators.

CreatingTriggersWhencreatingatrigger,youneedtospecifyfourpiecesofinformation:

Theuniquetriggername

Thetabletowhichthetriggeristobeassociated

Theactionthatthetriggershouldrespondto(DELETE,INSERT,orUPDATE)

Whenthetriggershouldbeexecuted(BEFOREorAFTERprocessing)

TriggersarecreatedusingtheCREATETRIGGERstatement.Hereisasimpleexample(whichdoesn’tactuallydoanythinguseful,butdoeshelpexplainthesyntaxneeded):

InputClickheretoviewcodeimage

CREATEORREPLACETRIGGERorders_after_insertAFTERINSERTONordersFOREACHROW

BEGIN

END;

Analysis

Thisexamplewon’trun;Oracledoesn’tlikecodethatdoesnothing,andifyoutrytoexecuteit,anerrorisreturned.Thatsaid,let’slookatthecode.

CREATEORREPLACETRIGGERisusedtocreatethenewtriggernamedorders_after_insert.Triggerscanexecutebeforeorafteranoperationoccurs,andhereAFTERINSERTONisspecifiedsothetriggerwillexecuteafterasuccessfulINSERTstatementhasbeenexecuted.INSERTcaninsertmultiplerows,andthetriggerthenspecifiesFOREACHROWandthecodetobeexecutedforeachinsertedrow.So,wheneveraproductisaddedtothecustomerstable,thistriggerruns,andanycodebetweenBEGINandENDexecutes.

Note:WhenTriggersFail

IfaBEFOREtriggerfails,Oracledoesnotperformtherequestedoperation.Inaddition,ifeitheraBEFOREtriggerortheSQLstatementitselffails,OracledoesnotexecuteanAFTERtrigger(ifoneexists).

DroppingTriggersBynow,thesyntaxfordroppingatriggershouldbeself-apparent.Todropatrigger,usetheDROPTRIGGERstatement,asshownhere:

InputClickheretoviewcodeimage

DROPTRIGGERorders_after_insert;

Analysis

Toupdateatrigger,eitherDROPandthenCREATEagain,oruseCREATEORREPLACEasshownpreviously.

UsingTriggersWiththebasicscovered,nowlookateachofthesupportedtriggertypes,andthedifferencesbetweenthem.

TriggersINSERTtriggersexecuteBEFOREorAFTERanINSERTstatementexecutes.Beawareofthefollowing:

WithinINSERTtriggercode,youcanrefertoavirtualtablenamed:NEWtoaccesstherowsbeinginserted.

InaBEFOREINSERTtrigger,thevaluesin:NEWmayalsobeupdated(allowingyoutochangevaluesabouttobeinserted).

Acommonusefortriggersistotracktablechanges(audittrailsorlogs).Totryanexample,you’llfirstneedatabletostorethisinformation.ThisnextOracleSQLstatementcreatesatabletostorealogofallchangestotheorderstable:

InputClickheretoviewcodeimage

CREATETABLEorders_log(changed_onTIMESTAMPNOTNULL,change_typeCHAR(1)NOTNULL,order_numINTNOTNULL);

Analysis

Thistablehascolumnstostorethechangedateandtime,thetypeofchange(Aforadded,Uforupdated,Dfordeleted),andtheorder_numoftheorderchanged.

Nowthatyouhaveatabletostorethechangelog,youneedtocreatethetriggerthatwillupdatethisnewtable.Hereisthecode:

InputClickheretoviewcodeimage

CREATEORREPLACETRIGGERorders_after_insertAFTERINSERTONordersFOREACHROW

BEGIN

INSERTINTOorders_log(changed_on,change_type,order_num)VALUES(SYSDATE,‘A’,:NEW.order_num);

END;

Analysis

CREATEORREPLACETRIGGERisusedtocreatethenewtriggernamedorders_after_insert.Triggerscanbeexecutedbeforeorafteranoperationoccurs,andhereAFTERINSERTONisspecifiedsothetriggerwillexecuteafterasuccessfulINSERTstatementhasbeenexecuted.ThetriggerthenspecifiesFOREACHROWsothatthetriggercodewillbeexecutedforeachrowifINSERTinsertsmultiplerows.Whenaneworderissavedinorders,Oracleexecutesthetrigger,andinsertsanewrowintoorders_log.ThedateandtimeissavedusingSYSTIME,theactionissettoA(foradd),andthenewnumberisobtainedfrom:NEW.order_num.

Themostimportantthingtonoteaboutthisexampleistheuseofthe:NEWtable.:NEWisnotanactualtable,butitcanbeusedasonewithintriggerstoaccessthenewdata.You’llsee:OLDusedthesamewayshortly.

Totestthistrigger,tryinsertinganeworder,likethis(feelfreetochangethevalues;justbesuretouseavalidcust_id):

InputClickheretoviewcodeimage

INSERTINTOorders(order_num,order_date,cust_id)VALUES(20010,SYSDATE,10001);

TheINSERTstatementitselfdoesnotreturnanythinguseful,butitdidcauseourtriggertobeexecuted.Toverifythis,let’sseewhatisintheorders_logtable:

Input

SELECT*FROMorders_log;

OutputClickheretoviewcodeimage

+–––––––+––––-+–––—+|changed_on|change_type|order_num|+–––––––+––––-+–––—+|19-FEB-1504.27.18|A|20010|+–––––––+––––-+–––—+

Analysis

orders_logscontainsthreecolumns.changed_oncontainsthedateandtimethatthechangeoccurred(returnedbySYSDATEinthetrigger),change_typeisA(orderadded),andorder_numcontainsthenewordernumber.

Tip: or ?

ThisexampleusedAFTERtoexecutethetriggeraftertheneworderwascreated.Asarule,useAFTERifyouneedtoaccessdatathatwon’texistuntilastatementhasbeenprocessed.UseBEFOREforanydatavalidationandcleanup(forexample,ifyouwanttomakesurethatthedatainsertedintothetablewasexactlyasneeded).

TriggersDELETEtriggersareexecutedbeforeorafteraDELETEstatementisexecuted.Beawareofthefollowing:

WithinDELETEtriggercode,youcanrefertoavirtualtablenamed:OLDtoaccesstherowsbeingdeleted.

Thevaluesin:OLDareallread-onlyandcannotbeupdated.

Thefollowingexampledemonstratestheuseof:OLDtosaverowsabouttobedeletedintothelogtable:

InputClickheretoviewcodeimage

CREATEORREPLACETRIGGERorders_before_deleteBEFOREDELETEONordersFOREACHROW

BEGIN

INSERTINTOorders_log(changed_on,change_type,order_num)VALUES(SYSDATE,‘D’,:OLD.order_num);

END;

Analysis

Thistriggerissimilartotheorders_after_inserttrigger,butthisonelogsorderdeletions.ThistriggerisexecutedBEFOREDELETE(oryouwouldnothaveaccesstotheorder_num).

Ifyouweretodeletetheorderyoujustinserted,youwouldseeasecondrowintheorders_logtablereflectingthedeletion.

AnothergooduseforDELETEtriggersistoarchivedeletions(rowsdeletedfromatablewillautomaticallybesavedintheirentiretytoanarchivetable).Thisupdatedversionoftheorders_before_deletetriggerlogsthedeletionandalsosavesthedeleteddatatoatablenamedorders_archive(you’llobviouslyneedtocreatethattableforthistriggertowork;orders_archivewillusethesameCREATETABLEstatementastheoneusedtocreateorders):

Input

Clickheretoviewcodeimage

CREATEORREPLACETRIGGERorders_before_deleteBEFOREDELETEONordersFOREACHROW

BEGIN

—LogdeletionINSERTINTOorders_log(changed_on,change_type,order_num)VALUES(SYSDATE,‘D’,:OLD.order_num);—ArchiveitINSERTINTOorders_archive(order_num,order_date,cust_id)VALUES(:OLD.order_num,:OLD.order_date,:OLD.cust_id);END;

Analysis

Beforeanyorderisdeleted,thistriggerwillbeexecuted.Inadditiontotheloggingshownpreviously,thistriggerusesanINSERTstatementtosavethevaluesin:OLD(theorderabouttobedeleted)intoanarchivetablenamedarchive_orders.

Tip:AnExtraLevelofProtection

TheadvantageofusingaBEFOREDELETEtrigger(asopposedtoanAFTERDELETEtrigger)isthatifforsomereasontheordercouldnotbearchived,theDELETEitselfwillbeaborted.

TriggersUPDATEtriggersareexecutedbeforeorafteranUPDATEstatementisexecuted.Beawareofthefollowing:

InUPDATEtriggercode,youcanrefertoavirtualtablenamed:OLDtoaccesstheprevious(pre-UPDATEstatement)valuesand:NEWtoaccessthenewupdatedvalues.

InaBEFOREUPDATEtrigger,thevaluesin:NEWmayalsobeupdated(allowingyoutochangevaluesabouttobeusedintheUPDATEstatement).

Thevaluesin:OLDareallread-onlyandcannotbeupdated.

Thefollowingexampleensuresthatstateabbreviationsarealwaysinuppercase(regardlessofhowtheywereactuallyspecifiedintheUPDATEstatement):

InputClickheretoviewcodeimage

CREATEORREPLACETRIGGERcustomers_before_updateBEFOREUPDATEONcustomersFOREACHROW

BEGIN

:NEW.cust_state:=Upper(:NEW.cust_state);

END;

Analysis

Obviously,anydatacleanupneedstooccurintheBEFOREUPDATEstatementasitdoesinthisexample.Eachtimearowisupdated,thevaluein:NEW.vend_state(thevaluethatwillbeusedtoupdatetablerows)isreplacedwithUpper(:NEW.vend_state).Noticethatthetriggerdoesn’thavetouseanUPDATEstatementtoupdatetherow.ThetriggerexecutesBEFOREtheUPDATEisexecuted,andthecodemodifiesthedatain:NEWbeforeitisused,sobythetimeOracleexecutestheoriginalUPDATEstatement,themodifiedcust_statewillbeused.

Multi-EventTriggersAllthetriggerswe’veseenthusfarexecutewhenaspecificevent(INSERT,UPDATE,orDELETE)occurs.Oracleallowstriggerstobeassociatedwithmultipleevents.Here’sanexample,aminormodificationtothelastshowntrigger:

InputClickheretoviewcodeimage

CREATEORREPLACETRIGGERcustomers_before_updateBEFOREINSERTORUPDATEONcustomersFOREACHROW

BEGIN

:NEW.cust_state:=Upper(:NEW.cust_state);

END;

Analysis

TheonlychangehereisthatBEFOREUPDATEhasbeenchangedtoBEFOREINSERTORUPDATE.Thiswayourtrigger,whichforcescorrectcaseofcust_state,willbeusedfornewcustomersaswellasupdates.

Ofcourse,triggersthatfireonmultipleeventsmustbecompatiblewithallofthoseevents.Inourexample,weused:NEW,whichisindeedpresentforbothINSERTandUPDATEoperations,andsothetriggercouldsafelybeusedforbothevents.Hadourcodeused:OLD,whichwouldbepresentforUPDATEbutnotINSERT,thisreusewouldnothavebeenpossible.

MoreonTriggersBeforewrappingthislesson,herearesomeimportantpointstokeepinmindwhenusingtriggers:

TriggersarewritteninPL/SQL,andeverythingyou’velearnedaboutPL/SQLthusfarappliestotriggers,too.

Creatingtriggersmightrequirespecialsecurityaccess.However,triggerexecutionisautomatic.IfanINSERT,UPDATE,orDELETEstatementmightbeexecuted,anyassociatedtriggersexecute,too.

Triggersshouldbeusedtoensuredataconsistency(case,formatting,andsoon).Theadvantageofperformingthistypeofprocessinginatriggeristhatitalwayshappens,andhappenstransparently,regardlessofclientapplication.

Oneveryinterestingusefortriggersisincreatinganaudittrail,asshowninthislesson.Usingtriggers,itwouldbeeasytologchanges(evenbeforeandafterstatesifneeded)toanothertable.

TriggerscaninvokeotherPL/SQLcode,includingfunctionsandstoredprocedures.

SummaryInthislesson,youlearnedwhattriggersareandwhytheyareused.Youlearnedthetriggertypesandthetimesthattheycanbeexecuted.YoualsosawexamplesoftriggersusedforINSERT,DELETE,andUPDATEoperations.

Lesson25.ManagingTransactionProcessing

Inthislesson,you’lllearnwhattransactionsareandhowtouseCOMMITandROLLBACKstatementstomanagetransactionprocessing.

UnderstandingTransactionProcessingTransactionprocessingisusedtomaintaindatabaseintegritybyensuringthatbatchesofOracleSQLoperationsexecutecompletelyornotatall.

AsexplainedbackinLesson15,“JoiningTables,”relationaldatabasesaredesignedsodataisstoredinmultipletablestofacilitateeasierdatamanipulation,management,andreuse.Withoutgoingintothehowsandwhysofrelationaldatabasedesign,takeitasagiventhatwell-designeddatabaseschemasarerelationaltosomedegree.

Theorderstablesyou’vebeenusinginpriorlessonsareagoodexampleofthis.Ordersarestoredintwotables:ordersstoresactualorders,andorderitemsstorestheindividualitemsordered.ThesetwotablesarerelatedtoeachotherusinguniqueIDscalledprimarykeys(asdiscussedinLesson1,“UnderstandingSQL”).Thesetables,inturn,arerelatedtoothertablescontainingcustomerandproductinformation.

Theprocessofaddinganordertothesystemisasfollows:

1.Checkwhetherthecustomerisalreadyinthedatabase(presentinthecustomerstable).Ifnot,addhimorher.

2.Retrievethecustomer’sID.

3.AddarowtotheorderstableassociatingitwiththecustomerID.

4.RetrievetheneworderIDassignedintheorderstable.

5.Addonerowtotheorderitemstableforeachitemordered,associatingitwiththeorderstablebytheretrievedID(andwiththeproductstablebyproductID).

Nowimaginethatsomedatabasefailure(forexample,outofdiskspace,securityrestrictions,tablelocks)preventsthisentiresequencefromcompleting.Whatwouldhappentoyourdata?

Well,ifthefailureoccurredafterthecustomerwasaddedandbeforetheorderstablewasadded,thereisnorealproblem.Itisperfectlyvalidtohavecustomerswithoutorders.Whenyourunthesequenceagain,theinsertedcustomerrecordwillberetrievedandused.Youcaneffectivelypickupwhereyouleftoff.

Butwhatifthefailureoccurredaftertheordersrowwasadded,butbeforetheorderitemsrowswereadded?Nowyouwouldhaveanemptyordersittinginyourdatabase.

Worse,whatifthesystemfailedduringaddingtheorderitemsrows?Nowyouwouldendupwithapartialorderinyourdatabase,butyouwouldn’tknowit.

Howdoyousolvethisproblem?That’swheretransactionprocessingcomesin.TransactionprocessingisamechanismusedtomanagesetsofSQLoperationsthatmustbeexecutedinbatchestoensurethatdatabasesnevercontaintheresultsofpartialoperations.Withtransactionprocessing,youcanensurethatsetsofoperationsarenotabortedmid-processing—theyeitherexecuteintheirentiretyornotatall(unlessexplicitlyinstructedotherwise).Ifnoerroroccurs,theentiresetofstatementsiscommitted(written)tothedatabasetables.Ifanerrordoesoccur,arollback(undo)canoccurtorestorethedatabasetoaknownandsafestate.

So,lookingatthesameexample,thisishowtheprocesswouldwork:

1.Checkwhetherthecustomerisalreadyinthedatabase;ifnot,addhimorher.

2.Committhecustomerinformation.

3.Retrievethecustomer’sID.

4.Addarowtotheorderstable.

5.Ifafailureoccurswhileaddingtherowtoorders,rollback.

6.RetrievetheneworderIDassignedintheorderstable.

7.Addonerowtotheorderitemstableforeachitemordered.

8.Ifafailureoccurswhileaddingrowstoorderitems,rollbackalltheorderitemsrowsaddedandtheordersrow.

9.Committheorderinformation.

Whenyou’reworkingwithtransactionsandtransactionprocessing,thereareafewkeywordsthat’llkeepreappearing.Herearethetermsyouneedtoknow:

Transaction—AblockofSQLstatements

Rollback—TheprocessofundoingspecifiedSQLstatements

Commit—WritingunsavedSQLstatementstothedatabasetables

Savepoint—Atemporaryplaceholderinatransactionsettowhichyoucanissuearollback(asopposedtorollingbackanentiretransaction)

ControllingTransactionsNowthatyouknowwhattransactionprocessingis,let’slookatwhatisinvolvedinmanagingtransactions.

ThekeytomanagingtransactionsinvolvesbreakingyourSQLstatementsintologicalchunksandexplicitlystatingwhendatashouldberolledbackandwhenitshouldnot.

UnlikemostDBMSs,Oracledoesnotrequireyoutostartatransaction.InOracle,transactionsareimplicit.AnytimeyouexecuteaSQLstatement,atransactionisstartedandfinished,andifmultiple,thestatementsareexecutedatonce;allarecontainedwithinasingletransaction.

UsingTheOracleROLLBACKcommandisusedtorollback(undo)PL/SQLstatements,asshowninthisnextstatement:

Input

SELECT*FROMorders_log;DELETEFROMorders_log;SELECT*FROMorders_log;ROLLBACK;SELECT*FROMorders_log;

Analysis

Thisexamplestartsbydisplayingthecontentsoftheorders_logstable(thistablewascreatedinLesson24,“UsingTriggers”).FirstaSELECTisperformedtoshowthatthetableisnotempty,andthenalltherowsaredeletedwithaDELETEstatement.AnotherSELECTverifiesthat,indeed,orders_logsisempty.AROLLBACKstatementisthenusedtorollbackallstatements,andthefinalSELECTshowsthatthetableisnolongerempty.

UsingOracleSQLstatementsareusuallyexecutedandwrittendirectlytothedatabasetables.Thisisknownasanimplicitcommit—thecommit(writeorsave)operationhappensautomatically.

Inatransactionblock,however,youmightwanttoforceanexplicitcommitsothatdataissavedbyusingtheCOMMITstatement,asshownhere:

InputClickheretoviewcodeimage

DELETEFROMorderitemsWHEREorder_num=20010;DELETEFROMordersWHEREorder_num=20010;COMMIT;

Analysis

Inthisexample,ordernumber20010isdeletedentirelyfromthesystem.Becausethisinvolvesupdatingtwodatabasetables,ordersandorderitems,atransactionblockisusedtoensurethattheorderisnotpartiallydeleted.ThefinalCOMMITstatementwritesthechangeonlyifnoerroroccurred.IfthefirstDELETEworked,butthesecondfailed,theDELETEwouldnotbecommitted(itwouldeffectivelybeautomaticallyundone).

Thetruthisthatthisexampleisnotoverlyuseful.IfthefirstDELETEhadfailed,thetransactionwouldhavebeenterminatedanywayandnoimplicitcommitwouldhaveoccurred.ButimagineadditionalprocessingaftertheCOMMIT,maybeupdatingstockquantities,orloggingchanges.Theabilitytocontrolwhencommitsoccurthenbecomesimportant.

Note:ImplicitTransactionCloses

AfteraCOMMITorROLLBACKstatementhasbeenexecuted,thetransactionisautomaticallyclosed(andfuturechangeswillimplicitlycommit).

UsingSavepointsSimpleROLLBACKandCOMMITstatementsenableyoutowriteorundoanentiretransaction.Althoughthisworksforsimpletransactions,morecomplextransactionsmightrequirepartialcommitsorrollbacks.

Forexample,theprocessofaddinganorderdescribedpreviouslyisasingletransaction.Ifanerroroccurs,youonlywanttorollbacktothepointbeforetheordersrowwasadded.Youdonotwanttorollbacktheadditiontothecustomerstable(iftherewasone).

Tosupporttherollbackofpartialtransactions,youmustbeabletoputbookmarksatstrategiclocationsinthetransactionblock.Then,ifarollbackisrequired,youcanrollbacktooneoftheplaceholders.

Thesebookmarksarecalledsavepoints,andtocreateone,usetheSAVEPOINTstatement,asfollows:

Input

SAVEPOINTdelete1;

Eachsavepointtakesauniquenamethatidentifiesitsothat,whenyourollback,Oracleknowswhereyouarerollingbackto.Torollbacktothissavepoint,dothefollowing:

InputClickheretoviewcodeimage

ROLLBACKTOSAVEPOINTdelete1;

Tip:TheMoreSavepointstheBetter

YoucanhaveasmanysavepointsasyouwantinyourOracleSQLcode,andthemorethebetter.Why?Becausethemoresavepointsyouhave,themoreflexibilityyouhaveinmanagingrollbacksexactlyasyouneedthem.

SummaryInthislesson,youlearnedthattransactionsareblocksofSQLstatementsthatmustbeexecutedasabatch.YoulearnedhowtousetheCOMMITandROLLBACKstatementstoexplicitlymanagewhendataiswrittenandwhenitisundone.Youalsolearnedhowtousesavepointstoprovideagreaterlevelofcontroloverrollbackoperations.

Lesson26.ManagingSecurity

Databaseserversusuallycontaincriticaldata,andensuringthesafetyandintegrityofthatdatarequiresthataccesscontrolbeused.Inthislesson,you’lllearnaboutOracleaccesscontrolandusermanagement.

UnderstandingAccessControlThebasisofsecurityforyourOracleserveristhis:Usersshouldhaveappropriateaccesstothedatatheyneed—nomoreandnoless.Inotherwords,usersshouldnothavetoomuchaccesstotoomuchdata.

Considerthefollowing:

Mostusersneedtoreadandwritedatafromtables,butfewuserswilleverneedtobeabletocreateanddroptables.

Someusersmightneedtoreadtablesbutmightnotneedtoupdatethem.

Youmightwanttoallowuserstoadddata,butnotdeletedata.

Someusers(managersoradministrators)mightneedrightstomanipulateuseraccounts,butmostshouldnot.

Youmightwantuserstoaccessdataviastoredprocedures,butneverdirectly.

Youmightwanttorestrictaccesstosomefunctionalitybasedonfromwheretheuserisloggingin.

Thesearejustexamples,buttheyhelpdemonstrateanimportantpoint.Youneedtoprovideuserswiththeaccesstheyneedandjusttheaccesstheyneed.Thisisknownasaccesscontrol,andmanagingaccesscontrolrequirescreatingandmanaginguseraccounts.

BackinLesson3,“WorkingwithOracle,”youlearnedthatyouneedtologintoOracletoperformanyoperations.Whenfirstinstalled,OraclecreatesauseraccountnamedSYSTEMthathascompleteandtotalcontrolovertheentireOracleserver.YoumighthavebeenusingtheSYSTEMloginthroughoutthelessonsinthisbook,andthatisokaywhenexperimentingwithOracleonnon-liveservers.Butintherealworld,youwouldneveruseSYSTEMonaday-to-daybasis.Instead,youwouldcreateaseriesofaccounts,someforadministration,someforusers,somefordevelopers,andsoon.

Note:PreventingInnocentMistakes

Itisimportanttonotethataccesscontrolisnotjustintendedtokeepoutuserswithmaliciousintent.Moreoftenthannot,datanightmaresaretheresultofaninadvertentmistake,amistypedOraclestatement,beinginthewrongdatabase,orsomeotherusererror.Accesscontrolhelpsavoidthesesituationsbyensuringthatusersareunabletoexecutestatementstheyshouldnotbeexecuting.

Caution:Don’tUse

TheSYSTEMlogin(actually,alltheSYSlogins—theremightbemultiplethatstartwithSYS)shouldbeconsideredsacred.Useitonlywhenabsolutelyneeded(perhapsifyoucannotgetintootheradministrativeaccounts).SYSTEMshouldneverbeusedinday-to-dayOracleoperations.

ManagingUsersOracleuseraccountsandinformationarestoredinanOracledatabasenameddba_users.Youusuallydonotneedtoaccessthedba_userstabledirectly(mostdatabaseadministratorsuseclienttoolstomanageaccounts),butsometimesyoumight.Oneofthosetimesiswhenyouwanttoobtainalistofalluseraccounts.Todothat,usethefollowingcode:

Input

SELECT*FROMdba_users;

Analysis

ThisSELECTstatementlistsallthedefinedusers(andyou’llbesurprisedbyhowmanydefaultaccountsthere).You’llalsoseeaccountcreationdates,lastlogintime,andmore.

CreatingUserAccountsTocreateanewuseraccount,usetheCREATEUSERstatement,asshownhere:

InputClickheretoviewcodeimage

CREATEUSERbenIDENTIFIEDBY“p@$$w0rd”;

Analysis

CREATEUSERcreatesanewuseraccount.Apasswordneednotbespecifiedatuseraccountcreationtime,butthisexampledoesspecifyapasswordusingIDENTIFIEDBY"p@$$w0rd"(doublequotesareneeded;singlequoteswon’twork).

Ifyouweretolisttheuseraccountsagain,youwouldseethenewaccountlistedintheoutput.

DeletingUserAccountsTodeleteauseraccount(alongwithanyassociatedrightsandprivileges),usetheDROPUSERstatementasshownhere:

Input

DROPUSERben;

Note:NoRenaming

Oracledoesn’tallowuserstoberenamed.Ifyouneedtorenameauser,you’llneedtoDROPandCREATEagain.

SettingAccessRightsWithuseraccountscreated,youmustnextassignaccessrightsandprivileges.Newlycreateduseraccountshavenoaccessatall.TheycanlogintoOraclebutwillseenodataandwillbeunabletoperformanydatabaseoperations.

Rightsgrantsarereferredtoasprivileges,andtheyarestoredinthesys.dba_sys_privstable:

Input

SELECTPRIVILEGEFROMsys.dba_sys_privsWHEREgrantee=‘ben’;

Analysis

Becausenoprivilegeshavebeendefined,thisstatementwillreturnrows.TryitagainforuserSYSTEMandyou’llseethateverythingisallowed.

Tosetrights,theGRANTstatementisused.Ataminimum,GRANTrequiresthatyouspecify:

Theprivilegebeinggranted

Theitembeinggrantedaccessto

Theusername

ThefollowingexampledemonstratestheuseofGRANT:

InputClickheretoviewcodeimage

GRANTSELECTONcustomersTOben;

Analysis

ThisGRANTallowstheuseofSELECToncustomers.BygrantingSELECTaccessonly,userbenhasread-onlyaccesstothetable.

Multiplegrantsmaybespecifiedatonce:

InputClickheretoviewcodeimage

GRANTSELECT,INSERT,UPDATEONcustomersTOben;

Analysis

ThisGRANTallowstheuseofSELECT,INSERT,andUPDATEontablecustomers.SouserbenwouldnotbeabletoDELETErows,anddefinitelynotALTERorDROPthetable.

Tip:UsePL/SQL

YoucanusePL/SQLtocreateloopstobatchtheassigningofprivileges.Ofcourse,youcouldcreatestoredprocedurestodothis,too.

TheoppositeofGRANTisREVOKE,whichisusedtorevokespecificrightsandpermissions.Hereisanexample:

InputClickheretoviewcodeimage

REVOKEINSERT,UPDATE,DELETEONcustomersFROMben;

Analysis

HereGRANTTOisreplacedwithREVOKEFROM.ThisREVOKEstatementtakesawayaccessgrantedtouserben.Theaccessbeingrevokedmustexistoranerrorwillbethrown.

Table26.1listseachofthetable-levelrightsandprivilegesthatmaybegrantedorrevoked.Table26.2listssomeoftheotherimportantdatabaserightsandprivileges;theseprivilegesareusuallytiedtospecificobjectsorcanbeusedwithANY.

TABLE26.1TableRightsandPrivileges

TABLE26.2DatabaseRightsandPrivileges

UsingGRANTandREVOKEinconjunctionwiththeprivilegeslistedinTables26.1and26.2,youhavecompletecontroloverwhatuserscanandcannotdowithyourpreciousdata.

ChangingPasswordsTochangeuserpasswords,usetheALTERUSERstatement,asshownhere:

InputClickheretoviewcodeimage

ALTERUSERbenIDENTIFIEDBY“l0ngerp@$$w0rd”REPLACE“p@$$w0rd”;

SummaryInthislesson,youlearnedaboutaccesscontrolandhowtosecureyourOracleserverbyassigningspecificrightstousers.Asyoucanimagine,thereisalotmoretothisadvancedtopic,andOracleadministratorsshoulddedicatethetimetofullyunderstandmanagingDBMSsecurity.

AppendixA.TheExampleTables

WritingSQLstatementsrequiresagoodunderstandingoftheunderlyingdatabasedesign.Withoutknowingwhatinformationisstoredinwhattable,howtablesarerelatedtoeachother,andtheactualbreakupofdatawithinarow,itisimpossibletowriteeffectiveSQL.

Youarestronglyadvisedtoactuallytryeveryexampleineverylessoninthisbook.Allthelessonsuseacommonsetofdatafiles.Toassistyouinbetterunderstandingtheexamplesandtoenableyoutofollowalongwiththelessons,thisappendixdescribesthetablesused,theirrelationships,andhowtoobtainthem.

UnderstandingtheSampleTablesThetablesusedthroughoutthisbookarepartofanorderentrysystemusedbyanimaginarydistributorofparaphernaliathatmightbeneededbyyourfavoritecartooncharacters(yes,cartooncharacters;noonesaidthatlearningOracleneededtobeboring).Thetablesareusedtoperformseveraltasks,including:

Managevendors

Manageproductcatalogs

Managecustomerlists

Entercustomerorders

Makingthisallworkrequiressixtablesthatarecloselyinterconnectedaspartofarelationaldatabasedesign.Adescriptionofeachofthetablesappearsinthefollowingsections.

Note:SimplifiedExamples

Thetablesusedherearebynomeanscomplete.Areal-worldorderentrysystemwouldhavetokeeptrackoflotsofotherdatathathasnotbeenincludedhere(forexample,paymentandaccountinginformation,shipmenttracking,andmore).However,thesetablesdodemonstratethekindsofdataorganizationandrelationshipsyouwillencounterinmostrealinstallations.Youcanapplythesetechniquesandtechnologiestoyourowndatabases.

Whatfollowsisadescriptionofeachofthesixtables,alongwiththenameofthecolumnswithineachtableandtheirdescriptions.

Note:WhyOutofOrder?

Ifyouarewonderingwhythesixtablesarelistedintheordertheyare,itisduetotheirdependencies.Becausetheproductstablesisdependentonthevendorstable,vendorsislistedfirst,andsoon.

The TableThevendorstablestoresthevendorswhoseproductsaresold(seeTableA.1).Everyvendorhasarecordinthistable,andthatvendorID(thevend_id)columnisusedtomatchproductswithvendors.

TABLEA.1vendorsTableColumns

Alltablesshouldhaveprimarykeysdefined.Thistableshouldusevend_idasitsprimarykey.vend_idisanautoincrementfield.

The TableTheproductstablecontainstheproductcatalog,oneproductperrow(seeTableA.2).EachproducthasauniqueID(theprod_idcolumn)andisrelatedtoitsvendorbyvend_id(thevendor’suniqueID).

TABLEA.2productsTableColumns

Alltablesshouldhaveprimarykeysdefined.Thistableshoulduseprod_idasitsprimarykey.

Toenforcereferentialintegrity,aforeignkeyshouldbedefinedonvend_id,relatingittovend_idinvendors.

The TableThecustomerstablestoresallcustomerinformation(seeTableA.3).EachcustomerhasauniqueID(thecust_idcolumn).

TABLEA.3customersTableColumns

Alltablesshouldhaveprimarykeysdefined.Thistableshouldusecust_idasitsprimarykey.cust_idisanautoincrementfield.

The TableTheorderstablestorescustomerorders(butnotorderdetails),asshowninTableA.4.Eachorderisuniquelynumbered(theorder_numcolumn).Ordersareassociatedwiththeappropriatecustomersbythecust_idcolumn(whichrelatestothecustomer’suniqueIDinthecustomerstable).

TABLEA.4ordersTableColumns

Alltablesshouldhaveprimarykeysdefined.Thistableshoulduseorder_numasitsprimarykey.order_numisanautoincrementfield.

Toenforcereferentialintegrity,aforeignkeyshouldbedefinedoncust_id,relatingittocust_idincustomers.

The TableTheorderitemstablestorestheactualitemsineachorder,onerowperitemperorder(seeTableA.5).Foreveryrowinorders,thereareoneormorerowsinorderitems.Eachorderitemisuniquelyidentifiedbytheordernumberplustheorderitem(firstiteminorder,seconditeminorder,andsoon).Orderitemsareassociatedwiththeirappropriateorderbytheorder_numcolumn(whichrelatestotheorder’suniqueIDinorders).Inaddition,eachorderitemcontainstheproductIDoftheitemorders(whichrelatestheitembacktotheproductstable).

TABLEA.5orderitemsTableColumns

Alltablesshouldhaveprimarykeysdefined.Thistableshoulduseorder_numandorder_itemasitsprimarykeys.

Toenforcereferentialintegrity,foreignkeysshouldbedefinedonorder_num,relatingittoorder_numinorders,andprod_id,relatingittoprod_idinproducts.

The TableTheproductnotestablestoresnotesassociatedwithspecificproducts(seeTableA.6).Notallproductsmayhaveassociatednotes,andsomeproductsmayhavemanyassociatednotes.

TABLEA.6productnotesTableColumns

Alltablesshouldhaveprimarykeysdefined.Thistableshouldusenote_idasitsprimarykey.

Toenforcereferentialintegrity,aforeignkeyshouldbedefinedonprod_id,relatingittoprod_idinproducts.

AppendixB.OraclePL/SQLDatatypes

AsexplainedinLesson1,“UnderstandingSQL,”datatypesarebasicallyrulesthatdefinewhatdatamaybestoredinacolumnandhowthatdataisactuallystored.

Datatypesareusedforseveralreasons:

Datatypesenableyoutorestrictthetypeofdatathatcanbestoredinacolumn.Forexample,anumericdatatypecolumnonlyacceptsnumericvalues.

Datatypesallowformoreefficientstorage,internally.Numbersanddatetimevaluescanbestoredinamorecondensedformatthantextstrings.

Datatypesallowforalternatesortingorders.Ifeverythingistreatedasstrings,1comesbefore10,whichcomesbefore2.(Stringsaresortedindictionarysequence,onecharacteratatimestartingfromtheleft.)Asnumericdatatypes,thenumberswouldbesortedcorrectly.

Whendesigningtables,paycarefulattentiontothedatatypesbeingused.Usingthewrongdatatypecanseriouslyimpactyourapplication.Changingthedatatypesofexistingpopulatedcolumnsisnotatrivialtask.(Inaddition,doingsocanresultindataloss.)

Althoughthisappendixisbynomeansacompletetutorialondatatypesandhowtheyaretobeused,itexplainsthemajorOracledatatypetypes,andwhattheyareusedfor.

StringDatatypesThemostcommonlyuseddatatypesarestringdatatypes.Thesestorestrings:forexample,names,addresses,phonenumbers,andZIPCodes.AslistedinTableB.1,therearebasicallytwotypesofstringdatatypethatyoucanuse—fixed-lengthstringsandvariable-lengthstrings.

TABLEB.1StringDatatypes

Fixed-lengthstringsaredatatypesthataredefinedtoacceptafixednumberofcharacters,andthatnumberisspecifiedwhenthetableiscreated.Forexample,youmightallow30charactersinafirst-namecolumnor11charactersinaSocialSecurityNumbercolumn(theexactnumberneededallowingforthetwodashes).Fixed-lengthcolumnsdonot

allowmorethanthespecifiednumberofcharacters.Theyalsoallocatestoragespaceforasmanycharactersasspecified.So,ifthestringBenisstoredina30-characterfirst-namefield,afull30bytesarestored.CHARisanexampleofafixed-lengthstringtype.

Variable-lengthstringsstoretextofvariablelength.Somevariable-lengthdatatypeshaveadefinedmaximumsize.Othersareentirelyvariable.Eitherway,onlythedataspecifiedissaved(andnoextradataisstored).VARCHARisanexampleofavariable-lengthstringtype.

Ifvariable-lengthdatatypesaresoflexible,whywouldyoueverwanttousefixed-lengthdatatypes?Theanswerisperformance.Oraclecansortandmanipulatefixed-lengthcolumnsfarmorequicklythanitcansortvariable-lengthcolumns.Inaddition,Oracledoesnotallowyoutoindexvariable-lengthcolumns(orthevariableportionofacolumn).Thisalsodramaticallyaffectsperformance.

Tip:UsingQuotes

Regardlessoftheformofstringdatatypebeingused,stringvaluesmustalwaysbesurroundedbyquotes(singlequotesareoftenpreferred).

Caution:WhenNumericValuesAreNotNumericValues

YoumightthinkthatphonenumbersandZIPCodesshouldbestoredinnumericfields(afterall,theyonlystorenumericdata),butdoingsowouldnotbeadvisable.IfyoustoretheZIPCode01234inanumericfield,thenumber1234wouldbesaved.Youwouldactuallyloseadigit.

Thebasicruletofollowis:Ifthenumberisusedincalculations(sums,averages,andsoon),itbelongsinanumericdatatypecolumn.Ifitisusedasaliteralstring(thathappenstocontainonlydigits),itbelongsinastringdatatypecolumn.

NumericDatatypesNumericdatatypesstorenumbers.UnlikemostDBMSs,Oraclereallysupportsonemajornumerictypethatsupportsbothfixed-andfloating-pointnumbers.TableB.2liststheOraclenumericdatatypes.

TABLEB.2NumericDatatypes

Tip:NotUsingQuotes

Unlikestrings,numericvaluesshouldneverbeenclosedwithinquotes.

Tip:StoringCurrency

ThereisnospecialOracledatatypeforcurrencyvalues;useNUMBER(8,2)instead.

DateandTimeDatatypesOracleusesspecialdatatypesforthestorageofdateandtimevalues,aslistedinTableB.3.

TABLEB.3DateandTimeDatatypes

BinaryDatatypesBinarydatatypesareusedtostoreallsortsofdata(evenbinaryinformation),suchasgraphicimages,multimedia,andwordprocessordocuments(seeTableB.4).

TABLEB.4BinaryDatatypes

Note:DatatypesinUse

Ifyouwouldliketoseeareal-worldexampleofhowdifferentdatabasesareused,seethesampletablecreationscripts(describedinAppendixA,“TheExampleTables”).

AppendixC.OraclePL/SQLReservedWordsandKeywords

OraclePL/SQLismadeupofkeywords—specialwordsthatareusedinperformingSQLoperations.Specialcaremustbetakentonotusethesekeywordswhennamingdatabases,tables,columns,andanyotherdatabaseobjects.

ALL

ALTER

AND

ANY

ARRAY

ARROW

AS

ASC

AT

BEGIN

BETWEEN

BY

CASE

CHECK

CLUSTER

CLUSTERS

COLAUTH

COLUMNS

COMPRESS

CONNECT

CRASH

CREATE

CURRENT

DECIMAL

DECLARE

DEFAULT

DELETE

DESC

DISTINCT

DROP

ELSE

END

EXCEPTION

EXCLUSIVE

EXISTS

FETCH

FOR

FORM

FROM

GOTO

GRANT

GROUP

HAVING

IDENTIFIED

IF

IN

INDEX

INDEXES

INSERT

INTERSECT

INTO

IS

LIKE

LOCK

MINUS

MODE

NOCOMPRESS

NOT

NOWAIT

NULL

OF

ON

OPTION

OR

ORDER,OVERLAPS

PRIOR

PROCEDURE

PUBLIC

RANGE

RECORD

RESOURCE

REVOKE

SELECT

SHARE

SIZE

SQL

START

SUBTYPE

TABAUTH

TABLE

THEN

TO

TYPE

UNION

UNIQUE

UPDATE

USE

VALUES

VIEW

VIEWS

WHEN

WHERE

WITH

InadditiontotheOraclePL/SQLreservedwords,thefollowinglistofwords(whilelegaltouse)havespecialmeaningtoOracle,andtheiruseisnotrecommended.

A

ADD

AGENT

AGGREGATE

ARRAY

ATTRIBUTE

AUTHID

AVG

BFILE_BASE

BINARY

BLOB_BASE

BLOCK

BODY

BOTH

BOUND

BULK

BYTE

C

CALL

CALLING

CASCADE

CHAR

CHAR_BASE

CHARACTER

CHARSET

CHARSETFORM

CHARSETID

CLOB_BASE

CLOSE

COLLECT

COMMENT

COMMIT

COMMITTED

COMPILED

CONSTANT

CONSTRUCTOR

CONTEXT

CONVERT

COUNT

CURSOR

CUSTOMDATUM

DANGLING

DATA

DATE

DATE_BASE

DAY

DEFINE

DETERMINISTIC

DOUBLE

DURATION

ELEMENT

ELSIF

EMPTY

ESCAPE

EXCEPT

EXCEPTIONS

EXECUTE

EXIT

EXTERNAL

FINAL

FIXED

FLOAT

FORALL

FORCE

FUNCTION

GENERAL

HASH

HEAP

HIDDEN

HOUR

IMMEDIATE

INCLUDING

INDICATOR

INDICES

INFINITE

INSTANTIABLE

INT

INTERFACE

INTERVAL

INVALIDATE

ISOLATION

JAVA

LANGUAGE

LARGE

LEADING

LENGTH

LEVEL

LIBRARY

LIKE2

LIKE4

LIKEC

LIMIT

LIMITED

LOCAL

LONG

LOOP

MAP

MAX

MAXLEN

MEMBER

MERGE

MIN

MINUTE

MOD

MODIFY

MONTH

MULTISET

NAME

NAN

NATIONAL

NATIVE

NCHAR

NEW

NOCOPY

NUMBER_BASE

OBJECT

OCICOLL

OCIDATE

OCIDATETIME

OCIDURATION

OCIINTERVAL

OCILOBLOCATOR

OCINUMBER

OCIRAW

OCIREF

OCIREFCURSOR

OCIROWID

OCISTRING

OCITYPE

ONLY

OPAQUE

OPEN

OPERATOR

ORACLE

ORADATA

ORGANIZATION

ORLANY

ORLVARY

OTHERS

OUT

OVERRIDING

PACKAGE

PARALLEL_ENABLE

PARAMETER

PARAMETERS

PARTITION

PASCAL

PIPE

PIPELINED

PRAGMA

PRECISION

PRIVATE

RAISE

RANGE

RAW

READ

RECORD

REF

REFERENCE

REM

REMAINDER

RENAME

RESULT

RETURN

RETURNING

REVERSE

ROLLBACK

ROW

SAMPLE

SAVE

SAVEPOINT

SB1

SB2

SB4

SECOND

SEGMENT

SELF

SEPARATE

SEQUENCE

SERIALIZABLE

SET

SHORT

SIZE_T

SOME

SPARSE

SQLCODE

SQLDATA

SQLNAME

SQLSTATE

STANDARD

STATIC

STDDEV

STORED

STRING

STRUCT

STYLE

SUBMULTISET

SUBPARTITION

SUBSTITUTABLE

SUBTYPE

SUM

SYNONYM

TDO

THE

TIME

TIMESTAMP

TIMEZONE_ABBR

TIMEZONE_HOUR

TIMEZONE_MINUTE

TIMEZONE_REGION

TRAILING

TRANSAC

TRANSACTIONAL

TRUSTED

TYPE

UB1

UB2

UB4

UNDER

UNSIGNED

UNTRUSTED

USE

USING

VALIST

VALUE

VARIABLE

VARIANCE

VARRAY

VARYING

VOID

WHILE

WORK

WRAPPED

WRITE

YEAR

ZONE

Index

Symbols||operator,93–94

%(percentsign),70

;(semicolon),35

_(underscore),72–73

*(wildcard),37

AABS()function,107

accesscontrol,239–240

accessrights,setting,242–243

passwords,244

useraccounts,241

users,240–241

accessrights,setting,242–243

Add_Month(),103

advantages

ofINoperator,67

ofSQL,11

AFTERtrigger,225,228

aggregatefunctions,109–110

ALLargument,117

AVG(),110–111

combining,118–119

COUNT(),112–113

defined,109

DISTINCTargument,117

distinctvalues,117–118

joins,160–161

MAX(),113–114

MIN(),114–115

namingaliases,119

overview,109

SUM(),115–116

aliases

alternativeuses,96

concatenatingfields,95–96

creating,153

fields,concatenating,95–96

tablenames,153–154

alphabeticalsortorder,47–49

ALTERTABLE,190–193

ALTERUSER,244

anchors,regularexpressions(PL/SQL),87–88

ANDkeyword,58

ANDoperator,combiningWHEREclause,61–62

ApplicationExpress,25

applications,filteringqueryresults,52

ASCkeyword,queryresultssortorder,49

ASkeyword,95–96

autoincrement,174

AVG()function,110–111

DISTINCTargument,117

Bbasiccharactermatching,regularexpressions(PL/SQL),76–79

basicsyntax,storedprocedures,208–209

BEFOREtriggers,225,228

bestpractices

joins,161

primarykeys,10

BETWEENkeyword,58

BETWEENoperator(WHEREclause),57

breakingup,data,8

Ccalculatedfields,91–92

concatenatingfields,92–94

columnaliases,95–96

mathematicalcalculations,96–98

overview,91–92

subqueries,136–139

views,202–203

calculatedvalues,totaling,116

calculations,testing,98

cartesianproduct,145

caseinsensitiveequalitycomparisons,55

casesensitivity,71

queryresultsortorder,49

SQLstatements,35

characterclasses,matching,84–85

characters

%(percentsign)wildcard,70–71

_(underscore)wildcard,72

clauses,44

GROUPBYclause,122–123,126–128

HAVINGclause,124–125

ORDERBYclause,45–46,52,126–128

positioning,53,59

SELECTclause,ordering,129

WHEREclause.SeeWHEREclause

client-basedresultsformatting,92

clients,14

client-serversoftware,Oracle,13–15

clienttools,Oracle,15–16

CLOSEstatement,217

closingcursors,217–218

colorcoding,OracleSQLDeveloper,42

columnaliases

alternativeuses,96

concatenatingfields,95–96

columns,7–8,92.Seealsofields

concepts,7–8

derivedcolumns,96

fullyqualifiednames,145

GROUPBYclause,123

individualcolumns,111

INSERTSELECTstatements,177

INSERTstatementand,173

INSERTstatement,omittingcolumns,175

multiple,sortingqueryresultsby,45–46

NULLvaluecolumns,187–189

omitting,175

paddedspaces,RTrim()function,94–95

primarykeys,9–10

retrieving,33–37

allcolumns,37–38

separatingnamesinqueries,36

sortingdata

descendingonmultiplecolumns,49

multiplecolumns,45–47

subqueryresultrestrictions,135

updatingmultiple,181

values,deleting,181

combinedqueries,163

creating,164–166

duplicaterowsand,167–168

including/eliminatingduplicaterows,167

overview,163

rules,166

sortingresults,168–169

combining

aggregatefunctions,118–119

WHEREclause,61

ANDoperator,61–62

orderofevaluation,63–65

ORoperator,62–63

comments,40–42

COMMITstatement(transactionprocessing),236–237

commits(transactionprocessing),defined,235

complexjoins,views,198–199

concatenating,93

fields,92–95

aliases,95–96

columnaliases,95–96

mathematicalcalculations,96–98

connectingOracleSQLDevelopertoOracleservers,25–26

constructs,programmingconstructs(storedprocedures),209–210

controllingtransactions,235

COMMIT,236–237

ROLLBACK,236

SAVEPOINT,237–238

correlatedsubqueries,138

COS()function,107

COUNT()function,110–113

DISTINCTargument,118

joinsand,160

COUNT*subquery,136

CREATEORREPLACETRIGGER,227

CREATEPROCEDURE,208

create.sql,30

CREATETABLE,185–187

DEFAULTkeyword,189–190

CREATETRIGGER,224

CREATEUSERstatement,241

CREATEVIEWstatement,197

cursordata,220–222

fetching,218–220

cursors,215

closing,217–218

creating,216–217

data,fetching,218–220

explicitcursors,216

implementing,216

implicitcursors,216

opening,217–218

overview,215

customerstable,247

customworkspaces,creating,24–25

Ddata

breakingcorrectly(columns),8

breakingup,8

cursordata,220–222

fetching,218–220

deleting,181–182

guidelines,183

filtering

INoperator,65–67

NOToperator,67–68

WHEREclause,51–53

inserting,171

completerows,172–176

retrieveddata,176–177

retrieving

allcolumns,37–38

distinctrows,38–39

individualcolumns,33–35

multiplecolumns,36–37

sorting,43–45

bymultiplecolumns,45–47

bynonselectedcolumns,45

specifyingsortdirection,47–49

updating,179

guidelines,183

databasemanagementsystems.SeeDBMS(DatabaseManagementSystem)

databases,5–8.Seealsotables

columns,7–8

concepts,5–6

datatypes,7–8

defined,6

primarykeys,9–10

rows,8–9

schemas,7

databaseservers,14

datagrouping,121–122

datainsertion,171

inserting

completerows,172–176

retrieveddata,176–177

views,204

WHEREclause,202

dateandtimefunctions,100,103–107

dates,104

DBMS(DatabaseManagementSystem),1,6

interactivetools,143

Oracle,13

querysortorder,44

decimalrounding,52

DECLAREstatement,219

cursors,creating,216–217

dedicatedOracleinstances,22–24

defaultsysteminstance,22

defaultvalues,tables,189–190

DEFAULTvalues,190

DELETEFROM,182

DELETEstatement,181–182

guidelines,183

WHEREclause,182

DELETEtriggers,228–230

deleting

columnvalues,181

data,181–183

tables,193

useraccounts,241

derivedcolumns,96

DESCkeyword,47–49

queryresultssortorder,47–49

dictionarysortorder(queryresults),49

DISTINCTargument,AVG()function,117

DISTINCTkeyword,39

distinctrows,retrieving,38–39

distinctvalues,aggregatefunctions,117–118

DROPcommand,213

dropping

storedprocedures,213

triggers,225

DROPTABLEstatement,193

DROPTRIGGER,225

DROPUSERstatement,241

duplicaterows,including/eliminating,167

Eemptystrings,189

equalityoperator(WHEREclause),53,243

equijoins,148

escaping,72

ETrim()function,95

exampletables,28–29

creating,30–31

obtainingtablescripts,28–30

execute,28

executingstoredprocedures,209

EXP()function,107

explicitcommits,236

explicitcursors,216

Extract(),103

FFETCH,218–220

fetchingcursordata,218–220

fields,92.Seealsocolumns

calculatedfields,91–92

concatenatingfields,92–96

mathematicalcalculations,96–98

overview,91–92

performingmathematicalcalculations,96–98

subqueries,136–139

views,202–203

concatenating,92–95

aliases,95–96

filtercondition,51

filtering

ANDoperator,61–62

applicationlevel,52

data

INoperator,65–67

NOToperator,67–68

WHEREclause,51–53

bydate,104

groups,123–126

INoperator,65–67

multiplecriteria,61

NOToperator,67–68

orderofevaluation,63–65

ORoperator,62–63

bysubqueries,131–135

views,unwanteddata,201–202

filters

%(percentsign)wildcard,70–71

_(underscore)wildcard,72–73

foreignkeys,142

ALTERTABLE,192

formatting

retrieveddatawithviews,199–200

server–basedcomparedtoclient–based,92

statements,187

subqueries,134

four-digityears,104

FROMclause

creatingjoins,144

subqueries,139

FROMkeyword,34

fullyqualifiedcolumnnames,145

fullyqualifiedtablenames,40

functions,99,207

aggregatefunctions,109–110

AVG()function,110–111

combining,118–119

COUNT()function,112–113

distinctvalues,117–118

joins,160–161

MAX()function,113–114

MIN()function,114–115

SUM()function,115–116

dateandtimefunctions,100,103–107

defined,99

numericfunctions,100,107

RTrim(),94–95

systemfunctions,100

textfunctions,100

textmanipulationfunctions,100–102

typesof,100

GGRANT,242–243

greaterthanoperator(WHEREclause),53

greaterthanorequaltooperator(WHEREclause),53

GROUPBYclause,122–123,126–128

groupingversussorting,126–128

groupingdata,121–122

filteringgroups,123–126

GROUPBYclause,122–123

nestedgroups,123

groups

creating,122–123

filtering,123–126

nestedgroups,123

guidelinesforupdating/deletingdata,183

HHAVINGclause,124–125

groupingdata,124

Iimplicitcommit,236

implicitcursors,216

INkeyword,67

innerjoins,148–149

INoperator,65–67

INSERT,171–175

insertingdata,171

completerows,172–176

retrieveddata,176–177

INSERTSELECT,176–177

INSERTstatement

columnslists,175

completingrows,172–174

omittingcolumns,175

overview,171

querydata,176–177

securityprivileges,171

VALUES,175

INSERTtrigger,225–228

installingOracle,19–20

instances

dedicatedOracleinstances,creating,22

defaultsysteminstance,22

matchingmultipleinstances,regularexpressions,85–87

Jjoiningmultipletables,149–151

joins,141

aggregatefunctions,160–161

bestpractices,161

complexjoins,views,198–199

creating,144–145

crossjoins,148

equijoins,148

innerjoins,148–149

leftouterjoin,160

naturaljoins,157–158

outerjoins,158–160

performance,150

reasonsforusing,143

rightouterjoin,160

selfjoins,154–157

versussubqueries,157

views,198–199

WHEREclause,145–148

Kkeys

foreignkeys,142

ALTERTABLE,192

primarykeys,9–10,142

keywords,33,255–257

AND,62

AS,95–96

ASC,queryresultssortorder,49

BETWEEN,58

DEFAULT,tablevalues,189–190

DESC,47–49

DISTINCT,39

FROM,34

IN,67

NOT,67

OR,63

Llanguages,SQL,11

Last_Day(),103

leftouterjoin,160

Length(),101

lessthanoperator(WHEREclause),53

lessthanorequaltooperator(WHEREclause),53

LIKEoperator,69,88

searchingwith

percentsign(%),70

underscore(_),72–73

LOOPstatement,222

Lower()function,101

LTrim()function,95,101

MMacusers,Oracle,17

matchingcharacterclasses,regularexpressions(PL/SQL),84–85

matchingmultipleinstances,regularexpressions(PL/SQL),85–87

matchingoneofseveralcharacters,regularexpressions(PL/SQL),80–81

matchingranges,regularexpressions(PL/SQL),82–83

matchingspecialcharacters,regularexpressions(PL/SQL),83–84

mathematicalcalculations,performinginfields,96–98

mathematicaloperators,98

MAX()function,110,113–114

non–numericdata,114

NULLvalues,114

MIN()function,110,114–115

DISTINCTargument,118

NULLvalues,115

Months_Between(),103

multi-eventtriggers,231

multiplecolumns

retrieving,36–37

sortingdata,45–47

multipleinstances,matchingregularexpressions,85–87

multipletables,joining,149–151

multipleworksheets,28

Nnames

fullyqualifiedcolumnnames,145

fullyqualifiedtablenames,40

naturaljoins,157–158

navigatingtables,cursors,215

nestedgroups,123

Next_Day(),103

non–equalityoperator(WHEREclause),53,243

NOTNULL,189

NOToperator,67–68

NULL,59

NULLkeyword,updatingcolumns,181

NULLvalues,187–189

AVG()function,110–111

comparedtoemptystrings,189

COUNT()function,113

emptystrings,189

tablecolumns,187–189

numericdatatypes,253–254

numericfunctions,100,107

Oomittingcolumns,175

openingcursors,217–218

OPENstatement,217

operators

defined,61

groupingrelated,64

HAVINGclause,124

INoperator,65–67

LIKEoperator,69

mathematicaloperators,98

NOToperator,67–68

||operator,93–94

WHEREclause,53

checkingagainstasinglevalue,54–56

checkingfornonmatches,56–57

checkingfornovalue,58–59

checkingforrangeofvalues,57–58

Oracle,13

client–serversoftware,13–15

clienttools,15–16

installing,19–20

Macusers,17

PL/SQL,15

savepoints,237

settingup

installingsoftware,19–20

obtainingsoftware,18–19

requiredsoftware,16–18

OracleDatabaseExpressEdition,18

OracleExpressEdition,creatingcustomworkspaces,24–25

OracleserversconnectingtoOracleSQLDeveloper,25–26

OracleSQLDeveloper,19,32

colorcoding,42

connectingtoOracleservers,25–26

overview,27–28

ORDERBYclause,45–46,52,126–128

ascending/descendingsortorder,47–49

comparedtoGROUPBYclause,126–128

SELECTstatement,44

sortingbymultiplecolumns,45–46

views,197

ordering

SELECTclause,129

sequencenumber,47

orderitemstable,248–249

orderofevaluation,combining(WHEREclause),63–65

orderstable,248

ORmatches,regularexpressions(PL/SQL),79–80

ORoperator,combining(WHEREclause),62–63

outerjoins,158–160

Pparentheses,WHEREclause,65

passwords,accesscontrol,244

percentsign(%),wildcardsearches,70

performance,151

joins,150

subqueries,136

views,197

performingmathematicalcalculations,calculatedfields,96–98

PI()function,107

placeholders,235–238

PL/SQL(ProceduralLanguage/StructuredQueryLanguage),15

regularexpressions,76

anchors,87–88

basiccharactermatching,76–79

matchingcharacterclasses,84–85

matchingmultipleinstances,85–87

matchingoneofseveralcharacters,80–81

matchingranges,82–83

matchingspecialcharacters,83–84

ORmatches,79–80

populate.sql,30

populatingtables,31–32

portability,99

INSERTstatementsand,175

predicates(operators),70

primarykeys,9–10,142

bestpractices,10

concepts,9–10

Customerexampletable,248

importance,9

OrderItemsexampletable,249

Ordersexampletable,248

Productsexampletable,247,250

updatingtables,191–192

Vendorsexampletable,247

privileges,242–243

ProceduralLanguage/StructuredQueryLanguage.SeePL/SQL

processing

subqueries,133

transactions.Seetransactionprocessing

productnotestable,249–250

productstable,247

programmingconstructs,storedprocedures,209–210

Qqueries,131

calculatedfields,136–139

concatenatingfields,92–96

mathematicalcalculations,96–98

overview,91–92

combinedqueries,163

creating,164–166

including/eliminatingduplicaterows,167

sortingresults,168–169

combining,133

dataformatting,37

defined,131

filteringby,131–134

INSERTstatementand,176–177

multipleWHEREclauses,166

overview,131

sortingresults,43–44

ascending/descendingorder,47–49

casesensitivity,49

bymultiplecolumns,45–46

nonselectedcolumnsand,45

subqueries,139

tablealiases,154

views,195

wildcards(*),37–38

quotes,WHEREclause,57

Rrecords,comparedtorows,9

referentialintegrity,143

reformattingretrieveddatawithviews,199–201

REGEXP_INSTR(),76

REGEXP_LIKE(),76,88

REGEXP_REPLACE(),76

REGEXP_SUBSTR(),76

regularexpressions,75

PL/SQL,76

anchors,87–88

basiccharactermatching,76–79

matchingcharacterclasses,84–85

matchingmultipleinstances,85–87

matchingoneofseveralcharacters,80–81

matchingranges,82–83

matchingspecialcharacters,83–84

ORmatches,79–80

relationaldatabases,sortorderand,44

relationaltables,141–143

removingviews,197

renamingtables,193

REPEATUNTILstatement,222

repetitionmetacharacters,85

REPLACEPROCEDURE,208

reservedwords,255

restrictions,views,197

resultsets,215

retrieveddata

inserting,176–177

reformattingwithviews,199–201

retrievingdata

allcolumns,37–38

distinctrows,38–39

individualcolumns,33–35

multiplecolumns,36–37

reusableviews,199

REVOKEstatement,243–244

RIGHTkeyword(outerjoins),159

rightouterjoin,160

ROLLBACKcommand(transactionprocessing),236

rollbacks(transactionprocessing)

COMMITstatement,237

defined,235

ROLLBACKcommand,236

savepointsand,237–238

statements,238

rows,8–9

cursors,215

duplicaterows,167

insertingcompleterows,172–176

INSERTstatement,172–174

retrievingdistinctrows,38–39

RTrim()function,94–95,99–101

rules

UNION,166

views,197

runscriptsversusrunstatements,28

runstatements,28

Ssampletables,245

customerstable,247

orderitemstable,248–249

orderstable,248

productnotestable,249–250

productstable,247

vendorstable,246

savepoints,transactionprocessing,235–238

scalablity,143

scale,143

schemas,7

schemata,7

searchcriteria,51

searchpatterns,69

security

accesscontrol,239–240

deletinguseraccounts,241

passwords,244

settingaccessrights,242–243

useraccounts,241

users,240–241

UPDATEstatement,179,182

SELECTclause,ordering,129

SELECTstatement,33

ASkeyword,95–96

AVG()function,111

combinedqueries,163

combining,61

concatenatingfields,94

COUNT()function,113

ISNULLclause,58

ORDERBYclause,44

retrieving

allcolumns,37–38

distinctrows,38

individualcolumns,33–35

multiplecolumns,36–37

unknown,38

subqueries,133–134

WHEREclause,51

selfjoins,154–157

semicolons(;),35

sequencenumber,orderingby,47

sequence(SELECTstatementclauses),129

server-basedresultsformatting

comparedtoclient-based,92

servers,14

SETcommand,updatingtables,180

SIN()function,107

software,obtainingforOraclesetup,18–19

sortdirection,specifying,47–49

sorting

combinedqueryresults,168–169

data,43–45

bymultiplecolumns,45–47

bynonselectedcolumns,45

specifyingsortdirection,47–49

versusgrouping,126–128

queryresults,43–44

ascending/descendingorder,47–49

casesensitivity,49

bymultiplecolumns,45–46

nonselectedcolumnsand,45

SOUNDEX()function101–102

spaces,removing(RTrimfunction),94–95

specialcharacters,69

matchingwithregularexpressions,83–84

SQL,10–11,15

advantagesof,11

deleting/updatingdata,183

overview,10

PL/SQL,15

SQLstatements,30,33

casesensitivity,35

comments,40–42

terminating,35

whitespace,35

SQRT()function,107

statements

ALTERTABLE,190

clauses,44

COMMIT,237

CREATETABLE,185–186

CREATEVIEW,197

DELETE,181–183

DROPTABLE,193

formatting,187

groupingrelatedoperators,64

INSERT.SeeINSERTstatement

rollbacks,238

defined,235

SELECT.SeeSELECTstatement

storedprocedures

disadvantagesof,207

overview,205–206

usefulnessof,206

UPDATE,179–183

storedprocedures,205–208

basicsyntax,208–209

buildingintelligentstoredprocedures,210–213

creating,208

disadvantagesof,207

dropping,213

executing,209

overview,205–206

programmingconstructs,209–210

reasonsforusing,206–207

usefulnessof,206

strings.Seealsotextfunctions

datatypes,252–253

empty,comparedtoNULLvalues,189

wildcardsearchingand,70

subqueries,131

ascalculatedfields,136–139

buildingqueries,139

correlatedsubqueries,138

filteringby,131–135

FROMclause,139

maximumamountof,135

SELECTstatements,133–134

selfjoinsand,155–157

UPDATEstatement,181

WHEREclause,135

SUM()function,110,115–116

multiplecolumns,116

NULLvalues,116

syntax,storedprocedures,208–209

Sysdate(),103

SYSlogins,240

systemfunctions,100

SYSTEMlogin,240

Ttablealiases,153–154

tablerights,243

tables,6–7

calculatedfields

concatenatingfields,92–96

mathematicalcalculations,96–98

overview,91–92

CartesianProduct,145

concepts,6–7

creating,144,185–187

CREATETABLE,186

defaultvalues,189–190

NULLvalues,187–189

overview,185

customerstable,247

defaultvalues,189–190

deleting,193

exampletables,28–29

creating,30–31

obtainingtablescripts,28–30

populating,31–32

functionsof,28,245

innerjoins,148

insertingdata,172–174

fromqueries,176–177

joiningmultipletables,149–151

multipletables,149–151

naming,7

NULLvalue,checkingfor,58

NULLvaluecolumns,187–189

orderitemstable,248

orderstable,248

overview,141

performanceconsiderations,150

productstable,247

relationaltables,141–143

renaming,193

rows,8

sampletables,245

updating,179–181,190–191

deletingdata,181–182

primarykeys,191–192

usefulnessof,143

vendorstable,246

virtual.Seeviews

WHEREclause,145,148

tablescripts,obtaining,29–30

Tan()function,107

terminatingSQLstatements,35

testingcalculations,98

textfunctions,100–101

listofcommon,101–103

textmanipulationfunctions,100–102

To_Date(),103

tools,clienttools(Oracle),15–16

trailingspaces,72

transactionprocessing,233–235,237–238

COMMITcommand,237

explicitcommits,236

managing,235

overview,233–234

ROLLBACKcommand,236

terminology,235

transactions

controlling,235

COMMIT,236–237

ROLLBACK,236

SAVEPOINT,237–238

defined,235

triggers,223–224

AFTERtrigger,228

BEFOREtriggers,228

creating,224–225

DELETEtriggers,228–230

dropping,225

INSERTtrigger,225–228

multi-eventtriggers,231

overview,232

UPDATEtriggers,230–231

Trim()function,95

trimmingpaddedspaces,94–95

Uunderscore(_),72–73

UNION

creatingcombinedqueries,164–166

duplicaterows,167

rulesfor,166

sortingcombinedqueryresults,168–169

versusWHEREclause,168

unions,163.Seealsocombinedqueries

unknown,59

unsorteddata,queryresults,34

UPDATE,179–181

guidelines,183

securityprivileges,179,182

subqueries,181

UPDATEtriggers,230–231

updating

data,179

guidelines,183

tabledata,179–181

deletingdata,181–182

tables,190–191

primarykeys,191–192

views,198,203–204

Upper()function,101

useraccounts,241

users,accesscontrol,240–241

Vvalues

concatenation,93

trimmingpaddedspace,95

VALUES,175

vendorstable,246

views,195–196

calculatedfields,202–203

complexjoins,198–199

creating,197

dataretrieval,204

filteringdata,201–202

joins,simplifying,198–199

ORDERBYclause,197

overview,195

performance,197

reasonsforusing,196

reformattingretrieveddata,199–201

removing,197

restrictions,197

reusable,199

rules,197

updating,198,203–204

usefulnessof,196

virtualtables.Seeviews

W–X–Y–Zwebsites,exampletabledownloadsite,29

WHEREclause,51–53.SeealsoHAVINGclause

checkingagainstsinglevalue,54

checkingfornonmatches,56–57

checkingforNULLvalue,58

checkingforrangeofvalues,57–58

combining,61

ANDoperator,61–62

orderofevaluation,63–65

ORoperator,62–63

inqueries,163

dataretrieval,202

DELETEstatements,182

filteringdata,124

filteringgroups,125

joins,145–148

operators,53

checkingagainstasinglevalue,54–56

checkingfornonmatches,56–57

checkingfornovalue,58–59

checkingforrangeofvalues,57–58

parentheses,65

quotes,57

Soundex()function,102

subqueries,134–135

UPDATEstatements,179–180

versusUNION,168

wildcards,69

whitespace,SQLstatements,35

wildcard(*),37

wildcards,37–38,69

naturaljoins,158

wildcardsearches

LIKEoperators,69

percentsign(%),70

tipsfor,74

trailingspaces,72

underscore(_),72–73

workingenvironments,21

creating

customworkspaces,24–25

dedicatedOracleinstances,22–24

worksheets,multipleworksheets,28

writingstoredprocedures,207

CodeSnippets