About This eBook - irantuto.comirantuto.com/upload/Oracle/books/oracle_pl_sql_in_10_minutes.pdfAbout...
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,[email protected].
ForquestionsaboutsalesoutsidetheU.S.,[email protected].
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:[email protected]
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=‘[email protected]’WHEREcust_id=10005;
TheUPDATEstatementalwaysbeginswiththenameofthetablebeingupdated.Inthisexample,itisthecustomerstable.TheSETcommandisthenusedtoassignthenewvaluetoacolumn.Asusedhere,theSETclausesetsthecust_emailcolumntothespecifiedvalue:
ClickheretoviewcodeimageSETcust_email=‘[email protected]’
TheUPDATEstatementfinisheswithaWHEREclausethattellsOraclewhichrowtoupdate.WithoutaWHEREclause,Oraclewouldupdatealltherowsinthecustomerstablewiththisnewemailaddress—definitelynotthedesiredeffect.
Note:NoOutput
UPDATEstatementsusuallygeneratenooutput,butifyouexecutetheprecedingstatementinOracleSQLDeveloper,youshouldseea1rowupdated.message.Ifmorethanonerowwasupdated,well,thatprobablymeansthatyouomitted(ormistyped)theWHEREclause.
Updatingmultiplecolumnsrequiresaslightlydifferentsyntax:
InputClickheretoviewcodeimage
UPDATEcustomersSETcust_name=‘TheFudds’,cust_email=‘[email protected]’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.|[email protected]||10003|Wascals|[email protected]||10004|YosemitePlace|[email protected]|+–––+–––––-+–––––––+
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