Advanced Oracle PL/SQL Developer’s -...
Transcript of Advanced Oracle PL/SQL Developer’s -...
TableofContents
AdvancedOraclePL/SQLDeveloper’sGuideSecondEdition
Credits
AbouttheAuthor
AbouttheReviewers
www.PacktPub.com
Supportfiles,eBooks,discountoffers,andmore
Whysubscribe?
FreeaccessforPacktaccountholders
InstantupdatesonnewPacktbooks
Preface
Whatthisbookcovers
Whatyouneedforthisbook
Whothisbookisfor
Conventions
Readerfeedback
Customersupport
Downloadingtheexamplecode
Errata
Piracy
Questions
1.OverviewofPL/SQLProgrammingConcepts
IntroductiontoPL/SQL
PL/SQLprogramfundamentals
Cursors–anoverview
Thecursorexecutioncycle
Cursorattributes
CursorFORloop
ExceptionhandlinginPL/SQL
System-definedexceptions
User-definedexceptions
TheRAISE_APPLICATION_ERRORprocedure
Exceptionpropagation
Creatingstoredprocedures
Executingaprocedure
Functions
Functions–executionmethods
RestrictionsoncallingfunctionsfromSQLexpressions
APL/SQLpackage
OracleDatabase12cenhancementstoPL/SQLsubprograms
Managingdatabasedependencies
Displayingthedirectandindirectdependencies
Dependencymetadata
Dependencyissuesandenhancements
ReviewingOracle-suppliedpackages
OracleSQLDeveloper
OracleSQLDeveloperforDBA,Developers,andApplicationArchitects
SQLDeveloper4.0
Summary
Practiceexercise
2.Oracle12cSQLandPL/SQLNewFeatures
DatabaseconsolidationandthenewMultitenantarchitecture
TheOracleDatabase12cMultitenantarchitecture–features
MultitenantforConsolidation
Plug/unplug
ManageManyasOne
Rapidprovisioning
CDBResourceManagement
Commonusersandlocalusers
Oracle12cSQLandPL/SQLnewfeatures
IDENTITYcolumns
DefaultcolumnvaluetoasequenceinOracle12c
TheDEFAULTONNULLclause
Supportfor32KVARCHAR2
RowlimitingusingFETCHFIRST
Invisiblecolumns
Temporaldatabases
In-DatabaseArchiving
DefiningaPL/SQLsubprogramintheSELECTqueryandPRAGMAUDF
Testsetup
Comparativeanalysis
ThePL/SQLprogramunitwhitelisting
GrantingrolestoPL/SQLprogramunits
Testsetup
MiscellaneousPL/SQLenhancements
TheOracleDatabase12c(12.1.0.2)In-Memoryoption
Thechallenge
TheproblemstatementandOracleDatabase12cIn-Memory
OracleDatabase12cIn-Memoryoptionfeatures
TheOracleDatabase12cIn-MemoryArchitecture
ControllingtheIn-Memorycolumnstore
TheINMEMORYclause
Performanceoptimizations
In-MemoryAdvisor
OracleDatabaseIn-Memorybenefits
Summary
3.DesigningPL/SQLCode
Cursorstructures
Cursorexecutioncycle
Cursorattributes
Implicitcursors
Explicitcursors
Cursorvariables
Strongandweakrefcursortypes
Workingwithcursorvariables
SYS_REFCURSOR
Cursorvariablesasarguments
Cursorvariables–restrictions
Cursordesignconsiderations
Cursordesign–guidelines
ImplicitstatementresultsinOracleDatabase12c
Subtypes
Subtypeclassification
Typecompatibilitywithsubtypes
Summary
Practiceexercise
4.UsingCollections
Introductiontocollections
Collectiontypes
Associativearrays
Nestedtables
Modifyanddropanestedtableobjecttype
Designconsiderationsofanestedtable
Nestedtablestorage
Nestedtableinanindex-organizedtable
Nestedtablelocators
Nestedtableastheschemaobject
Operationsonanestedtabletypecolumn
Createanestedtableinstance
Queryinganestedtablecolumn
NestedtablecollectiontypeinPL/SQL
Collectioninitialization
Queryingthenestedtablemetadata
Nestedtablecomparisonfunctions
Multisetoperationsonnestedtables
Varray
Varrayasaschemaobject
Operationsonvarraytypecolumns
Insertingvarraycollectiontypeinstance
Queryingvarraycolumn
Updatingthevarrayinstance
VarrayinPL/SQL
Comparingthecollectiontypes
Selectingtheappropriatecollectiontype
Oracle12cenhancementstocollections
PL/SQLcollectionmethods
EXISTS
COUNT
LIMIT
FIRSTandLAST
PRIORandNEXT
EXTEND
TRIM
DELETE
Summary
Practiceexercise
5.UsingAdvancedInterfaceMethods
OverviewofExternalProcedures
ExternalProcedures
Componentsofexternalprocedureexecutionflow
Theextprocagent
TheLibraryobject
CalloutandCallback
CallSpecification
HowanExternalProcedureexecutes
Environmentsetup
TNSNAMES.ora
EXTPROC.ora
ExecutingexternalCprogramsfromPL/SQL
SecuringExternalProcedureswithOracleDatabase12c
ExecutingJavaprogramsfromPL/SQL
LoadingaJavaclassintoadatabase
StepstoexecuteaJavaclassfromanOraclePL/SQLunit
Summary
Practiceexercise
6.VirtualPrivateDatabase
OracleDatabaseSecurityoverview
Fine-GrainedAccessControl
HowFGACworks
VirtualPrivateDatabase
HowdoesVirtualPrivateDatabasework?
Column-levelVirtualPrivateDatabase
VirtualPrivateDatabasewithOracleDatabase12cMultitenant
VirtualPrivateDatabasecomponents
ApplicationContext
VirtualPrivateDatabasepolicyfunction
Policytypes
TheDBMS_RLSpackage
Demonstration
VirtualPrivateDatabasefeaturesandbestpractices
VirtualPrivateDatabasemetadata
Policyutilities—refreshanddrop
OracleDatabase12cSecurityenhancements
OracleDatabase12cDataRedaction
DataRedactionexemptionsandmiscellaneousfeatures
DataRedactionfunctiontypes
Demonstration
TheDataRedactionmetadata
Summary
Practiceexercise
7.OracleSecureFiles
IntroductiontoLargeObjects
ClassificationofLargeObjectdatatypes
InternalLOB
PersistentandTemporaryLOB
ExternalLOB
LOBrestrictions
LOBdatatypesinOracle
BLOBandCLOB
BFILE
Somemorerelatedstuff
TheLOBlocator
LOBinstanceinitialization
TheDBMS_LOBpackage
TheDBMS_LOBconstants
TheDBMS_LOBdatatypes
TheDBMS_LOBsubprograms
LOBusagenotes
OracleSecureFiles
Deduplicationandcompression
Encryption
FileSystemLogging
WriteGatherCache
Freespacemanagement
BasicFilesandSecureFiles
Thedb_securefileparameter
WorkingwithLOBs
LOBmetadata
EnablingtheadvancedfeaturesofaSecureFile
PopulatingtheLOBdata
TemporaryLOBoperations
ManagingtemporaryLOBs
WorkingwithatemporaryLOB
MigratingLONGtoLOBs
UsetheALTERTABLEcommand
UsingtheTO_LOBfunction
OnlineTableRedefinition
MigratingBasicFilestoSecureFiles
OracleDatabase12cenhancementstoSecureFiles
Summary
Practiceexercise
8.TuningthePL/SQLCode
ThePL/SQLCompiler
SubprograminlininginPL/SQL
PRAGMAINLINE
PLSQL_OPTIMIZE_LEVEL
Case1:WhenPLSQL_OPTIMIZE_LEVEL=0
Case2:WhenPLSQL_OPTIMIZE_LEVEL=1
Case3:WhenPLSQL_OPTIMIZE_LEVEL=2
Case4:WhenPLSQL_OPTIMIZE_LEVEL=3
Nativeandinterpretedcompilationtechniques
OracleDatabase11gRealNativeCompilation
Selectingtheappropriatecompilationmode
Settingthecompilationmode
Queryingthecompilationsettings
Compilingaprogramunitfornativeorinterpretedcompilation
RecompilingadatabaseforaPL/SQLnativeorinterpretedcompilation
TuningPL/SQLcode
Buildsecureapplicationsusingbindvariables
Callparametersbyreference
Avoidinganimplicitdatatypeconversion
UnderstandingtheNOTNULLconstraint
Selectionofanappropriatenumericdatatype
BulkprocessinginPL/SQL
BULKCOLLECT
FORALL
FORALLandexceptionhandling
Summary
Practiceexercise
9.ResultCache
OracleDatabase11gResultCache
WhatistheServerResultCache?
ConfiguringtheServerResultCache
ResultCacheversusBufferCache
ResultCacheversusOracle12cDatabaseIn-Memory
ResultCacheversusIn-MemoryDatabaseCache
SQLqueryResultCache
MonitoringtheSQLResultCache
InvalidationoftheSQLResultCache
ReadconsistencyoftheSQLResultCache
Limitations
PL/SQLFunctionResultCache
Doesitsoundsimilartodeterministicfunctions?
DifferencesbetweenResultCacheandothercachingtechniques
Illustration
MonitoringthePL/SQLResultCache
InvalidationofthePL/SQLResultCache
Limitation
OCIClientresultscache
TheDBMS_RESULT_CACHEpackage
Displayingtheresultcachememoryreport
OracleDatabase12cenhancementstothePL/SQLfunctionResultCache
ResultcacheinRealApplicationClusters
Summary
Practiceexercise
10.Analyzing,Profiling,andTracingPL/SQLCode
AsamplePL/SQLprogram
TrackingPL/SQLcodinginformation
USER_ARGUMENTS
USER_OBJECTS
USER_OBJECT_SIZE
USER_SOURCE
USER_PROCEDURES
USER_PLSQL_OBJECT_SETTINGSandUSER_STORED_SETTINGS
USER_DEPENDENCIES
TheDBMS_DESCRIBEpackage
Trackingtheprogramexecutionsubprogramcallstack
TrackingpropagatingexceptionsinPL/SQLcode
Determiningidentifiertypesandusages
USER_IDENTIFIERS
ThePL/Scopetool
ThePLSCOPE_SETTINGSparameter
TheDBMS_METADATApackage
DBMS_METADATAdatatypesandsubprograms
Parameterrequirements
TheDBMS_METADATAtransformationparametersandfilters
Demonstration
TracingPL/SQLprogramsusingDBMS_TRACE
InstallingtheDBMS_TRACEpackage
DBMS_TRACEsubprograms
CompilingaPL/SQLprogramfordebugging
ViewingthePL/SQLtraceinformation
StepstotracePL/SQLprogramexecution
ProfilingPL/SQLcode
TheDBMS_HPROFpackage
DifferencesbetweenDBMS_PROFILERandDBMS_HPROF
DBMS_HPROFsubprograms
Collectingrawprofiledata
Interpretingtherawprofilerdata
Analyzingprofilerdata
Creatingtheprofilertables
Analyzingtheprofileroutput
Queryingtheprofilertables
Theplshprofutility
Whatdothesereportsreveal?
Summary
Practiceexercise
11.SafeguardingPL/SQLCodeagainstSQLinjection
WhatisSQLinjection?
SQLinjectiontargets
HowtoexploitthePL/SQLcode?
PreventingSQLinjectionattacks
SanitizinginputsusingDBMS_ASSERT
Choosetherightsubprogramfortherightidentifier
Unquotedidentifiers
Quotedidentifiers
Literals
DBMS_ASSERT–limitations
Useofbindvariablestopreventinjectionattacks
BestpracticestoavoidSQLinjection
TestingthecodeforSQLinjectionflaws
Teststrategy
Aneffectivecodereview
Staticcodeanalysis
Fuzztools
Generatingtestcases
Summary
Practiceexercise
12.WorkingwithOracleSQLDeveloper
AnoverviewofSQLDeveloper
Keydifferentiators
Historyandbackground
SQLDeveloperforDevelopers
SQLDeveloperforDatabaseAdministrators
SQLcl–ThenewSQLcommandline
GettingstartedwithSQLDeveloper
Creatingadatabaseconnection
UsingtheSQLworksheet
CorefeaturesofSQLDeveloper
ObjectBrowser
PL/SQLEditorandDebugger
DBAPanel
DatabaseUtilities
TheDataModeler
SQLDeveloperreports
Versioncontrol
TheSQLTranslationFramework
SQLDeveloper4.0and4.1NewFeatures
Summary
Index
AdvancedOraclePL/SQLDeveloper’sGuideSecondEditionCopyright©2016PacktPublishing
Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.
Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishinganditsdealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecauseddirectlyorindirectlybythisbook.
PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.
Firstpublished:May2012
Secondedition:February2016
Productionreference:1080216
PublishedbyPacktPublishingLtd.
LiveryPlace
35LiveryStreet
BirminghamB32PB,UK.
ISBN978-1-78528-480-9
www.packtpub.com
CreditsAuthor
SaurabhK.Gupta
Reviewers
KamranAghayevA
PatrickBarel
NassyamBasha
RamakrishnaKandula
WissemELKhlifi
SeanStacey
DavorZelic
CommissioningEditor
PriyaSingh
AcquisitionEditor
TusharGupta
ContentDevelopmentEditor
ArwaManasawala
TechnicalEditor
RohanUttamGosavi
CopyEditor
StephenCopestake
ProjectCoordinator
ShwetaHBirwatkar
Proofreader
SafisEditing
Indexer
MonicaAjmeraMehta
Graphics
AbhinashSahu
ProductionCoordinator
NileshR.Mohite
AbouttheAuthorSaurabhK.Guptaisaseasoneddatabasetechnologistwithextensiveexperienceindesigninghighperformanceandhighlyavailabledatabaseapplications.HistechnologyfocushasbeencenteredaroundOracleDatabasearchitecture,OracleCloudplatform,DatabaseIn-Memory,DatabaseConsolidation,Multitenant,Exadata,BigData,andHadoop.Hehasauthoredthefirsteditionofthisbook.HeisanactivespeakerattechnicalconferencesfromOracleTechnologyNetwork,IOUGCollaborate‘15,AIOUGSangam,andTechDays.Connectwithhimonhistwitterhandle(orSAURABHKG)orthroughhistechnicalblogwww.sbhoracle.wordpress.com,withcomments,suggestions,andfeedbackregardingthisbook.
AbouttheReviewersPatrickBarelisaPL/SQLdeveloperforAMISServices(http://www.amis.nl/)intheNetherlands.BesidesworkingwithSQLandPL/SQL,heco-developedCodeGentogetherwithStevenFeuerstein,andhaswrittendifferentplugins(http://bar-solutions.com/)forPL/SQLdeveloperat(http://www.allroundautomations.com/).HepublishesarticlesonAMISTechnologyBlog(http://technology.amis.nl/blog)andonhisownblog(http://blog.bar-solutions.com).
HehasbeenareviewerforseveralbooksincludingOraclePL/SQLProgrammingbyStevenFeuerstein.HehasbeenanOracleACEsince2011.
NassyamBashaisadatabaseadministratorandanOracleACEDirector.Heholdsamaster’sdegreeinComputerApplicationsfromtheUniversityofMadras.HeisanOracle11gCertifiedMasterandExadataimplementationspecialist,andhasgoodknowledgeofOracletechnologies,suchasDataGuard,RMAN,RAC,andExadata.HeactivelyparticipatesinOracle-relatedforums,suchasOTN,wherehehassuperherostatus.HemaintainsanOracle-technology-relatedblog(www.oracle-ckpt.com)andhascoauthoredOracleDataGuard11gR2administrationbeginnersguide,PacktPublishing.HeactivelywritesmanyarticlesonOTNinvariouslanguages.HeisaspeakeratOTN,IOUG,andSANGAM,andheistheco-founderofOraworld-team(www.oraworld-team.com).HeispartoftheAIOUGcommunityonTwitter,whereheoccasionallyexpresseshisviewsviatheTwitterhandle@AIOUG.HeiscurrentlyworkingwithPythianasanOracledatabaseconsultant.
NassyamBashahaswrittenOracleDataGuard11gR2Beginner’sGuide,PacktPublishing.
IwanttothankthealmightyAllahandmyparents,AbdulAleemandRahimunnisa,fortheirsupportandblessingsallthetime—withoutthem,nothingispossible.Specialthankstomywifeand9-month-olddaughterYashfeenFathima,who’vesharedalotoffunandcrazythingswithmewhileIworkedonthisbook,and,asalways,Iwouldalsoliketothankmybrother,Nawaz,andmycousins,fortheirgreatsupport.Finally,thankstoSaurabhGuptaforreferringmeasatechnicalreviewer,whichwasnotaneasytaskforme,asthisismyfirstassignmentasareviewer.Hedidagreatjobonthisbook.
WissemElKhlifiisthefirstOracleACEinSpainandanOracleCertifiedProfessionalDBAwithover12yearsofITexperience.
HeearnedhisComputerScienceengineeringdegreefromFSTTunisia,hismaster’sdegreeinComputerSciencefromtheUPC,Barcelona,andanothermaster’sdegreeinBigDataSciencefromtheUPC,Barcelona.
HisareasofinterestareLinuxSystemAdministration,OracleERPandDatabases(RACandDataguard),bigdataNoSQLdatabasemanagement,andbigdataanalysis.
HiscareerhasincludedtherolesofOracleandJavaanalyst/programmer,OracleDBA,architect,teamleader,andbigdatascientist.Hecurrentlyworksasseniordatabaseand
applicationengineerforSchneiderElectric/APC.
Hewritesnumerousarticlesonhiswebsite,http://www.oracle-class.com,andyoucancontacthimviaTwitterat@orawiss.
DavorZelicisanITprofessionalwithmorethan15yearsofexperienceindesigning,developing,andimplementingITsystems.
Aftergettinghismaster’sdegreeinElectricalEngineering,hebeganhisprofessionalcareerworkingwithOracletechnologyintheCroatianITcompanyTEBInformatika.Formorethan10years,DavorworkedonITprojectsrelatedtoroadmanagement,wherehegainedextensiveexperienceworkingasanOracleSQL,PLSQL,Forms,andReportsandSpatialdeveloper.HehasprovedhisknowledgebybecominganOracleCertifiedProfessionalissuedbytheOracleCorporation.
ApartfromOracletechnology,Davorhasgainedexpertiseindesignanddevelopmentofgeographicinformationsystemsforcollection,storage,transformation,analysis,andvisualizationofgeo-referenceddata.HeoriginallyworkedwithIntergraphtechnology,butlaterhisfocusmovedtoopensourceGIStechnologies,suchasGeoserverandOpenLayers.
DavorcurrentlyworksasasoftwarearchitectattheITdepartmentofCroatianCentralBank,designingsoftwaresolutionsforCroatianfinancialmarketdatacollectionandanalysis.
Iwanttothankmyparentsforthesupportthattheygavemeinchoosingmyeducationalpath,whichallowedmetofindajobthatisnotjustaroutine,butalsoasourceofsatisfactionandconstantchallenge.
Supportfiles,eBooks,discountoffers,andmoreForsupportfilesanddownloadsrelatedtoyourbook,pleasevisitwww.PacktPub.com.
DidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.com,andasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusat<[email protected]>formoredetails.
Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewsletters,andreceiveexclusivediscountsandoffersonPacktbooksandeBooks.
https://www2.packtpub.com/books/subscription/packtlib
DoyouneedinstantsolutionstoyourITquestions?PacktLibisPackt’sonlinedigitalbooklibrary.Here,youcansearch,access,andreadPackt’sentirelibraryofbooks.
Whysubscribe?FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,print,andbookmarkcontentOndemandandaccessibleviaawebbrowser
FreeaccessforPacktaccountholdersIfyouhaveanaccountwithPacktatwww.PacktPub.com,youcanusethistoaccessPacktLibtodayandview9entirelyfreebooks.Simplyuseyourlogincredentialsforimmediateaccess.
InstantupdatesonnewPacktbooksGetnotified!Findoutwhennewbooksarepublishedbyfollowing@PacktEnterpriseonTwitterorthePacktEnterpriseFacebookpage.
PrefaceHowmanyofuswouldbelievethatPL/SQLwasintroducedasascriptinglanguageforexecutingabunchofSQLscripts?Well,that’strue.Withthegrowingneedtobuildcomputationallogicandcondition-basedconstructs,andtomanageexceptionruleswithindatabases,OracleCorporationfirstreleasedPL/SQLalongwithOracleDatabaseVersion6.0withalimitedsetofcapabilities.Withinitscapacity,PL/SQLwascapableofcreatingprogramunitsthatcouldnotbestoredinsidethedatabase.Eventually,Oracle’sreleaseintheapplicationline,SQL*FormsversionV3.0,includedthePL/SQLengineandalloweddeveloperstoimplementtheapplicationlogicthroughprocedures.Backthen,PL/SQLusedtobepartofthetransactionprocessingoptioninOracle6andtheproceduraloptioninOracle7.Sincethetimeofitsingenuousbeginning,PL/SQLhasmaturedimmenselyasastandardfeatureofOracleDatabase.Ithasbeenenthusiasticallyreceivedbythedevelopercommunity,andthecreditgoestoitssupportforadvancedelementssuchasmodularprogramming,encapsulation,supportforobjectsandcollections,programoverloading,nativeanddynamicSQL,andexceptionhandling.
PL/SQLislooselyderivedfromAda(namedafterAdaLovelace,anEnglishmathematicianwhoisregardedasthefirstcomputerprogrammer),ahigh-levelprogramminglanguage,whichcomplieswiththeadvancedprogrammingelements.Buildingadatabasebackendforanapplicationdemandstheabilitytodesignthedatabasearchitecture,skillstocodecomplexbusinesslogics,andexpertiseinadministeringandprotectingthedatabaseenvironment.OneoftheprincipalreasonswhyPL/SQLisakeyenablerinthedevelopmentphaseisitstightintegrationwithOracle’sSQLlanguage.Inadditiontothis,itprovidesarichplatformforimplementingthebusinesslogicintheOracleDatabaselayerandstorethemasproceduresorfunctionsforsubsequentuse.Asaprocedurallanguage,PL/SQLprovidesadiverserangeofdatatypes,iterativeandcontrolconstructs,conditionalstatements,andexceptionhandlers.
Inastandardsoftwaredevelopmentspace,anOracledatabasedeveloperisexpectedtogetinvolvedinschemadesign;codebusinesslogicsontheserversidebyusingfunctions,procedures,orpackages;implementactionrulesbyusingtriggers;andsupportclient-sideprogramsinsettinguptheapplicationinterface.Whilebuildingtheserver-sidecode,developersshouldunderstandthattheircodecontributestotheapplication’sperformanceandscalability.Languagebasicsareexpectedtoberesilient,butwhilebuildingrobustandsecureapplicationsusingPL/SQL,developersmusttakeadvantageofbestpracticesandtrytouseadvancedlanguagefeatures.ThisbookfocusesontheadvancedfeaturesofPL/SQLvalidateduptothelatestOracleDatabase12c.
Learningbyexamplehasalwaysbeenawell-attestedapproachfordivingdeepintoaconcept.ThisbookwillenableyoutomasterthelatestenhancementsandnewfeaturesofOracleDatabase12c.Forefficientreading,youjusthavetobefamiliarwiththePL/SQLfundamentalssothatyoucanrelatetotheevolutionofanadvancedfeaturefromitsever-expandingroots.
ThisbookcloselyfollowstheoutlineoftheOracleUniversitycertification;thatis,the
OracleCertifiedAdvancedPL/SQLDeveloperProfessional(1Z0-146)exam.Oneofthemostsoughtaftercertificationsinthedevelopercommunity,the1Z0-146certification’sobjectivesarequitecomprehensive,andtouchuponthevariousprogressiveareasofPL/SQL.Tonameafew,PL/SQLcodeperformance,maintenance,bulkprocessingtechniques,PL/SQLcollections,securityimplementation,andthehandlingoflargeobjects.Forcertificationaspirants,thisbookwillserveasaone-stopexamguide.Atmanystages,thisbookgoesbeyondthecertificationobjectivesandattemptstobuildadeepunderstandingoftheconcepts.Therefore,mid-leveldatabasedeveloperswillfindthisbookahandylanguagereferenceandwouldbekeentohaveitontheirbookshelves.
Mylastworkonthesamesubjectwillremainclosetomyheart,butthisoneisstraightfrommyexperience.IhopethatthisbookwillhelpyouimproveyourPL/SQLdevelopmentskillsandgainconfidenceinusingadvancedfeatures,alongwithmeticulousfamiliarizationofOracleDatabase12c.
“Theonlyrealsecuritythatamancanhaveintheworldisareserveofknowledge,experienceandability”
—HenryFord
WhatthisbookcoversChapter1,OverviewofPL/SQLProgrammingConcepts,providesanoverviewofPL/SQLfundamentals.Itrefreshesthebasicconcepts,suchasPL/SQLlanguagefeatures,theanonymousblockstructure,exceptionhandling,andstoredsubprograms.
Chapter2,Oracle12cSQLandPL/SQLNewFeatures,talksaboutthenewfeaturesofOracleDatabase12c.ItstartswiththeideaofconsolidationofdatabasesonacloudandhowtheOracle12cMultitenantarchitectureaddressestherequirements.ItconsolidatesthenewfeaturesinOracle12cSQLandPL/SQL,andexplainseachofthemwithexamples.ItwillhelpyoutofeeltheessenceofOracleDatabase12candunderstandwhatthedrivingwheelofinnovationis.AsectionontheOracleDatabase12cIn-memoryoptionwillfamiliarizeyouwiththebreakthroughfeatureintheanalyticsandwarehousespace.
Chapter3,DesigningPL/SQLCode,primarilyfocusesonthePL/SQLcursor’sdesignandhandling.Youwillgettolearnthebasicsofcursordesign,cursortypesandcursorvariables,handlingcursorsinPL/SQL,anddesignguidelines.ThischapterwillalsoincludetheenhancementsmadebyOracleDatabase12cwithrespecttocursors.
Chapter4,UsingCollections,introducesyoutotheworldofcollections;namely,associativearrays,nestedtables,andvarrays.TakingyouallthewayfromtheircreationinSQLandPL/SQLtodesignconsiderations,thischaptermakesyouwiseenoughtochoosetherightcollectiontypeinagivensituation.AsectiononOracleDatabase12cenhancementstocollectionsintroducesaveryhandyfeaturethatwillallowyoutojoinatableandcollection.
Chapter5,UsingAdvancedInterfaceMethods,focusesonapowerfulfeatureofPL/SQL:howtoexecuteexternalproceduresinPL/SQL.YouwilllearnandunderstandthespecificsofexecutingaCorJavaprograminPL/SQLasanexternalprocedurethroughstep-by-stepdemonstration.ThischapteralsomentionstheOracleDatabase12cenhancementwhichallowsyoutosecureexternalproceduresthroughanadditionalsafetynet.
Chapter6,VirtualPrivateDatabase,providesadetailedoverviewoftheOracleDatabaseSecurityDefense-in-deptharchitectureandfocusesononeofthedeveloper-centricfeatures,knownastheVirtualPrivateDatabase.OracleDatabase12csecurityenhancementsandademonstrationofdataredactionwillmakeyouunderstandOracle’ssecurityofferings.
Chapter7,OracleSecureFiles,providesathoroughunderstandingofhandlinglargeobjectsinOracleandfocusesonstorageoptimizationsmadebySecureFiles.IntroducedinOracle11g,SecureFilesisthenewstoragemechanismthatscoreshighonitsadvancedfeatures,suchascompression,encryption,anddeduplication.ThischapteralsohelpsyouwiththerecommendedmigrationmethodsfromolderLOBstoSecureFiles.
Chapter8,TuningthePL/SQLCode,introducesthebestpracticesfortuningPL/SQLcode.ItstartswiththePL/SQLoptimizerandrollsthroughthebenefitsofnative
compilation,PL/SQLcodewritingskills,andcodeevaluationdesign.ThischapterincludesthechangesinOracle12cwithrespecttolargeobjecthandling.
Chapter9,ResultCache,explainstheresultcachingfeatureinOracleDatabase.ItisapowerfulcachingmechanismthatenhancestheperformanceofSQLqueriesandPL/SQLfunctionsthatarerepeatedlyexecutedontheserver.ThischapteralsodiscussestheenhancementsmadetothefeatureinOracleDatabase12c.
Chapter10,Analyzing,Profiling,andTracingPL/SQLCode,detailsthetechniquesusedtoanalyze,profile,andtracePL/SQLcode.IfyouaretroubleshootingPL/SQLcodeforperformance,youmustlearntheprofilingandtracingtechniques.Inanenterpriseapplicationenvironment,thesepracticesarevitalweaponsinadeveloper’sarsenal.
Chapter11,SafeguardingPL/SQLCodeagainstSQLinjection,describeswaystoprotectyourPL/SQLfrombeingattacked.Avulnerablepieceofcodeispronetomaliciousattacksandrunstheriskofgivingawaysensitiveinformation.Efficientcodewritingandproofingthecodefromexternalattackscanhelptominimizingtheattacksurfacearea.Inthischapter,youwilllearnthepracticesforsafeguardingyourcodeagainstexternalthreats.
Chapter12,WorkingwithOracleSQLDeveloper,describesthebenefitsoftheOracleSQLDeveloperfordevelopers,databaseadministrators,andarchitects.ThischapternotonlyhelpsyougetstartedwithSQLDeveloper,butalsohelpsyougainabetterunderstandingofthenewfeaturesofSQLDeveloper4.0and4.1.
WhatyouneedforthisbookIfyouaregoodwithPL/SQLdevelopmentbasics,I’msureyouwillenjoyreadingthisbook.YouwilllearnnewwaystoprogramefficientlyinPL/SQL.
WhothisbookisforThisbookisforOracledeveloperswhoareresponsiblefordatabasemanagement.ReadersareexpectedtohavebasicknowledgeoftheOracleDatabaseandthefundamentalsofPL/SQLprogramming.Certificationaspirantscanusethisbooktoprepareforthe1Z0-146examinationinordertobecomeanOracleCertifiedProfessionalinAdvancedPL/SQL.
ConventionsInthisbook,youwillfindanumberofstylesoftextthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestyles,andanexplanationoftheirmeaning.
Codewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:“ThemodifiedSELECTqueryisthenexecutedintheHRschemaofthedatabase.”
Ablockofcodeissetasfollows:
/*Createthestoredproceduretosetthecontextattribute*/
CREATEORREPLACEPROCEDUREp_app_context(p_valVARCHAR2)
IS
BEGIN
/*CreateanamespaceDEMO_CONTEXT*/
DBMS_SESSION.SET_CONTEXT(
NAMESPACE=>'DEMO_CONTEXT',
ATTRIBUTE=>'COUNTRY',
VALUE=>P_VAL);
END;
/
Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,inmenusordialogboxesforexample,appearinthetextlikethis:“Thisishowinterpretedcompilationworks.Inthecaseofnativecompilation,,asharabledynamiclinkedlibrary(DLL)isgeneratedinsteadofamachinecode.”
NoteWarningsorimportantnotesappearinaboxlikethis.
TipTipsandtricksappearlikethis.
ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook—whatyoulikedormayhavedisliked.Readerfeedbackisimportantforustodeveloptitlesthatyoureallygetthemostoutof.
Tosendusgeneralfeedback,simplysendane-mailto<[email protected]>,andmentionthebooktitleviathesubjectofyourmessage.
Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,seeourauthorguideonwww.packtpub.com/authors.
CustomersupportNowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelpyoutogetthemostfromyourpurchase.
DownloadingtheexamplecodeYoucandownloadtheexamplecodefilesforallPacktbooksyouhavepurchasedfromyouraccountathttp://www.packtpub.com.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.
ErrataAlthoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyoufindamistakeinoneofourbooks—maybeamistakeinthetextorthecode—wewouldbegratefulifyouwouldreportthistous.Bydoingso,youcansaveotherreadersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufindanyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata,selectingyourbook,clickingontheerratasubmissionformlink,andenteringthedetailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedandtheerratawillbeuploadedonourwebsite,oraddedtoanylistofexistingerrata,undertheErratasectionofthattitle.Anyexistingerratacanbeviewedbyselectingyourtitlefromhttp://www.packtpub.com/support.
PiracyPiracyofcopyrightmaterialontheInternetisanongoingproblemacrossallmedia.AtPackt,wetaketheprotectionofourcopyrightandlicensesveryseriously.Ifyoucomeacrossanyillegalcopiesofourworks,inanyform,ontheInternet,pleaseprovideuswiththelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy.
Pleasecontactusat<[email protected]>withalinktothesuspectedpiratedmaterial.
Weappreciateyourhelpinprotectingourauthors,andourabilitytobringyouvaluablecontent.
QuestionsYoucancontactusat<[email protected]>ifyouarehavingaproblemwithanyaspectofthebook,andwewilldoourbesttoaddressit.
Chapter1.OverviewofPL/SQLProgrammingConceptsStructuredQueryLanguage(SQL)isalanguagethathasbeenwidelyacceptedandadoptedforaccessingrelationaldatabases.Thislanguageallowsuserstoperformdatabaseoperationssuchasreading,creating,modifying,anddeletingthedata.Sincethesummerof1970,whenDr.E.F.CoddpublishedthepaperARelationalModelofDataforLargeSharedDataBanksfortheACMjournal,thelanguagehasmaturedcomprehensivelyasanindustrystandard.Withitsbroadrangeoffeaturesandeasyadaptationtoenterpriseenvironments,theSQLlanguagehasbeentypicallyregardedasthemostreliablelanguageforinteractingwithrelationaldatabases.
PL/SQLwasdevelopedin1991byOracleCorporationasaprocedurallanguageextensiontoSQL.ItsabilitytointegrateseamlesslywithSQLmakesitapowerfullanguagetoconstructthedataaccesslayerandtherichproceduralextensionshelpintranslatingbusinesslogicwithintheOracleDatabase.ThisfirstchapterintroducesyoutothePL/SQLlanguageandrefreshessomeofthekeyprogrammingconcepts.Thechapterisoutlinedasfollows:
IntroductiontoPL/SQLRecapitulateprocedures,functions,packages,andcursorsExceptionhandlingObjectdependenciesMajorOraclesuppliedpackagesOracleDevelopmenttools—SQLDeveloperandSQL*Plus
IntroductiontoPL/SQLPL/SQLstandsforProceduralLanguage-StructuredQueryLanguage(PL/SQL).ItispartoftheOracleDatabaseproduct,whichmeansnoseparateinstallationisrequired.Itiscommonlyusedtotranslatebusinesslogicinthedatabaseandexposetheprograminterfacelayertotheapplication.WhileSQLispurelyadataaccesslanguagethatdirectlyinteractswiththedatabase,PL/SQLisaprogramminglanguageinwhichmultipleSQLsandproceduralstatementscanbegroupedinaprogramunit.PL/SQLcodeisportablebetweenOracleDatabases(subjecttolimitationsimposedbyversions).Thebuilt-indatabaseoptimizerrefactorsthecodetoimprovetheexecutionperformance.
TheadvantagesofPL/SQLasalanguageareasfollows:
PL/SQLsupportsalltypesofSQLstatements,datatypes,staticSQL,anddynamicSQLPL/SQLcoderunsonallplatformssupportedbytheOracleDatabasePL/SQLcodeperformancecanbeimprovedbytheuseofbindvariablesindirectSQLqueriesPL/SQLsupportstheobject-orientedmodeloftheOracleDatabasePL/SQLapplicationsincreasescalabilitybyallowingmultipleuserstoinvokethesameprogramunit
Althoughitisnotusedtobuilduserinterfaces,itprovidestheopportunitytobuildrobust,secure,andportableinterfacelayers,whichcanbeexposedtoahigh-levelprogramminglanguage.SomeofthekeyfacultiesofPL/SQL(PL/SQLaccomplishments)arelistedhere:
Aprocedurallanguage:APL/SQLprogramcanincludealistofoperationsthatcanexecutesequentiallytogetthedesiredresult.UnlikeSQL,whichisjustadeclarativelanguage,PL/SQLaddsselectiveanditerativeconstructstoit.Databaseprogramminglanguage:Serversideprogramsrunfasterthanthemiddle-tierprograms.Codemaintenancebecomeseasyasitneedstobere-writtenlessfrequently.Anintegrallanguage:ApplicationdeveloperscaneasilyintegrateaPL/SQLprogramwithotherhigh-levelprogramminginterfacessuchasJava,C++,or.NET.ThePL/SQLproceduresorsubprogramscanbeinvokedfromclientprogramsasexecutablestatements.
PL/SQLprogramfundamentalsAwell-writtenPL/SQLprogramshouldbeabletoanswerthefollowingfundamentalquestions:
HowdowehandleanSQLexecutionintheprogram?Howdowehandletheproceduralexecutionflowintheprogram?Doestheprogramhandletheexceptions?Howdowemaintain(traceanddebug)thePL/SQLprogramcode?
Well,therearemultipletipsandtechniquestostandardizePL/SQLcodingpractices.Butbeforewedrilldowntotheprogrammingskills,letusfamiliarizeourselveswiththestructureofaPL/SQLprogram.APL/SQLprogramcanbebrokendownintofoursections.Eachsectioncarriesaspecificobjectiveandmustexistinthesamesequenceinaprogram.Letushaveabrieflookatthesections:
Header:Thisisanoptionalsectionwhichisrequiredfornamedblockssuchasprocedures,functions,andtriggers.Itcontainstheprogramname,theprogram’sowner,andtheparameterspecification.Declaration:Thisisanoptionalsectionusedtodeclarelocalvariables,cursors,andlocalsubprogramsthatarelikelytobeusedintheprogrambody.TheDECLAREkeywordindicatesthebeginningofthedeclarationsection.ThesectioncanbeskippedifthePL/SQLprogramusesnovariables.Execution:Thisistheproceduralsectionoftheprogramandcomprisesthemainprogrambodyandanexceptionsection.TheBEGINandENDkeywordsindicatethebeginningandendoftheprogrambody.Itmustcontainatleastoneexecutablestatement.Duringblockexecution,thesestatementsareparsedandsequentiallyexecutedbythePL/SQLengine.Exception:Thisisanoptionalsectionintheprogrambodythatcontainsasetofinstructionsasproceduralstatements,forvariouserrors,thatmayoccurintheprogramleadingtoabnormaltermination.Theprogramcontrollandsintotheexceptionsectionandtheappropriateexceptionhandlerisexecuted.TheEXCEPTIONkeywordindicatesthestartoftheexceptionsection.
ThefollowingblockdiagramshowsthestructureofaPL/SQLblock:
APL/SQLblockistheelementaryunitofaprogramthatgroupsasetofproceduralstatements.BasedonthesectionsincludedinaPL/SQLprogramunit,wecanclassifyaprogramunderfollowingcategories:
AnonymousPL/SQLblock:ThisisthesimplestPL/SQLprogramthathasnoname,buthasitsDECLARE-BEGIN-ENDskeleton.ItcaneitherberunforcurrentexecutionasstandaloneblockorembeddedlocallywithinaPL/SQLprogramunit.Ananonymousblockcannotbestoredinthedatabase.Named:ThisblockisanamedPL/SQLroutinethatisstoredpersistentlyinthedatabaseasaschemaobject.Itcanbeinvokedeitherfromadatabasesessionorbyanotherprogramunit.AnamedPL/SQLprogramcanbeafunction,procedure,trigger,orpackage.Nested:AblockwithinanotherPL/SQLblockformsanestedblockstructure.
So,let’sgetstartedwithourfirstanonymousPL/SQLblock.Theblockdeclaresastringanddisplaysitonscreen.Notethateachlineintheprogramendswithasemi-colonandtheblockendswithaslash(/)forcodeexecution.
/*EnabletheServeroutputtodisplayblockmessages*/
SETSERVEROUTPUTON
NoteTheSERVEROUTPUTparameterisaSQL*Plusvariablethatenablestheprintingof
DBMS_OUTPUTmessagesfromaPL/SQLblock.
/*StartthePL/SQLblock*/
DECLARE
/*Declarealocalvariableandinitializewithadefaultvalue*/
L_STRVARCHAR2(50):='IamnewtoPL/SQL';
BEGIN
/*Printtheresult*/
DBMS_OUTPUT.PUT_LINE('ISaid-'||L_STR);
END;
/
ISaid-IamnewtoPL/SQL
PL/SQLproceduresuccessfullycompleted.
Cursors–anoverviewWritingSQLinPL/SQLisoneofthecriticalpartsofdatabaseprogramming.AllSQLstatementsembeddedwithinaPL/SQLblockareexecutedasacursor.Acursorisaprivatememoryarea,temporarilyallocatedinthesession’sUserGlobalArea(UGA),thatisusedforprocessingSQLstatements.TheprivatememorystorestheresultsetretrievedfromtheSQLexecutionandcursorattributes.Cursorscanbeclassifiedasimplicitandexplicitcursors.
OraclecreatesanimplicitcursorforalltheSQLstatementsincludedintheexecutablesectionofaPL/SQLblock.Inthiscase,thecursorlifecycleismaintainedbytheOracleDatabase.
Forexplicitcursors,theexecutioncyclecanbecontrolledbytheuser.DatabasedeveloperscanexplicitlydeclareanimplicitcursorundertheDECLAREsectionalongwithaSELECTquery.
ThecursorexecutioncycleAcursormovesthroughthefollowingstagesduringexecution.Notethat,inthecaseofanimplicitcursor,allthestepsarecarriedoutbytheOracleDatabase.Let’stakeaquicklookattheexecutionstagesOPEN,FETCH,andCLOSE.
TheOPENstageallocatesthecontextareainthesession’sUserGlobalAreaforperformingSQLprocessing.TheSQLprocessingstartswithparsingandbinding,followedbystatementexecution.InthecaseoftheSELECTquery,therecordpointerpointstothefirstrecordintheresultset.TheFETCHstagepullsthedatafromthequeryresultset.Iftheresultsetisamulti-recordset,therecordpointermovesincrementallywitheveryfetch.Thefetchstageisaliveuntilthelastrecordisreachedintheresultset.TheCLOSEstageclosesthecursor,flushesthecontextarea,andreleasesthememorybacktotheUGA.
CursorattributesCursorattributesholdtheinformationaboutthecursorprocessingateachstageofitsexecution:
%ROWCOUNT:NumberofrowsfetcheduntilthelastfetchorimpactedbythelastDMLoperation.ApplicableforSELECTaswellasDMLstatements.%ISOPEN:BooleanTRUEifthecursorisstillopen,ifnotFALSE.Foranimplicitcursor,thisattributeisalwaysFALSE.%FOUND:BooleanTRUE,ifthefetchoperationswitchesandpointstoarecord;ifnot,FALSE.%NOTFOUND:BooleanFALSEwhenthecursorpointerswitchesbutdoesnotpointtoarecordintheresultset.
Note%ISOPENistheonlycursorattributethatisaccessibleoutsidethecursorexecutioncycle.
Thefollowingprogramusesthecursorattributes%ISOPEN,%NOTFOUND,and%ROWCOUNTtofetchthedatafromtheEMPtableanddisplayit:
/*EnabletheSERVEROUTPUTtodisplayblockmessages*/
SETSERVEROUTPUTON
/*StartthePL/SQLBlock*/
DECLARE
/*Declareacursortoselectemployeesdata*/
CURSORC_EMPIS
SELECTEMPNO,ENAME
FROMEMP;
L_EMPNOEMP.EMPNO%TYPE;
L_ENAMEEMP.ENAME%TYPE;
BEGIN
/*Checkifthecursorisalreadyopen*/
IFNOTC_EMP%ISOPENTHEN
DBMS_OUTPUT.PUT_LINE('***DisplayingEmployeeInfo***');
ENDIF;
/*Openthecursoranditerateinaloop*/
OPENC_EMP;
LOOP
/*Fetchthecursordataintolocalvariables*/
FETCHC_EMPINTOL_EMPNO,L_ENAME;
EXITWHENC_EMP%NOTFOUND;
/*Displaytheemployeeinformation*/
DBMS_OUTPUT.PUT_LINE(chr(10)||'DisplayInformationfor
employee:'||C_EMP%ROWCOUNT);
DBMS_OUTPUT.PUT_LINE('EmployeeId:'||L_EMPNO);
DBMS_OUTPUT.PUT_LINE('EmployeeName:'||L_ENAME);
ENDLOOP;
END;
/
***DisplayingEmployeeInfo***
DisplayInformationforemployee:1
EmployeeId:7369
EmployeeName:SMITH
DisplayInformationforemployee:2
EmployeeId:7499
EmployeeName:ALLEN
DisplayInformationforemployee:3
EmployeeId:7521
EmployeeName:WARD
DisplayInformationforemployee:4
EmployeeId:7566
EmployeeName:JONES
….
PL/SQLproceduresuccessfullycompleted.
CursorFORloopLoopingthroughalltherecordsofacursorobjectcanbefacilitatedwiththeuseoftheFORloop.AFORloopopeningacursordirectlyisknownasaCURSORFORloop.TheusageoftheCURSORFORloopreducestheoverheadofmanuallyspecifyingtheOPEN,FETCH,andCLOSEstagesofacursor.
TheCURSORFORloopwillbestcompactthecodewhenworkingwithmulti-rowexplicitcursors.ThefollowingPL/SQLblockdemonstratesthepurpose:
/*EnabletheSERVEROUTPUTparametertoprinttheresultsinthe
environment*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declareanexplicitcursortoselectemployeeinformation*/
CURSORCUR_EMPIS
SELECTename,sal
FROMemp;
BEGIN
/*FORLoopusesthecursorCUR_EMPdirectly*/
FOREMPINCUR_EMP
LOOP
/*Displaymessage*/
DBMS_OUTPUT.PUT_LINE(EMP.ename||'earns'||EMP.sal||'permonth');
ENDLOOP;
END;
/
SMITHearns800permonth
ALLENearns1600permonth
WARDearns1250permonth
JONESearns2975permonth
MARTINearns1250permonth
BLAKEearns2850permonth
CLARKearns2450permonth
SCOTTearns3000permonth
KINGearns5000permonth
TURNERearns1500permonth
ADAMSearns1100permonth
JAMESearns950permonth
FORDearns3000permonth
MILLERearns1300permonth
PL/SQLproceduresuccessfullycompleted.
Notethat,withtheCURSORFORloop,youdonotneedtodeclaretheblockvariablestocapturethecursorcolumns.TheCURSORFORloopindeximplicitlyactsasarecordofthecursortype.Also,youdonotneedtoexplicitlyopenorclosethecursorinthePL/SQLprogram.
ExceptionhandlinginPL/SQLIfaprogramshowsanunusualandunexpectedflowduringruntime,whichmightresultinabnormalterminationoftheprogram,thesituationissaidtobeanexception.SucherrorsmustbetrappedandhandledintheEXCEPTIONsectionofthePL/SQLblock.Theexceptionhandlerscansuppresstheabnormalterminationwithanalternativeandsecuredaction.
Exceptionhandlingisoneoftheimportantstepsofdatabaseprogramming.Unhandledexceptionscanresultinunplannedapplicationoutages,impactbusinesscontinuity,andfrustrateendusers.
Therearetwotypesofexceptions—system-definedanduser-defined.WhiletheOracleDatabaseimplicitlyraisesasystem-definedexception,auser-definedexceptionisexplicitlydeclaredandraisedwithintheprogramunit.
Inaddition,Oracleprovidestwoutilityfunctions,SQLCODEandSQLERRM,toretrievetheerrorcodeandmessageforthemostrecentexception.
System-definedexceptionsAsthenameimplies,system-definedexceptionsaredefinedandmaintainedimplicitlybytheOracleDatabase.TheyaredefinedintheOracleSTANDARDpackage.Wheneveranexceptionoccursinsideaprogram,thedatabasepicksuptheappropriateexceptionfromtheavailablelist.Allsystem-definedexceptionsareassociatedwithanegativeerrorcode(except1to100)andashortname,whichisusedwhilespecifyingtheexceptionhandlers.
Forexample,thefollowingPL/SQLprogramincludesaSELECTstatementtoselectdetailsofemployee8376.ItraisesNO_DATA_FOUNDexceptionbecauseemployeeid8376doesn’texist.
SETSERVEROUTPUTON
/*DeclarethePL/SQLblock*/
DECLARE
L_ENAMEVARCHAR2(100);
L_SALNUMBER;
L_EMPIDNUMBER:=8376;
BEGIN
/*WriteaSELECTstatement*/
SELECTENAME,SAL
INTOL_ENAME,L_SAL
FROMEMP
WHEREEMPNO=L_EMPID;
END;
/
DECLARE
*
ERRORatline1:
ORA-01403:nodatafound
ORA-06512:atline8
LetusrewritetheprecedingPL/SQLblocktoincludeanEXCEPTIONsectionandhandletheNO_DATA_FOUNDexception:
/*EnabletheSERVEROUTPUTparametertoprinttheresultsinthe
environment*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarethelocalvariables*/
L_ENAMEVARCHAR2(100);
L_SALNUMBER;
L_EMPIDNUMBER:=8376;
BEGIN
/*SELECTstatementtofetchthenameandsalarydetailsofthe
employee*/
SELECTENAME,SAL
INTOL_ENAME,L_SAL
FROMEMP
WHEREEMPNO=L_EMPID;
EXCEPTION
/*ExceptionHandler*/
WHENNO_DATA_FOUNDTHEN
/*Displayaninformativemessage*/
DBMS_OUTPUT.PUT_LINE('NoEmployeeexistswiththeid'||L_EMPID);
END;
/
NoEmployeeexistswiththeid8376
PL/SQLproceduresuccessfullycompleted.
Thefollowingtablelistssomeofthecommonlyusedsystem-definedexceptionsalongwiththeirshortnameandORAerrorcode:
Error Namedexception Comments(raisedwhen:)
ORA-00001 DUP_VAL_ON_INDEX Duplicatevalueexists
ORA-01001 INVALID_CURSOR Cursorisinvalid
ORA-01012 NOT_LOGGED_ON Userisnotloggedin
ORA-01017 LOGIN_DENIED Systemerroroccurred
ORA-01403 NO_DATA_FOUND Thequeryreturnsnodata
ORA-01422 TOO_MANY_ROWS Asinglerowqueryreturnsmultiplerows
ORA-01476 ZERO_DIVIDE Anattemptwasmadetodivideanumberbyzero
ORA-01722 INVALID_NUMBER Thenumberisinvalid
ORA-06504 ROWTYPE_MISMATCH Mismatchoccurredinrowtype
ORA-06511 CURSOR_ALREADY_OPEN Cursorisalreadyopen
ORA-06531 COLLECTION_IS_NULL WorkingwithNULLcollection
ORA-06532 SUBSCRIPT_OUTSIDE_LIMIT Collectionindexoutofrange
ORA-06533 SUBSCRIPT_BEYOND_COUNT Collectionindexoutofcount
User-definedexceptionsOracleallowsuserstocreatecustomexceptions,specifynames,associateerrorcodes,andraisestatementsinlinewiththeimplementationlogic.IfPL/SQLapplicationsarerequiredtostandardizetheexceptionhandling,notjusttocontroltheabnormalprogramflowbutalsotoaltertheprogramexecutionlogic,youneedtouseuser-definedexceptions.Theuser-definedexceptionsareraisedintheBEGIN..ENDsectionoftheblockusingtheRAISEstatement.
Therearethreewaysofdeclaringuser-definedexceptions:
DeclaretheEXCEPTIONtypevariableinthedeclarationsection.RaiseitexplicitlyintheprogrambodyusingtheRAISEstatement.HandleitintheEXCEPTIONsection.Notethatnoerrorcodeisinvolvedhere.DeclaretheEXCEPTIONvariableandassociateitwithastandarderrornumberusingPRAGMAEXCEPTION_INIT.
NoteAPragmaisadirectivetothecompilertomanipulatethebehavioroftheprogramunitduringcompilation,andnotatthetimeofexecution.
PRAGMAEXCEPTION_INITcanalsobeusedtomapanexceptiontoanon-predefinedexception.ThesearestandarderrorsfromOraclebutnotdefinedasPL/SQLexceptions.
UsetheRAISE_APPLICATION_ERRORtodeclareadedicatederrornumberanderrormessage.
ThefollowingPL/SQLblockdeclaresauser-definedexceptionandraisesitintheprogrambody:
/*EnabletheSERVEROUTPUTparametertoprinttheresultsinthe
environment*/
SETSERVEROUTPUTON
/*DeclareabindvariableM_DIVISOR*/
VARIABLEM_DIVISORNUMBER;
/*DeclareabindvariableM_DIVIDEND*/
VARIABLEM_DIVIDENDNUMBER;
/*AssignvaluetoM_DIVISORaszero*/
EXEC:M_DIVISOR:=0;
PL/SQLproceduresuccessfullycompleted.
/*AssignvaluetoM_DIVIDENDas10/
EXEC:M_DIVIDEND:=10;
PL/SQLproceduresuccessfullycompleted.
/*StartthePL/SQLblock*/
DECLARE
/*Declarethelocalvariablesandinitializewiththebindvariables*/
L_DIVISORNUMBER:=:M_DIVISOR;
L_DIVIDENDNUMBER:=:M_DIVIDEND;
L_QUOTNUMBER;
/*Declareanexceptionvariable*/
NOCASEEXCEPTION;
BEGIN
/*RaisetheexceptionifDivisorisequaltozero*/
IFL_DIVISOR=0THEN
RAISENOCASE;
ENDIF;
L_QUOT:=L_DIVIDEND/L_DIVISOR;
DBMS_OUTPUT.PUT_LINE('Theresult:'||L_QUOT);
EXCEPTION
/*ExceptionhandlerforNOCASEexception*/
WHENNOCASETHEN
DBMS_OUTPUT.PUT_LINE('Divisorcannotbeequaltozero');
END;
/
Divisorcannotbeequaltozero
PL/SQLproceduresuccessfullycompleted.
/*AssignanonzerovaluetoM_DIVISOR*/
EXEC:M_DIVISOR:=2;
PL/SQLproceduresuccessfullycompleted.
/*Re-executetheblock*/
SQL>/
Theresult:5
PL/SQLproceduresuccessfullycompleted.
TheRAISE_APPLICATION_ERRORprocedureTheRAISE_APPLICATION_ERRORisanOracle-suppliedprocedurethatraisesauser-definedexceptionwithacustomexceptionmessage.Theexceptioncanbeoptionallypre-definedinthedeclarativesectionofthePL/SQL.
ThesyntaxfortheRAISE_APPLICATION_ERRORprocedureisasfollows:
RAISE_APPLICATION_ERROR(error_number,error_message[,{TRUE|FALSE}])
Inthissyntax,theerror_numberparameterisamandatoryparameterwiththeerrorvaluerangingbetween20000to20999.error_messageistheuser-definedmessagethatappearsalongwiththeexception.Thelastparameterisanoptionalargumentthatisusedtoaddtheexceptionerrorcodetothecurrenterrorstack.
ThefollowingPL/SQLprogramliststheemployeeswhohavejoinedtheorganizationafterthegivendate.Theprogrammustraiseanexceptionifthedateofjoiningisbeforethegivendate.TheblockusesRAISE_APPLICATION_ERRORtoraisetheexceptionwithanerrorcode20005,andanappropriateerrormessageappearsonthescreen:
/*EnabletheSERVEROUTPUTparametertoprinttheresultsinthe
environment*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarethebirthdate*/
L_DOB_MONDATE:='01-DEC-1981';
/*Declareacursortofilteremployeeswhowerehiredonbirthdaymonth*/
CURSORCIS
SELECTempno,ename,hiredate
FROMemp;
BEGIN
FORIINC
LOOP
/*Raiseexception,ifbirthdateislaterthanthehiredate*/
IFi.hiredate<l_dob_monTHEN
RAISE_APPLICATION_ERROR(-20005,'Hiredateearlierthanthegiven
date!!Checkforanotheremployee');
ELSE
DBMS_OUTPUT.PUT_LINE(i.ename||'washiredon'||i.hiredate);
ENDIF;
ENDLOOP;
END;
/
*
ERRORatline1:
ORA-20005:Hiredateearlierthanthegivendate!!Checkforanother
employee
ORA-06512:atline11
Intheprecedingexample,notethattheexceptionnameisnotusedtocreatetheexceptionhandler.JustaftertheexceptionisraisedthroughRAISE_APPLICATION_ERROR,theprogramisterminated.
IfyouwishtohaveaspecificexceptionhandlerfortheexceptionsraisedthroughRAISE_APPLICATION_ERROR,youmustdeclaretheexceptioninthedeclarativesectionandassociatetheerrornumberusingPRAGMAEXCEPTION_INIT.CheckthefollowingPL/SQLprogram:
/*EnabletheSERVEROUTPUTparametertoprinttheresultsinthe
environment*/
SQL>SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarethebirthdate*/
L_DOB_MONDATE:='01-DEC-1981';
/*Declaretheexceptionvariable*/
INVALID_EMP_DATESEXCEPTION;
PRAGMAEXCEPTION_INIT(INVALID_EMP_DATES,-20005);
/*Declareacursortofilteremployeeswhowerehiredonbirthdaymonth*/
CURSORCIS
SELECTename,deptno,hiredate
FROMemp;
BEGIN
FORIINC
LOOP
/*Raiseexception,ifbirthdateislaterthanthehiredate*/
IFi.hiredate<l_dob_monTHEN
RAISEINVALID_EMP_DATES;
ELSE
DBMS_OUTPUT.PUT_LINE(i.ename||'washiredon'||i.hiredate);
ENDIF;
ENDLOOP;
EXCEPTION
WHENINVALID_EMP_DATESTHEN
DBMS_OUTPUT.PUT_LINE(SQLERRM||'Hiredateearlierthanthegivendate!!
Checkforanotheremployee');
END;
/
ORA-20005:Hiredateearlierthanthegivendate!!Checkforanother
employee
PL/SQLproceduresuccessfullycompleted.
ExceptionpropagationUntilnow,wehaveseenthat,assoonastheexceptionisraisedintheproceduralsectionofaPL/SQLblock,thecontroljumpstotheexceptionsectionandchoosestheappropriateexceptionhandler.Thenon-existenceoftheexceptionhandlermayleadtotheabnormalterminationoftheprogram.
InthecaseofnestedPL/SQLblocks,iftheexceptionisraisedinaninnerblock,theprogramcontrolflowsdowntotheexceptionsectionoftheinnerblock.Iftheinnerblockhandlestheexception,itisexecutedandtheprogramcontrolreturnstothenextexecutablestatementintheouterblock.
Iftheinnerblockdoesnothandletheexception,theprogramcontrolcontinuestosearchfortheappropriatehandlerandpropagatestotheexceptionsectionoftheouterblock.Yes,theexecutionoftheouterblockisskippedandtheprogramcontrollandsstraightintotheexceptionsection.Theprogramcontrolwillcontinuetopropagatetheunhandledexceptionintheouterblocksuntiltheappropriateoneisfoundandhandled.
Forexample,thefollowingPL/SQLprogramcontainsachildblockwithintheparentblock:
/*Parentblock*/
DECLARE…
BEGIN
/*Outerblockexecutablestatements*/
...
/*ChildBlock*/
DECLARE
...
BEGIN
...
/*Innerblockexecutablestatements*/
...
EXCEPTION
/*Innerblockexceptionhandlers*/
END;
...
/*Outerblockexecutablestatements*/
EXCEPTION
/*Outerblockexceptionhandlers*/
END;
Iftheexceptionisraisedinoneofthe/*Innerblockexecutablestatements*/,thecontrolflowsto/*Innerblockexceptionhandlers*/.Iftheappropriateexceptionhandlerisnotfound,itpropagatesstraighttothe/*Outerblockexceptionhandlers*/andexecutionof/*Outerblockexecutablestatements*/isskipped.
WhenworkingwithnestedPL/SQLblocks,developersmustbecautiouswhilecodingexceptionhandlinglogic.Theexceptionpropagationshouldbethoroughlytestedtobuildfail‑proofapplications.
CreatingstoredproceduresAprocedureisaderivativeofaPL/SQLblockthathasanameandisstoredpersistentlywithinthedatabase.Itistheschemaobjectthatisprimarilyusedtoimplementbusinesslogicontheserverside.Aprocedurepromotesamodularprogrammingtechniquebybreakingdowncomplexlogicintosimpleroutines.
Thekeyfeaturesofstoredproceduresare:
AproceduremustbeinvokedfromtheexecutablesectionofaPL/SQLblockasaproceduralstatement.YoucanalsoexecuteitdirectlyfromSQLPLUSusingtheEXECUTEstatement.NotethataprocedurecannotbecalledfromaSELECTstatement.AprocedurecanoptionallyacceptparametersinIN,OUT,orINOUTmode.Aprocedurecannotreturnavalue.TheonlywayforaproceduretoreturnavalueisthroughOUTparameters,butnotthroughtheRETURN[value]statement.TheRETURNstatementinaprocedureisusedtoskipthefurtherexecutionoftheprogramandexitcontrol.
ThefollowingtabledifferentiatesbetweentheIN,OUT,andINOUTparameters:
IN OUT INOUT
Defaultparametermode Hastobeexplicitlydefined Hastobeexplicitlydefined
Parameter’svalueispassedtotheprogramfromthecallingenvironment
Parameterreturnsavaluebacktothecallingenvironment
Parametermaypassavaluefromthecallingenvironmenttotheprogramorreturnvaluetothecallingenvironment
Parametersarepassedbyreference
Parametersarepassedbyvalue Parametersarepassedbyvalue
Maybeaconstant,literal,orinitializedvariable Uninitializedvariable Initializedvariable
Canholddefaultvalue Defaultvaluecannotbeassigned Defaultvaluecannotbeassigned
Thesyntaxforaprocedureisasfollows:
CREATE[ORREPLACE]PROCEDURE[ProcedureName][ParameterList]
[AUTHIDDEFINER|CURRENT_USER]
IS
[DeclarationStatements]
BEGIN
[ExecutableStatements]
EXCEPTION
[Exceptionhandlers]
END[ProcedureName];
Thefollowingstandaloneprocedureconvertsthecaseoftheinputstringfromlowercasetouppercase:
/*Createaproceduretochangecaseofastring*/
CREATEORREPLACEPROCEDUREP_TO_UPPER(P_STRVARCHAR2)
IS
/*Declarethelocalvariables*/
L_STRVARCHAR2(50);
BEGIN
/*ConvertthecaseusingUPPERfunction*/
L_STR:=UPPER(P_STR);
/*Displaytheoutputwithappropriatemessage*/
DBMS_OUTPUT.PUT_LINE('InputstringinUppercase:'||L_STR);
END;
/
Procedurecreated.
ExecutingaprocedureAprocedurecaneitherbeexecutedfromSQL*PlusoraPL/SQLblock.TheP_TO_UPPERprocedurecanbeexecutedfromSQL*Plus.
ThefollowingcodeshowstheexecutionoftheprocedurefromSQL*Plus(notethattheparameterispassedusingbindvariable):
/*EnabletheSERVEROUTPUTparametertoprinttheresultsinthe
environment*/
SQL>SETSERVEROUTPUTON
/*Declareasessionvariablefortheinput*/
SQL>VARIABLEM_STRVARCHAR2(50);
/*Assignatestvaluetothesessionvariable*/
SQL>EXECUTE:M_STR:='MyfirstPLSQLprocedure';
PL/SQLproceduresuccessfullycompleted.
/*CalltheprocedureP_TO_UPPER*/
SQL>EXECUTEP_TO_UPPER(:M_STR);
InputstringinUppercase:MYFIRSTPLSQLPROCEDURE
PL/SQLproceduresuccessfullycompleted.
TheP_TO_UPPERprocedurecanbecalledasaproceduralstatementwithinananonymousPL/SQLblock:
/*EnabletheSERVEROUTPUTparametertoprinttheresultsinthe
environment*/
SQL>SETSERVEROUTPUTON
/*StartaPL/SQLblock*/
SQL>BEGIN
/*CalltheP_TO_UPPERprocedure*/
P_TO_UPPER('MyfirstPLSQLprocedure');
END;
/
InputstringinUppercase:MYFIRSTPLSQLPROCEDURE
PL/SQLproceduresuccessfullycompleted.
FunctionsSimilartoastoredprocedure,afunctionisanamedderivativeofaPL/SQLblockthatisphysicallystoredwithintheOracledatabaseschema.
Thekeyfeaturesofstoredfunctionsareasfollows:
Afunctioncanacceptparametersinallthreemodes(IN,OUT,andINOUT)andmandatorilyreturnsavalue.FunctionscanbecalledinSQLstatements(SELECTandDMLs).SuchfunctionsmustacceptonlyINparametersofvalidSQLtypes.Alternatively,afunctioncanalsobeinvokedfromSELECTstatementsifthefunctionbodyobeysthedatabasepurityrules.IfthefunctioniscalledfromanSQLstatement,itsreturntypeshouldbeavalidSQLdatatype.IfthefunctionisinvokedfromPL/SQL,thereturntypeshouldbeavalidPL/SQLtype.
NoteStartingfromOracleDatabase12c,PL/SQL—onlydatatypescancrossthePL/SQLtoSQLinterface.APL/SQLanonymousblockcaninvokeaPL/SQLsubprogramwithparametersofBOOLEANorapackagedcollectiontype.
Thesyntaxforafunctionisasfollows:
CREATE[ORREPLACE]FUNCTION[FunctionName][ParameterList]
RETURN[Datatype]
[AUTHIDDEFINER|CURRENT_USER]
[DETERMINISTIC|PARALLEL_ENABLED|PIPELINED]
[RESULT_CACHE[RELIES_ON(tablename)]]
IS
[DeclarationStatements]
BEGIN
[ExecutableStatements]
RETURN[Value]
EXCEPTION
[Exceptionhandlers]
END[FunctionName];
Letuscreateastandalonefunction,F_GET_DOUBLE,whichacceptsanumericparameterandreturnsitsdouble:
/*CreatethefunctionF_GET_DOUBLE*/
CREATEORREPLACEFUNCTIONF_GET_DOUBLE(P_NUMNUMBER)
RETURNNUMBER/*Specifythereturndatatype*/
IS
/*Declarethelocalvariable*/
L_NUMNUMBER;
BEGIN
/*Calculatethedoubleofthegivennumber*/
L_NUM:=P_NUM*2;
Functions–executionmethodsFunctionscaneitherbecalledfromaSQL*PlusenvironmentorinvokedfromaPL/SQLprogramasaproceduralstatement.
ThefunctionF_GET_DOUBLEcanbeexecutedintheSQL*Pluscommandpromptasfollows.Asthefunctionreturnsanoutput,youmustdeclareasessionvariableandcapturethefunctionresultinthevariable.
/*EnabletheSERVEROUTPUTparametertoprinttheresultsinthe
environment*/
SETSERVEROUTPUTON
/*DeclareasessionvariableM_NUMtoholdthefunctionoutput*/
VARIABLEM_NUMNUMBER;
/*Functionisexecutedandoutputisassignedtothesessionvariable*/
EXECUTE:M_NUM:=F_GET_DOUBLE(10);
PL/SQLproceduresuccessfullycompleted.
/*PrintthesessionvariableM_NUM*/
PRINTM_NUM
M_NUM
----------
20
TheF_GET_DOUBLEfunctioncanbecalledfromananonymousblockorastandalonesubprogram.
/*EnabletheSERVEROUTPUTparametertoprinttheresultsinthe
environment*/
SETSERVEROUTPUTON
DECLARE
M_NUMNUMBER;
BEGIN
M_NUM:=F_GET_DOUBLE(10);
DBMS_OUTPUT.PUT_LINE('Doubledtheinputvalueas:'||M_NUM);
END;
/
Doubledtheinputvalueas:20
PL/SQLproceduresuccessfullycompleted.
RestrictionsoncallingfunctionsfromSQLexpressionsUnlikeprocedures,astoredfunctioncanbecalledfromaSELECTstatement,provideditdoesnotviolatethedatabasepuritylevels.Therulesareasfollows:
AfunctioncalledfromaSELECTstatementcannotcontainDMLstatementsAfunctioncalledfromanUPDATEorDELETEstatementonatablecannotquery(SELECT)orperformtransactions(DMLs)onthesametableAfunctioncalledfromanSQLexpressioncannotcontainTCL(COMMITorROLLBACK)commandsorDDL(CREATEorALTER)commands
TheF_GET_DOUBLEfunctioncaneasilybeembeddedwithinaSELECTstatementasitrespectsalltheprecedingrules:
/*InvokethefunctionF_GET_DOUBLEfromSELECTstatement*/
SQL>SELECTF_GET_DOUBLE(10)FROMDUAL;
F_GET_DOUBLE(10)
----------------
20
NoteIntheOracleDatabase,DUALisatableownedbytheSYSuser,whichhasasinglerowandasinglecolumn,DUMMY,ofVARCHAR2(1)type.ItwasfirstdesignedbyCharlesWeisswhileworkingwithinternalviewstoduplicatearow.TheDUALtableiscreatedbydefaultduringthecreationofthedatadictionarywithasinglerowwhosevalueisX.Alldatabaseusers,otherthanSYS,useitspublicsynonymtoselectthevalueofpseudocolumnssuchasUSER,SYSDATE,NEXTVAL,orCURRVAL.Oracle10gconsiderablyimprovedtheperformanceimplicationsoftheDUALtablethroughafastdual-accessmechanism.
APL/SQLpackageAPL/SQLpackageencapsulatesmultiplePL/SQLconstructsunderasingleunit.ThePL/SQLconstructscanbesubprograms,cursors,variables,andexceptions.Asaschemaobject,aPL/SQLpackagedemonstratestheprinciplesoflogichiding,encapsulation,andsubprogramoverloading.
NoteStandalonesubprogramscannotbeoverloaded.Onlypackagedsubprogramscanbeoverloadedbytheirsignatures.
Thefollowingdiagramshowstheadvantagesofapackage:
Apackagehastwocomponents—thepackagespecificationandpackagebody.Whilethepackagespecificationcontainstheprototypeofpublicconstructs,thepackagebodycontainsthedefinitionofpublicaswellasprivate(local)constructs.
Thecharacteristicsofthepackagespecificationareasfollows:
Itisthemandatorycomponentofthepackage.Apackagecannotexistwithoutitsspecification.Itcontainstheprototypesofpublicconstructs.Theprototypeisaforwarddeclarationoftheconstructsthatincludesthedeclaration,headerspecificationandsignatureinformationterminatedbyasemicolon.Thesubprogramsconstructs,onceprototyped,shouldbedefinedinthepackagebodysection.Thepackagespecificationcannotcontainanexecutablesection.Thesememberconstructsarevisiblewithinandoutsidethepackage.Theycanbeinvokedfromoutsidethepackagebytheprivilegedusers.
NoteThepublicconstructsofapackageareaccessedas[PACKAGENAME].[CONSTRUCT].
ValidpackageconstructscanbePL/SQLtypes,variables,exceptions,procedures,andfunctions.Ifthepackagespecificationcontainsvariables,theyareimplicitlyinitializedtoNULLbyOracle
Thecharacteristicsofthepackagebodyareasfollows:
Thepackagebodycontainsthedefinitionofthesubprogramsthatweredeclaredinthepackagespecification.Thepackagebodycanoptionallycontainlocalconstructs.Theaccessibilityofthelocalconstructsislimitedtothepackagebodyonly.Thepackagebodyisanoptionalcomponent;apackagecanexistinadatabaseschemawithoutitspackagebody.
Thesyntaxforcreatingapackageisasfollows:
CREATE[ORREPLACE]PACKAGE[NAME]IS
[PRAGMA]
[PUBLICCONSTRUCTS]
END;
CREATE[ORREPLACE]PACKAGEBODY[NAME]IS
[LOCALCONSTRUCTS]
[SUBPROGRAMDEFINITION]
[BEGIN]
END;
NotetheoptionalBEGINsectioninthepackagebody.Itisoptional,butgetsexecutedonlythefirsttimethepackageisreferenced.Itisusedtoinitializeglobalvariables.
Apackagecanbecompiledwithitsspecificationcomponentalone.Insuchcases,packagedprogramunitscannotbeinvokedastheirexecutablelogichasnotbeendefinedyet.
Thecompilationofapackagewithaspecificationandbodyensurestheconcurrencybetweentheprogramunitsprototypedinthespecificationandtheprogramunitsdefinedinthepackagebody.Allpackagedprogramunitsarecompiledinasinglepackagecompilation.Ifapackageiscompiledwitherrors,itiscreatedasaninvalidobjectinthedatabaseschema.YoucanquerytheSTATUScolumntocheckthecurrentstatusofanobjectintheUSER_OBJECTS,ALL_OBJECTS,orDBA_OBJECTSdictionaryviews.
OracleDatabase12cenhancementstoPL/SQLsubprogramsOracleDatabaseRelease12cincludesanumberofPL/SQLfeatureenhancements.TheseenhancementsarefocusedonimprovingtheusabilityofPL/SQLasalanguage.Althoughthenextchapterwilldiscussmanymorenewfeaturesindetail,itisworthwhiletomentionafewofthemthatareexclusivelyrelatedtoOraclePL/SQLsubprograms.
DefiningPL/SQLsubprogramsintheSELECTstatement:AlthoughPL/SQLallowstheinvokingofafunctionfromtheSELECTstatement,thecontextswitchfromSQLtothePL/SQLenginedegradedtheperformance.Oracle12callowscreatingPL/SQLunitsintheWITHclauseofasubqueryandusingitintheSELECTstatement.ThenewapproachtocallingfunctionsinSQLstatementsenhancestheperformanceasthereisnocontextswitchingacrosstheengines.Inaddition,thesefunctionsarenotstoredinthedatabaseschema.Grantingrolestoprogramunits:OneofthechallengesinPL/SQLbeforeOracle12cwasthataprogramunithadtobecreatedwithdefinersrights,ifitwasintendedtobeexecutedbyallusers.Auserwithalowersetofprivilegescouldperformtheunauthorizedchanges.WithOracle12c,grantingrolestoPL/SQLprogramunitsaddsalevelsofsafety.Youcannowcreateprogramunitswithinvoker’srightsandcontroltheprivileges,whicharerequiredtoruntheprogram,througharole.ProtectingPL/SQLunitaccessthroughtheACCESSIBLEBYclause:WithOracle12c,youcanrestrictaccesstoaPL/SQLunitbyunauthorizedprograms.Asubprogram(aprocedure,functionorapackage)canoptionallyincludeanACCESSIBLEBYclausetodefineawhitelistofPL/SQLprogramunitsthatcaninvokeit.
ManagingdatabasedependenciesPL/SQLprogramunits,aswellasotherdatabaseobjectssuchasviews,mayrefertootherdatabaseobjectsintheirproceduralsection.Thecallingprogramunitissaidtobedependentonthecalledprogramunits(knownasreferencedobjects).IfEMPandDEPTarethebasetablesusedincreatingaviewV_EMP_REP,thentheviewisdependentonEMPandDEPT.
NoteAsequencecanalwaysbeareferencedobject.Apackagebodyisalwaysadependentobject.
Databasedependencycanbeclassifiedasdirectorindirect.Considerthreeobjects—P,M,andN.IfobjectPreferencesobjectMandobjectMreferencesobjectN,thenPisdirectlydependentonMandindirectlydependentonN.
DisplayingthedirectandindirectdependenciesThedependencymatrixisautomaticallygeneratedandmaintainedwithintheOracleDatabase.Thestatusofanobjectisthebasisofdependencyamongtheobjects.ThestatusofanobjectcanbequeriedfromtheUSER_OBJECTS(orALL_OBJECTSorDBA_OBJECTS)dictionaryview.ThefollowingqueryqueriesthestatusofthefunctionF_GET_DOUBLE:
/*CheckthestatusofthefunctionF_GET_DOUBLE*/
SELECTstatus
FROMuser_objects
WHEREobject_name='F_GET_DOUBLE'
/
STATUS
-------
VALID
ThesystemviewsDEPTREEandIDEPTREEcapturethenecessaryinformationaboutthedirectandindirectdependencies.Databaseadministratorscancreatetheviewsbyrunningthescript$ORACLE_HOME\RDBMS\ADMIN\utldtree.sql.
Theexecutionstepsforthescriptareasfollows:
1. LoginasSYSDBAinSQLDeveloperorSQL*Plus.2. Copythecompletepathandscriptname(prefixedwith@).3. Executethescript(withF9).4. QuerytheDEPTREEandIDEPTREEviewstoverifytheircreation.
ThescriptcreatestheDEPTREE_TEMPTABtableandtheDEPTREE_FILLprocedure.TheDEPTREE_FILLprocedurecanbeexecutedtopopulatethedependencydetailsofanobject.
/*PopulatethedependencymatrixforthefunctionF_GET_DOUBLE*/
SQL>EXECDEPTREE_FILL('FUNCTION','SCOTT','F_GET_DOUBLE');
PL/SQLproceduresuccessfullycompleted.
NotethatthefirstparameteroftheDEPTREE_FILLprocedureistheobjecttype,thesecondistheowner,andthethirdistheobjectname.
TheDEPTREEandIDEPTREEviewscannowbequeriedtoviewthedependencyinformation.
DependencymetadataOracleprovidesthedatadictionaryviews(USER_DEPENDENCIES,ALL_DEPENDENCIES,andDBA_DEPENDENCIES)toviewthecompletedependencymetricssharedbyanobject.Besidesthedependentobject’slist,italsolistsitsreferencingobjectnameandowner.
ThefollowingscreenshotshowsthestructureofthedictionaryviewDBA_DEPENDENCIES:
DependencyissuesandenhancementsInlinewiththeconventionaldependencyphenomenon,thestatusvalidityofthedependentobjectdependsuponthestatusofthereferencedobject.So,ifthedefinitionofthereferencedobjectisaltered,thedependentobjectismarkedINVALIDintheUSER_OBJECTSview.Althoughobjectrecompilationcaneasilysolvetheproblem,theobjectinvalidationsmayimpacttheapplicationflow.
Oracle11gintroducedFineGrainedDependencyTracking(FGD)tomodifythedependencyprincipleasfollows.Ifthealterationinthereferencedobjectdoesnotaffectthedependentobject,thedependentobjectwillremainintheVALIDstate.Forinstance,ifaviewiscreatedwithafixedsetofcolumnsofatableandthetableisalteredtoaddanewcolumn,theviewwillremaininaVALIDstate.
ReviewingOracle-suppliedpackagesOracle-suppliedpackagesexistasprebuiltprogramsinthedatabaseaswrappercode.Thesepackagesnotonlyhelpdatabasedevelopersworkonextendedfunctionalitiesbutalsoreducewritingextensiveandcomplexcode.TheuseoftheOracle-suppliedAPIisalwaysrecommendedasitimprovescodestandardization.
Thescriptsforthesepackagesareavailableinthe$ORACLE_HOME\RDBMS\ADMIN\folder.Allpackagesresideonthedatabaseserver.Publicsynonymsareavailable(orcanbecreatedtoo)forthesepackagessothatthepackagesareaccessibletothedatabaseusers.Oracle12caddsmultiplepackagestotheOracle-suppliedPL/SQLpackagelist.ThelatestadditionsprovidePL/SQLinterfacesforthenewfunctionalitiesthathavebeenaddedtothedatabaserelease.
SomeoftheimportantOracle-suppliedpackagesarelistedasfollows:
DBMS_ALERT:Thispackageisusedforthenotificationofdatabaseevents.DBMS_LOCK:Thispackageisusedformanaginglockoperations(lock,conversion,andrelease)inPL/SQLapplications.DBMS_SESSION:ThispackageisusedtosetsessionlevelpreferencesfromPL/SQLprograms(similartoALTERSESSION).DBMS_OUTPUT:Thispackageisoneofthemostfrequentlyusedbuilt-insforbufferingdatamessagesanddisplayingdebuginformation.DBMS_HTTP:ThispackageisusedforHTTPcallouts.UTL_FILE:Thispackageisusedforreading,writing,andperformingotherfileoperationsontheserver.UTL_MAIL:Thispackageisusedtocomposeandsendmails.DBMS_SCHEDULER:Thispackageisusedforschedulingexecutionofstoredproceduresatagiventime.DBMS_PARALLEL_EXECUTE:Thispackagecanbeusedtoexecuteauser-definedtaskinparallel.IfthePL/SQLblockisrunningalargeupdateonatable,thepackagecanbeusedtoenabletheparallelexecutionofthetaskbysplittingitintochunks.DBMS_PRIVILEGE_CAPTURE:ThispackageisintroducedinOracleDatabase12ctosetapolicyinordertocapturetheusageofprivileges(objectandsystem)inrespecttousers.Ithelpsincontrollingexcessprivilegesforusers.DBMS_REDACT:ThispackageisintroducedinOracleDatabase12ctocreateredactionpolicies,inordertomaskdatabasedonuserauthorization.DBMS_RESOURCE_MANAGER:Thispackageisusedtocreateconsumergroups,directives,andresourcemanagerplansforcontainersaswellasapluggabledatabase.Theresourcemanagerplandeterminestheresourcesallocatedtoapluggabledatabase,aschema,oratask.DBMS_DATAPUMP:Thispackageisusedtomovedata,metadata,orbothfromonedatabasetoanother.Thesourceandtargetdatabasescanbeondifferentplatforms.DBMS_PDB:ThispackageisintroducedinOracleDatabase12ctogenerateoranalyzetheintegrationpropertiesofapluggabledatabaseforunplug/plugoperations.
DBMS_SQL:ThispackageenablesdynamicSQLinPL/SQL.YoucanrunDMLorDDLstatementsusingDBMS_SQLfromaPL/SQLblock.DBMS_REDEFINITION:Thispackageisusedtoperformonlineredefinitiontasksfortables.DBMS_UTILITY:Thispackageisusedtoaccomplishmanyutilityoperationssuchasanalyzeobject,compileschema,getdependency,resolveagivenname,validatedatabaseobjects,formatcallanderrorstack,expandSQLtext,andretrievecurrentdatabaseversion.
Basedontheobjectivetobeachieved,thepackagescanbecategorizedasfollows:
Standardapplicationdevelopment:ManyoftheDBMSpackagesprovideanapplicationinterfacefordatabasefeatures.Forexample,DBMS_REDACTprovidesaninterfacetocreateandmanageredactionpolicies.Similarly,DBMS_UTILITYprovidessubprogramstoretrieveinstanceordatabaseinformation,callstacksanderrorstacks,andanalyzeandvalidateobjects.TheDBMS_OUTPUTpackageisoneofthepackagesmostfrequentlyusedtodisplaytextmessages.Itcanbeefficientlyusedfortracinganddebuggingpurposes.AccessingandwritingoperatingsystemfileswasmadepossiblethroughUTL_FILE.Generalusageandapplicationadministration:Oraclehasmanypackagesformonitoringapplicationsandusers.Statisticsgeneration,loadhistory,andspacemanagementarethekeyobjectivesaccomplishedbythesepackages.DBMS_UTILITYcomprisessubprogramsforgeneralusage.Internalsupportpackages:Oraclemaintainsthesepackagesforitsownuse.Transactionprocessingpackages:Oracleprovidesutilitypackagesthatenablethemonitoringoftransactionstages.Thoughtheyarerarelyused,theycanefficientlyensuretransparentandsmoothtransactions.Forexample,DBMS_TRANSACTIONisusedtoaccessSQLtransactionsfromstoredsubprograms.DBMS_PARALLEL_EXECUTEexecutesalargeupdateinparallelbysplittingitintosmalltasks.
OracleSQLDeveloperOracleSQLDeveloperisaGraphicalUserInterface(GUI)integrateddevelopmentenvironmentfromOracleCorporation.OracleSQLDeveloperisafreetoolthatsimplifiesPL/SQLcodedevelopment,thedatabasedesign,andmodelingandadministrationforstandaloneandclouddeployments.Thistoolenhancestheuser’sexperiencebymaximizingproductivityandextensibility.
SQLDeveloperisaJava-basedcross-platformtoolthatcanrunonLinux,Windows,andMacOSX.
OracleSQLDevelopersupportsOracleDatabaseversions10g,11g,and12c.WithOracleDatabase12cMultitenantarchitecture,SQLDeveloperextendsfullsupportforvariousmultitenantoperations.InadditiontothesupportforOracleDatabases,thetoolalsoallowsuserstoconnecttonon-OracleDatabasesincludingMySQL,MicrosoftSQLServer,MicrosoftAccess,Sybase,andTeradata.Theextensibleframeworkenablesuserstodevelopcustomextensionsinordertoaddressspecificrequirements.
SQLDeveloperwasfirstreleasedinMarch,2006.TheinitialreleaseofSQLDeveloperincludedbasicfeaturessuchasaschemabrowser,anSQLworksheettorunSQLandinvokeSQLscripts,aPL/SQLeditor,codedebugging,andrunningbasicreports.Sincethen,thetoolhasgrownimmenselyandmaturedovertheyears.Atthetimeofwriting,thelatestreleaseofSQLDeveloperis4.1.
OracleSQLDeveloperforDBA,Developers,andApplicationArchitectsOracleSQLDeveloperprovidespowerfulfeaturesandinterfacesforcodedevelopment,administrativeactivities,anddatamodeling.ItoffersricheditorsfordeveloperswhoworkwithSQL,PL/SQL,andstoredprogramunits.SQLDevelopercanrunSQLqueries,monitorperformancethroughexecutionplansandSQLtuning,andpreparescripts.DatabasedeveloperscanbuildPL/SQLapplications,debugthem,andperformrun-timetesting.
WithSQLDeveloper3.0,theDBApanelinthetooladdedthefunctionalitytoperformcommonDBAtasksandactivities.Thenewfeatureadditionssuchasthedataminer,datamodeler,databasenavigator,andDBMSschedulerprovidearangeofadministrativefunctionalitiesinthetool.Databaseadministratorscanperformcoreadministrationtaskssuchasexport/importthroughdatapump,RMAN,userandrolemanagement,andresourcemanagement.SQLDeveloperintegratesseamlesslywithOracleAPEX,therebyallowingAPEXdeveloperstobrowse,deploy,andexportapplications.
Withthemostrecentversion,moreDBAactivitieshavebeenincorporatedtomakeitmorefeature-richandcomplete.
Fordatabasearchitects,SQLDeveloperoffersadatamodelingsolutionwithSQLDeveloperDataModeler(SDDM).TheSDDMenablesarchitectstocreatedataflowdiagrams,designversioningviasubversion,importdesignerrepositories,andmostimportantlyperformlogical,relational,andphysicaldatamodeling.
SQLDeveloper4.0WiththereleaseofOracleSQLDeveloper4.0andonwards,thetoolfollowsOracle’sdatamanagementstrategybysupportingOracleDatabase12cMultitenantoption,clouddeployments,OracleNoSQLandJSON.Inaddition,itincludesabrandnewcommandlineinterfaceutilitytoenhanceuserexperience.WithnativesupportforOracleRestDataServicesinOracleDatabase12c,WebapplicationdeveloperscanworkwithSQLDevelopertocreateandalterservices.DatabaseadministratorscannowrunASH,AWR,andADDMreportsfromtheperformancepageintheDBApanel.SQLDeveloper4.0’snewfeaturescanbesummarizedasfollows:
SupportforOracleDatabase12cMultitenantarchitectureSupportforOracleNoSQLDatabaseSupportfordatabaseproductssuchasTimesTen,DataMiner,XMLDB,andSpatialandGraphsSupportforJava7QueryingJSONdatainrelationalformatNewinstanceviewerenablesthemonitoringofwaitevents,storage,logswitches,anddatabaseprocesses
Chapter12,WorkingwithOracleSQLDeveloper,focusesonvariousfeaturesoftheOracleSQLDevelopertool.
SummaryOvertheyears,PL/SQLhasmaturedagreatdealandhasproducedavastlibraryofobjects,features,andstandards.ThischapterfocusedongivingaquicksummaryofPL/SQLprogramming.Itassumedreaderswerefamiliarwithdatabaseprogrammingconceptsandprovidedenoughsubstancetogetthemreadyfortheforthcomingchapters.ItwouldhavebeenatoughcalltobuildaglossaryofPL/SQLobjectsinasinglechapter.
WestartedwithanoverviewofPL/SQLfundamentals,blockstructure,andexceptionhandling.Additionally,thischapterthrewlightoncursorhandlinginPL/SQL,theCURSORFORloop,andschemaobjectssuchasprocedures,functions,andpackages.Inforthcomingchapters,wewillfocusonthekeyfacultiesofthePL/SQLlanguageaswellasOracleDatabase12cfeatures.
PracticeexerciseWhichofthefollowingfeaturesarenotavailableinSQLDeveloper?
1. Querybuilder.2. Databaseexportandimport.3. Databasebackupandrecoveryfunctions.4. CodeSubversionrepository.
ForafunctiontobecalledfromaSQLexpression,whichofthefollowingconditionsshoulditobey?
1. AfunctionintheSELECTstatementshouldnotcontainDMLstatements.2. Thefunctionshouldreturnavalue.3. AfunctionintheUPDATEorDELETEstatementshouldnotquerythesametable.4. AfunctioncalledfromaSQLexpressioncannotcontainTCL(COMMITor
ROLLBACK)commandsorDDL(CREATEorALTER)commands.
ThefollowingqueryisexecutedintheSCOTTschema:
SELECTNAME,referenced_owner,referenced_name
FROMall_dependencies
WHEREowner=USER
ANDreferenced_typeIN('TABLE','VIEW')
ANDreferenced_ownerIN('SYS')
ORDERBYowner,NAME,referenced_owner,referenced_name;
Whichstatementistrueabouttheoutputofthisquery?
1. Itdisplaystheschemaobjects,createdbytheuserORADEV,thatuseatableorviewownedbySYS.
2. AnexceptionoccursasuserSCOTThasinsufficientprivilegestoaccessALL_DEPENDENCIESview.
3. ItdisplaysallPL/SQLcodeobjectsthatreferenceatableorviewdirectlyforalltheusersinthedatabase.
4. ItdisplaysonlythosePL/SQLcodeobjectscreatedbytheuserOEthatreferenceatableorviewcreatedbytheuserSYS.
WhichofthefollowingistrueaboutPL/SQLblocks?
1. ExceptionisamandatorysectionwithoutwhichananonymousPL/SQLblockfailstocompile.
2. BindvariablescannotbereferredinsideaPL/SQLblock.3. Thescopeandvisibilityofthevariablesdeclaredinthedeclarativesectionof
theblockarewithinthecurrentblockonly.4. TheRAISE_APPLICATION_ERRORproceduremapsapredefinederrormessagetoa
customizederrorcode.
Fromthefollowingoptions,identifythewaysofdefiningexceptions:
1. DeclareanEXCEPTIONvariableandraiseitusingtheRAISEstatement.2. UsePRAGMAEXCEPTION_INITtoassociateacustomizedexceptionmessagetoa
pre-definedoracleerrornumber.3. DeclareanEXCEPTIONvariableanduseitinRAISE_APPLICATION_ERROR.4. UseRAISE_APPLICATION_ERRORtocreateadynamicexceptionatanystage
withintheexecutableorexceptionsectionofaPL/SQLblock.
Choosethedifferencesbetweenproceduresandfunctions:
1. Afunctionmustmandatorilyreturnavalue,whileaproceduremayormaynot.2. AfunctioncanbecalledfromaSQLquery,whileaprocedurecanneverbe
invokedfromSQL.3. Afunctioncanacceptparameterspassedbyavalue,whileaprocedurecan
acceptparameterspassedbyreferenceonly.4. Astandalonefunctioncanbeoverloadedbutaprocedurecannot.
Examinethevaluesofthecursorattributeforthefollowingqueryandpicktheattributewiththewrongvalue:
BEGIN
…
SELECTENAME,SAL
INTOL_ENAME,L_SAL
FROMEMPLOYEES
WHEREEMPID=7900;
…
END;
1. SQL%ROWCOUNT=12. SQL%ISOPEN=FALSE3. SQL%FOUND=FALSE4. SQL%NOTFOUND=FALSE
Chapter2.Oracle12cSQLandPL/SQLNewFeaturesOraclereleasedOracleDatabase12cinJuly2013.Fromatechnologystandpoint,itwasanimportantproductreleaseasthefocuswasconsolidationofdatabasesonpublicandprivatecloudinfrastructures.OracleDatabase12cintroducesthenewMultitenantarchitecturethatallowsmultipledatabasestorunasatenantwithinasingledatabase.Thenewdesignassurestenantisolationandsecurity,andenhancesmanageabilityofconsolidateddatabases,OracleDatabase12cprovidesmorethan500newfeaturesincludingmultitenantarchitectureandmanyothersrelatedtosecurity,highavailability,andperformance.Thechaptercoversthekeyfeaturesintroducedinthelatestproductrelease.
OracleDatabase12chasmadeconsiderableimprovementstotheSQLandPL/SQLlanguages.ThelanguageenhancementsinOracleDatabase12cfocusonsupportforANSISQLstandards,effortlesscodewritingandmigrationfromnon-OracletoOraclecompliantcode.ThischapterdiscussesmanysuchenhancementsandfeaturesofOracleDatabase12c.
Theoutlineofthechapterisasfollows:
TheMultitenantarchitectureSQLnewfeaturesPL/SQLnewfeaturesOracleDatabase12cIn-Memoryoption
DatabaseconsolidationandthenewMultitenantarchitectureConsolidationisthekeyenablerformovingdatabasestoon-cloudmodels.Anefficientconsolidationstrategycanprovideelasticsharingofresourcesandmaximizeresourceutilizationinaconsolidatedstack.Adatabasehostedonapublicorprivatecloudmustguaranteetenantisolationandsecurity.Inadditiontotheelementaryrequirementsofclouddeployments,databaseprovisioningonthecloudshouldbequickandeasy.
OracleDatabase12cintroducesamultitenantarchitecturethatmeetsthechallengesofclouddeployments.Thenewtenant-basedarchitectureallowsoneormoreapplicationdatabases(knownaspluggabledatabases)torunwithinasingledatabase(knownasthecontainerdatabase).Eachpluggabledatabaseiscompletelyshieldedfromallotherpluggabledatabasesrunningwithinthesamecontainerdatabase.Thearchitectureprovidesauniquemechanismtosegregatethesystemandapplicationmetadataatthecontainerandpluggablelevelrespectively.Inasingle-tenantarchitecture,arootcontainercanhavejustonepluggabledatabase.Inamultitenantarchitecture,arootcontainercanhavemorethanonepluggabledatabase.Whilesingle-tenantisfreeofcostandavailableinOracleDatabaseStandardEdition,multitenantcanbelicensedinOracleDatabaseEnterpriseEditiononly.
StartingwithOracleDatabase12.1.0.2,thenon-tenantorstandalonearchitectureofOracleDatabaseisdeprecatedwhichmeansthatitwillnotbefurtherenhanced.
Letusgetfamiliarizedwiththetermsofthenewworld—thecontainerandpluggabledatabases.
AnOracle12ccontainerdatabase(CDB)providestheinstancethatcanbesharedbymultipledatabases.ACDBinstancehasthememoryandasetofbackgroundprocesses.Fromtheserversubsystem,thecontainerdatabaseistheonlydatabasevisible.
Apluggabledatabase(PDB)issimilartoapre12cdatabasethatservesasanapplicationdatabasebackend.Apluggabledatabasecontainstheapplicationtablespaces.
ThefollowingdiagramshowstheOracleDatabase12cmultitenantarchitecture:
Acontainerdatabasemaycontainoneormorepluggabledatabasecontainers.Withreferencetotheprecedingarchitecture,letusdrillintothespecificsofnewcomponents.
Acontainerdatabase(CDB)consistsofonerootcontainer(knownasCDB$ROOT),oneseedpluggabledatabase(knownasPDB$SEED),andmultiplepluggabledatabases.Similartothepreviousreleases,acontainerdatabasehasaninstanceandsetoffiles.Thedatabaseinstanceisofthecontainer,whichmeansthattheSystemGlobalArea(SGA)iscommonforallthepluggabledatabases.Also,thereisasinglecopyofbackgroundprocessesatthecontainerinstancelevelonly,andnotreplicatedforeachPDB.
Apluggabledatabaseisadatabasethatstorestheapplicationdata.AsofOracleDatabase12cRelease1,amultitenantdatabasecanhaveamaximumof252pluggabledatabases.APDBserviceiscreatedatthetimeofprovisioningthatrunswithintheCDBserviceandgetsauto-registeredwiththeCDBlistener.SinceaPDBrunsasasecuredservicewithinthecontainerdatabaseadministrationservice,itcannotbeauthenticatedbytheserveroperatingsystem.However,youcancreateauser-definedserviceusingDBMS_SERVICEforOSauthenticationandTNSconnection.
Theredologsandarchivelogsareatthecontainerlevel.Everytimeapluggabledatabasehastomakearedoentry,therequestistaggedwiththePDBidentity.Theidentityinthiscaseisnothingbutthecontaineridentifier(CON_ID).Eachcontainerinacontainerdatabaseisassignedauniquecontainerid.Theroothasthecontainerid1;theseedPDBhas2andeachpluggabledatabaseisassignedacontaineridinasequentialfashion.Thecontaineridisquiteasignificantelementasthecommonredoislogicallyvirtualizedbyannotatingeachandeveryentrywiththecontainerid.AllthedictionaryviewsandmetadataviewshaveanadditionalcolumnCON_IDtoidentifythecontainertowhichtheinformationbelongs.
Thecontrolfileandserverparameterfileareattherootcontainerlevel.Startingwith
Oracle12c,therearetwocategoriesofparameters—CDBmodifiableandPDBmodifiable.TheV$PARAMETERdictionaryviewhasanadditionalcolumnISPDB_MODIFIABLE.ThevalueofthecolumnisNforCDB-modifiableandYforPDB-modifiableparameters.
TheSYSTEMandSYSAUXtablespacesattherootcontainerlevelstorethesystemmetadatathatisspecificjusttotheOracleDatabase.TheapplicationmetadataforeachpluggabledatabaseisstoredineachPDB’srespectiveSYSTEMandSYSAUXtablespaces.TheUNDOtablespaceisattherootcontainerlevel.Onceagain,similartoredo,eachundoentryistaggedwiththecontaineridentifierorCON_ID.Withoneundofortheentirecontainer,youmightbeinterestedinevaluatingtheperformanceimplicationsofthesystem.Well,undomanagementinmultitenantconsolidationisnottoodifferentfromschemaconsolidation.Theredoandundoentriesareindexedbythecontainerids,thusspeedinguptheconcurrentrecordaccessforaspecificPDB.
AlthoughthemultitenantarchitectureshowstheTEMPtablespaceatthecontainerlevel,butitcanbecreatedforeachofthepluggabledatabasetoo.Userscancreatetablespaceswithinthepluggabledatabasesasusual,wheneverrequired.
TheOracleDatabase12cMultitenantarchitecture–featuresHavingmentionedthechallengesofconsolidationandclouddeployments,letustakealookatthecapabilitiesenabledbythemultitenantarchitecture.
MultitenantforConsolidationInthepast,enterpriseshavebeenfollowingmultipleapproachestoconsolidatedatabasestoachievetenantisolationandmanageability.Youcouldhaveanenormousphysicalserverandthenextractvirtualizedhomesforeachapplication.Thevirtualizedhomeistheapplication’sworldofoperationandsharestheserversubsystem.Howevertheoverheadofmanagingtheheterogeneouspiecescanbeapotentialpainpoint.Theconsolidationdensityislimitedbythefactthatthememoryallocatedtoavirtualizedhomeremainsintactwhetherornotitisgettingused.
Youcancreatemultipledatabasesonaserverforeachapplication.Anaggregationofdatabasesispossibleuntiltheservermemoryisexhausted.Keepinmindthateachdatabaseinstancecreatesit’sowncopyofbackgroundprocesses,whichholdstheCPUcycles,thusreducingtheconsolidationdensity.
OneofthemostefficientapproachesbeforeOracle12cwastoadoptschema-basedconsolidation.Youcanachievethehighestconsolidationdensityasmultipleschemasarepartofasingledatabase.Thedownsideofschema-basedconsolidationisthattenantisolationwasnotguaranteed,whilesecurityandmanageabilitywereabigconcern.
ThemultitenantapproachinOracleDatabase12callowstheeffectivesharingofserverresources,theoperatingsystem,andeventhedatabase.Theadvancedsharingofresourcesmakesitsuitabletoimplementanddeployonthecloud.Itguaranteesthetenantisolationaseachpluggabledatabaseappearsremotetootherpluggabledatabasessharingthesamecontainer.AcommonSGAandasinglesetofbackgroundprocessesoptimallyutilizetheservermemory,thusmaximizingconsolidation.ManagementcapabilitiesaddvaluetothenewarchitectureinOracle12c.
Plug/unplugApluggabledatabasecanbeunpluggedfromthecurrentcontainerandpluggedintoanothercompatiblecontainer.DatamobilityacrossthecontainersbecomeseasierandquickerasyoujusthavetoworkwiththePDBmetadataandnotmovetheapplicationdata.TheunplugoperationcapturesthePDBlineageinanXMLmanifestfile,allowingaPDBtobepluggedintoanothercontainerdatabase.
Thefeaturecomesinhandyindatacenteroperationswhenthedatabasesareexpectedtomovequicklytodifferentservicelevels,withoutimpactingbusinesscontinuity.Anotherveryimportantusecaseoftheplug/unplugfeatureiswhenyouarerequiredtoupgradeorpatchsubsetsofPDBsinacontainer.YoucanunplugaPDBfroma12.1containerandplugitinaOracle12.xcontainerdatabase.
ManageManyasOneThemultitenantarchitectureenablesthe“managemanyasone”capability.OrganizationswhoareadoptingaMultitenantarchitecture,areexpectedtoseeasignificantreductioninoperationalexpensesbymanagingmultipledatabasesasone.Hereisthelistofmultitenantoperationsthatapplytoallthepluggabledatabases:
Backingupthecontainerdatabasebacksuptherootcontainerincludingallthepluggabledatabases.However,pointintimerecoveryatthepluggabledatabaselevelispossible.
NoteYoucanalsobackupjusttheCDB$ROOToraparticularPDB
Inadataguardsetup,allpluggabledatabasesareauto-discoveredatthestandbysite.Therefore,ahighavailabilityofallPDBsismaintainedbyimplementingthedataguardatthecontainerlevel.
NoteInOracleDatabase12.1.0.2,youcanprovisionaPDBonaprimarysitebutdisableitsrecoveryatthestandbysitebyspecifyingSTANDBYS=NONE
Upgradingandpatchingthecontainerdatabaseupgradesorpatchesallthepluggabledatabases.However,ifyouarerequiredtoupgradeorpatchasubsetofpluggabledatabases,youcanunplugandplugintoadifferentcontainerofahigherreleaseorpatchset.
RapidprovisioningPluggabledatabasescanbequicklyprovisionedeitherlocallywithinacontainerorfromaremotecontainer.PDBprovisioningdoesn’tinvolvecopyingthesystemmetadataorthecreationofbackgroundprocesses,therebyspeedingupthecreationprocess.
Apluggabledatabasecanbeprovisionedindifferentwaysaslistedhere:
AfreshPDBfromseed(PDB$SEED)—creatingabrandnewpluggabledatabasefromtheseedPDBisamerecopyofSYSTEMandSYSAUXfilesfromtheseedlocationtothetargetPDBlocationonthedatabaseserver.Clone/copyanexistingPDB—anexistingPDBcanbeclonedlocallywithinthecurrentcontainer.Operationally,cloningaPDBiscopyingthefilestoanewPDBlocation.ThePDBremotecloningfeatureisavailablefromOracleDatabase12c(12.1.0.2).SnapshotCloning—OracleDatabase12csupportssnapshotcloningofpluggabledatabasesoncopy-on-writefilesystems.Byvirtueofthecopy-on-writefeature,snapshotcloningisanextremelyfastmethodofcreatingcopiesofpluggabledatabases.
OracleDatabase12.1.0.2introducednewenhancementstoPDBcloninginamultitenantcontainerdatabase.Theenhancementsarebrieflydescribedhere:
SchemaconsolidationtoPDB-basedconsolidation—youcancreateanewpluggabledatabasebyspecifyingjustthetablespacestobeavailableinthenewPDB.YoucanspecifytablespacesintheUSER_TABLESPACEclauseatthetimeofPDBcreation.Pre12cdatabases,whichearlierusedtheschemaconsolidationapproach,willbenefitfromthisnewfeaturewhilemovingtoOracle12cMultitenant.Metadata-onlyclone—YoucancloneaPDBdatamodel,andnotitsdata,byspecifyingNODATAatthetimeofcloning.Remoteclonenon-CDBasPDB—YoucandirectlycloneanOracle12cnon-CDBasthePDBinamultitenantcontainerdatabase.
CDBResourceManagementResourcemanagementisanessentialexerciseinamultitenantcontainerdatabasethathostsmultipleapplicationdatabases,withacommonSGAandbackgroundprocess.Withmultiplepluggabledatabases,scenariosmayarisewheredatabasesmaycompeteforserverresources.Therequestcongestionmightimpacttheperformanceofcriticaldatabases,thusimpactingbusinessSLAs.TheDatabaseResourceManager(DBRM)featurehasbeenenhancedinOracle12ctoextendsupporttothemultitenantarchitecture.
Inamultitenantenvironment,youcancreateCDBplandirectivestomanagetheallocationoftheCPUasshares,andparallelexecutionslavesacrossthemultiplepluggabledatabases.Intheeventofresourcecongestion,pluggabledatabasesfollowtheCDBresourceplantoprioritizetherequests.
Withinapluggabledatabase,youcancreatetheusualdatabaseresourcemanagementplanstocontroltheconsumptionoftheavailableresourcesacrossconsumergroups.
CommonusersandlocalusersStartingwithOracle12cMultitenantarchitecture,therewillbetwofamiliesofusers,namelycommonusersandlocalusers.ThecontainerDBAcreatesacommonuserintherootcontainer.Localusersaretheonesthatarevisibleandoperationalwithinasinglepluggabledatabase.AlltheusersuntilOracleDatabase11gwillfallunderthecategoryoflocalusers.
Herearetheimportantpointsregardingcommonandlocalusers:
AllcommonusersmuststartwithC##.SYSisanexception.PluggabledatabasesmustgrantCONNECTandCREATESESSIONprivilegetothecommonusertoallowaccesstothecontainer.ThestaticviewsCDB_USERSandDBA_USERShaveanewcolumnCOMMONtodifferentiatecommonandlocalusers.Acommonusercanbeusedtoexecuteagenericscriptacrossmultiplecontainers(usingcatcon.pl).WithOracle12c(12.1.0.2),commonuserscanquerycommonobjectsinrootthe(CDB$ROOT)frommultiplecontainersusingtheCONTAINERSclause.
Oracle12cSQLandPL/SQLnewfeaturesSQListhemostwidelyuseddataaccesslanguagewhilePL/SQLisapopularlanguagethatcanintegrateseamlesslywithSQLcommands.ThebiggestbenefitofrunningPL/SQListhatthecodeprocessinghappensnativelywithintheOracleDatabase.Inthepast,therehavebeendebatesanddiscussionsonserversideprogrammingwhiletheclientinvokesthePL/SQLroutinestoperformatask.Theserversideprogrammingapproachhasmanybenefits.Itreducesthenetworkroundtripsbetweentheclientandthedatabase.ItreducesthecodesizeandeasesthecodeportabilitybecausePL/SQLcanrunonallplatforms,whereverOracleDatabaseissupported.
OracleDatabase12cintroducesmanylanguagefeaturesandenhancementsthatfocusonSQLtoPL/SQLintegration,codemigration,andANSIcompliance.ThissectiondiscussestheSQLandPL/SQLnewfeaturesinOracleDatabase12c.
IDENTITYcolumnsOracleDatabase12cintroducesidentitycolumnsinSQLincompliancewiththeAmericanNationalStandardInstitute(ANSI)SQLstandard.Atablecolumn,markedasIDENTITY,automaticallygeneratesanincrementalnumericvalueatthetimeofrecordcreation.
BeforethereleaseofOracle12c,developershadtocreateanadditionalsequenceintheschemaandassignitsvaluetothecolumnthroughatriggerorinaPL/SQLblock.Thenewfeaturesimplifiescodewritingandbenefitsthemigrationofanon-OracledatabasetoOracle.
ThefollowingscriptdeclaresanidentitycolumninthetableT_ID_COL:
/*Createatablefordemonstrationpurpose*/
CREATETABLEt_id_col
(idNUMBERGENERATEDASIDENTITY,
nameVARCHAR2(20))
/
TheidentitycolumnmetadatacanbequeriedfromthedictionaryviewsUSER_TAB_COLSandUSER_TAB_IDENTITY_COLS.NotethatOracleimplicitlycreatesasequencetogeneratethenumbervaluesforthecolumn.However,Oracleallowstheconfigurationofthesequenceattributesofanidentitycolumn.ThecustomsequenceconfigurationislistedunderIDENTITY_OPTIONSinUSER_TAB_IDENTITY_COLSview:
/*QueryidentitycolumninformationinUSER_TAB_COLS*/
SELECTcolumn_name,data_default,user_generated,identity_column
FROMuser_tab_cols
WHEREtable_name='T_ID_COL'
/
COLUMN_NAMEDATA_DEFAULTUSEIDE
--------------------------------------------------
ID"SCOTT"."ISEQ$$_93001".nextvalYESYES
NAMEYESNO
LetuschecktheattributesoftheprecedingsequencethatOraclehasimplicitlycreated.NotethatthequeryusesREGEXP_SUBSTRtoprintthesequenceconfigurationinmultiplerows:
/*CheckthesequenceconfigurationfromUSER_TAB_IDENTITY_COLSview*/
SELECTtable_name,column_name,generation_type,
REGEXP_SUBSTR(identity_options,'[^,]+',1,LEVEL)identity_options
FROMuser_tab_identity_cols
WHEREtable_name='T_ID_COL'
CONNECTBYREGEXP_SUBSTR(identity_options,'[^,]+',1,level)
ISNOTNULL
/
TABLE_NAMECOLUMN_NAMEGENERATIONIDENTITY_OPTIONS
-----------------------------------------------------------------
T_ID_COLIDALWAYSSTARTWITH:1
T_ID_COLIDALWAYSINCREMENTBY:1
T_ID_COLIDALWAYSMAX_VALUE:9999999999999999999999999999
T_ID_COLIDALWAYSMIN_VALUE:1
T_ID_COLIDALWAYSCYCLE_FLAG:N
T_ID_COLIDALWAYSCACHE_SIZE:20
T_ID_COLIDALWAYSORDER_FLAG:N
7rowsselected
WhileinsertingdatainthetableT_ID_COL,donotincludetheidentitycolumnasitsvalueisautomaticallygenerated:
/*Inserttestdatainthetable*/
BEGIN
INSERTINTOt_id_col(name)VALUES('Allen');
INSERTINTOt_id_col(name)VALUES('Matthew');
INSERTINTOt_id_col(name)VALUES('Peter');
COMMIT;
END;
/
Letuscheckthedatainthetable.Notetheidentitycolumnvalues:
/*Querythetable*/
SELECTid,nameFROMt_id_col
/
IDNAME
-------------------------
1Allen
2Matthew
3Peter
Thesequencecreatedunderthecoversforidentitycolumnsistightlycoupledwiththecolumn.Ifausertriestoinsertauser-definedinputfortheidentitycolumn,theoperationthrowsanexceptionORA-32795:
INSERTINTOt_id_colVALUES(7,'Steyn');
insertintot_id_colvalues(7,'Steyn')
*
ERRORatline1:
ORA-32795:cannotinsertintoageneratedalwaysidentitycolumn
DefaultcolumnvaluetoasequenceinOracle12cOracleDatabase12callowsdeveloperstodefaultacolumndirectlytoasequence‑generatedvalue.TheDEFAULTclauseofatablecolumncanbeassignedtoSEQUENCE.CURRVALorSEQUENCE.NEXTVAL.Thefeaturewillbeusefulwhilemigratingnon-OracledatadefinitionstoOracle.
TheDEFAULTONNULLclauseStartingwithOracleDatabase12c,acolumncanbeassignedadefaultnon-nullvaluewhenevertheusertriestoinsertNULLintothecolumn.ThedefaultvaluewillbespecifiedintheDEFAULTclauseofthecolumnwithanewONNULLextension.
NotethattheDEFAULTONNULLcannotbeusedwithanobjecttypecolumn.
Thefollowingscriptcreatesatablet_def_cols.AcolumnIDhasbeendefaultedtoasequencewhilethecolumnDOJwillalwayshaveanon-nullvalue:
/*Createasequence*/
CREATESEQUENCEseqSTARTWITH100INCREMENTBY10
/
/*Createatablewithacolumndefaultedtothesequencevalue*/
CREATETABLEt_def_cols
(idnumberdefaultseq.nextvalprimarykey,
namevarchar2(30),
dojdatedefaultonnull'01-Jan-2000'
)
/
ThefollowingPL/SQLblockinsertsthetestdata:
/*Insertthetestdatainthetable*/
BEGIN
INSERTINTOt_def_cols(name,doj)values('KATE','27-FEB-2001');
INSERTINTOt_def_cols(name,doj)values('NANCY','17-JUN-1998');
INSERTINTOt_def_cols(name,doj)values('LANCE','03-JAN-2004');
INSERTINTOt_def_cols(name)values('MARY');
COMMIT;
END;
/
QuerythetableandcheckthevaluesfortheIDandDOJcolumns.IDgetsthevaluefromthesequenceSEQwhileDOJforMARYhasbeendefaultedto01-JAN-2000.
/*Querythetabletoverifysequenceanddefaultonnullvalues*/
SELECT*FROMt_def_cols
/
IDNAMEDOJ
---------------------------
100KATE27-FEB-01
110NANCY17-JUN-98
120LANCE03-JAN-04
130MARY01-JAN-00
Supportfor32KVARCHAR2OracleDatabase12csupportstheVARCHAR2,NVARCHAR2,andRAWdatatypesupto32,767bytesinsize.ThepreviousmaximumlimitfortheVARCHAR2(andNVARCHAR2)andRAWdatatypeswas4,000bytesand2,000bytesrespectively.Thesupportforextendedstringdatatypeswillbenefitnon-OracletoOraclemigrations.
ThefeaturecanbecontrolledusingtheinitializationparameterMAX_STRING_SIZE.Itacceptstwovalues:
STANDARD(default)—ThemaximumsizepriortothereleaseofOracleDatabase12cwillapply.EXTENDED—Thenewsizelimitforstringdatatypesapply.NotethataftertheparameterissettoEXTENDED,thesettingcannotberolledback.
Thestepstoincreasethemaximumstringsizeinadatabaseare:
1. RestartthedatabaseinUPGRADEmode.Inthecaseofapluggabledatabase,thePDBmustbeopenedinMIGRATEmode.
2. UsetheALTERSYSTEMcommandtosetMAX_STRING_SIZEtoEXTENDED.3. AsSYSDBA,executethe$ORACLE_HOME/rdbms/admin/utl32k.sqlscript.Thescript
isusedtoincreasethemaximumsizelimitofVARCHAR2,NVARCHAR2,andRAWwhereverrequired.
4. RestartthedatabaseinNORMALmode.5. AsSYSDBA,executeutlrp.sqltorecompiletheschemaobjectswithinvalidstatus.
Thepointstobeconsideredwhileworkingwiththe32ksupportforstringtypesare:
COMPATIBLEmustbe12.0.0.0AftertheparameterissettoEXTENDED,theparametercannotberolledbacktoSTANDARD
InRACenvironments,alltheinstancesofthedatabasecomplywiththesettingofMAX_STRING_SIZE
RowlimitingusingFETCHFIRSTForTop-Nqueries,OracleDatabase12cintroducesanewclause,FETCHFIRST,tosimplifythecodeandcomplywithANSISQLstandardguidelines.Theclauseisusedtolimitthenumberofrowsreturnedbyaquery.ThenewclausecanbeusedinconjunctionwithORDERBYtoretrieveTop-Nresults.
TherowlimitingclausecanbeusedwiththeFORUPDATEclauseinanSQLquery.Inthecaseofamaterializedview,thedefiningqueryshouldnotcontaintheFETCHclause.
Anothernewclause,OFFSET,canbeusedtoskiptherecordsfromthetopormiddle,beforelimitingthenumberofrows.Forconsistentresults,theoffsetvaluemustbeapositivenumber,lessthanthetotalnumberofrowsreturnedbythequery.Forallotheroffsetvalues,thevalueiscountedaszero.
KeywordswiththeFETCHFIRSTclauseare:
FIRST|NEXT—SpecifyFIRSTtobeginrowlimitingfromthetop.UseNEXTwithOFFSETtoskipcertainrows.ROWS|PERCENT—Specifythesizeoftheresultsetasafixednumberofrowsorpercentageoftotalnumberofrowsreturnedbythequery.ONLY|WITHTIES—UseONLYtofixthesizeoftheresultset,irrespectiveofduplicatesortkeys.Ifyouwantallrecordswithmatchingsortkeys,specifyWITHTIES.
ThefollowingquerydemonstratestheuseoftheFETCHFIRSTandOFFSETclausesinTop-Nqueries:
/*Createthetesttable*/
CREATETABLEt_fetch_first
(empnoVARCHAR2(30),
deptnoNUMBER,
salNUMBER,
hiredateDATE)
/
ThefollowingPL/SQLblockinsertssampledatafortesting:
/*InsertthetestdatainT_FETCH_FIRSTtable*/
BEGIN
INSERTINTOt_fetch_firstVALUES(101,10,1500,'01-FEB-2011');
INSERTINTOt_fetch_firstVALUES(102,20,1100,'15-JUN-2001');
INSERTINTOt_fetch_firstVALUES(103,20,1300,'20-JUN-2000');
INSERTINTOt_fetch_firstVALUES(104,30,1550,'30-DEC-2001');
INSERTINTOt_fetch_firstVALUES(105,10,1200,'11-JUL-2012');
INSERTINTOt_fetch_firstVALUES(106,30,1400,'16-AUG-2004');
INSERTINTOt_fetch_firstVALUES(107,20,1350,'05-JAN-2007');
INSERTINTOt_fetch_firstVALUES(108,20,1000,'18-JAN-2009');
COMMIT;
END;
/
TheSELECTquerypullsinthetop-5rowswhensortedbytheirsalary:
/*Querytolisttop-5employeesbysalary*/
SELECT*
FROMt_fetch_first
ORDERBYsalDESC
FETCHFIRST5ROWSONLY
/
EMPNODEPTNOSALHIREDATE
------------------------------
104 30155030-DEC-01
101 10150001-FEB-11
106 30140016-AUG-04
107 20135005-JAN-07
103 20130020-JUN-00
TheSELECTqueryliststhetop25%ofemployees(2)whensortedbytheirhiredate:
/*Querytolisttop-25%employeesbyhiredate*/
SELECT*
FROMt_fetch_first
ORDERBYhiredateFETCHFIRST25PERCENTROWONLY
/
EMPNODEPTNOSALHIREDATE
----------------------------
10320130020-JUN-00
10220110015-JUN-01
TheSELECTqueryskipsthefirstfiveemployeesanddisplaysthenexttwo—the6thand7themployeedata:
/*Querytolist2employeesafterskippingfirst5employees*/
SELECT*
FROMt_fetch_first
ORDERBYSALDESC
OFFSET5ROWSFETCHNEXT2ROWSONLY
/
InvisiblecolumnsOracleDatabase12csupportsinvisiblecolumns,whichimpliesthatausercancontrolthevisibilityofacolumn.Acolumnmarkedinvisibledoesnotappearinthefollowingoperations:
SELECT*FROMqueriesonthetableSQL*PlusDESCRIBEcommandLocalrecordsof%ROWTYPEOracleCallInterface(OCI)description
AcolumncanbemadeinvisiblebyspecifyingtheINVISIBLEclauseagainstthecolumn.Columnsofalltypes(exceptuser-definedtypes),includingvirtualcolumns,canbemarkedinvisible,providedthetablesarenottemporarytables,externaltables,orclustered.TheSELECTstatementcanexplicitlyselectaninvisiblecolumn.Similarly,theINSERTstatementwillnotinsertvaluesinaninvisiblecolumnunlessexplicitlyspecified.
Furthermore,atablecanbepartitionedbasedonaninvisiblecolumn.Acolumnretainsitsnullityfeatureevenafteritismadeinvisible.Aninvisiblecolumncanbemadevisible,buttheorderingofthecolumninthetablemaychange.
Inthefollowingscript,thecolumnNICKNAMEissetasinvisibleinthetablet_inv_col:
/*Createatabletodemonstrateinvisiblecolumns*/
CREATETABLEt_inv_col
(idNUMBER,
nameVARCHAR2(30),
nicknameVARCHAR2(10)INVISIBLE,
dobDATE
)
/
Theinformationabouttheinvisiblecolumnscanbefoundinuser_tab_cols.Notethattheinvisiblecolumnismarkedashidden:
/*QuerytheUSER_TAB_COLSformetadatainformation*/
SELECTcolumn_id,
column_name,
hidden_column
FROMuser_tab_cols
WHEREtable_name='T_INV_COL'
ORDERBYcolumn_id
/
COLUMN_IDCOLUMN_NAMEHID
-------------------------
1IDNO
2NAMENO
3DOBNO
NICKNAMEYES
Hiddencolumnsaredifferentfrominvisiblecolumns.Invisiblecolumnscanbemadevisibleandviceversa,buthiddencolumnscannotbemadevisible.
IfwetrytomaketheNICKNAMEvisibleandNAMEinvisible,observethechangeincolumnordering:
/*ScripttochangevisibilityofNICKNAMEcolumn*/
ALTERTABLEt_inv_colMODIFYnicknameVISIBLE
/
/*ScripttochangevisibilityofNAMEcolumn*/
ALTERTABLEt_inv_colMODIFYnameINVISIBLE
/
/*QuerytheUSER_TAB_COLSformetadatainformation*/
SELECTcolumn_id,
column_name,
hidden_column
FROMuser_tab_cols
WHEREtable_name='T_INV_COL'
ORDERBYcolumn_id
/
COLUMN_IDCOLUMN_NAMEHID
-------------------------
1IDNO
2DOBNO
3NICKNAMENO
NAMEYES
TemporaldatabasesTemporaldatabaseswerereleasedasanewfeatureinANSISQL:2011.Thetermtemporaldatacanbeunderstoodasapieceofinformationthatcanbeassociatedwithaperiodwithinwhichtheinformationisvalid.BeforethefeaturewasincludedinOracleDatabase12c,datawhosevalidityislinkedwithatimeperiodhadtobehandledeitherbytheapplicationorusingmultiplepredicatesinthequeries.Oracle12cpartiallyinheritsthefeaturefromtheANSISQL:2011standardtosupporttheentitieswhosebusinessvaliditycanbebracketedwithatimedimension.
ThetemporaldatabasefeatureinOracleDatabase12cisdifferentfromthetotalrecallfeatureinOracleDatabase11g.Thetotalrecallfeaturerecordsthetransactiontimeofthedatainthedatabasetosecurethetransactionvalidityandnotthefunctionalvalidity.Forexample,aninvestmentschemeisactivebetweenJanuarytoDecember.Thedaterecordedinthedatabaseatthetimeofdataloadingisthetransactiontimestamp.
TipStartingfromOracle12c,theTotalRecallfeaturehasbeenrebrandedasFlashbackDataArchiveandhasbeenmadeavailableforallversionsofOracleDatabase.
ThevalidtimetemporalfeaturecanbeenabledforatablebyaddingatimedimensionusingthePERIODFORclauseonthedateortimestampcolumnsofthetable.Thefollowingscriptcreatesatablet_tmp_dbwithvalidtimetemporal:
/*Createtablewithvalidtimetemporal*/
CREATETABLEt_tmp_db(
idNUMBER,
nameVARCHAR2(30),
policy_noVARCHAR2(50),
policy_termnumber,
pol_st_datedate,
pol_end_datedate,
PERIODFORpol_valid_time(pol_st_date,pol_end_date))
/
Createsomesampledatainthetable:
/*Inserttestdatainthetable*/
BEGIN
INSERTINTOt_tmp_db
VALUES(100,'Packt','PACKT_POL1',1,'01-JAN-2015','31-DEC-2015');
INSERTINTOt_tmp_db
VALUES(110,'Packt','PACKT_POL2',2,'01-JAN-2015','30-JUN-2015');
INSERTINTOt_tmp_db
VALUES(120,'Packt','PACKT_POL3',3,'01-JUL-2015','31-DEC-2015');
COMMIT;
END;
/
LetussetthecurrenttimeperiodwindowusingDBMS_FLASHBACK_ARCHIVE.GranttheEXECUTEprivilegeonthepackagetothescottuser.
/*Connecttosysdbatograntexecuteprivilegetoscott*/
connsys/oracleassysdba
GRANTEXECUTEONdbms_flashback_archivetoscott
/
Grantsucceeded.
/*Connecttoscott*/
connscott/tiger
/*SetthevalidtimeperiodasCURRENT*/
EXECDBMS_FLASHBACK_ARCHIVE.ENABLE_AT_VALID_TIME('CURRENT');
PL/SQLproceduresuccessfullycompleted.
SettingthevalidtimeperiodasCURRENTmeansthatallthetableswithavalidtimetemporalwillonlylisttherowsthatarevalidwithrespecttotoday’sdate.Youcansetthevalidtimetoaparticulardatetoo.
/*Querythetable*/
SELECT*fromt_tmp_db
/
IDPOLICY_NOPOL_ST_DATEPOL_END_DATE
---------------------------------------------------------------
100PACKT_POL101-JAN-1531-DEC-15
110PACKT_POL201-JAN-1530-JUN-15
TipDuetoadependencyonthecurrentdate,theresultmayvarywhenthereaderrunstheprecedingqueries.
ThequerylistsonlythosepoliciesthatareactiveasofMarch2015.Since,thethirdpolicystartsinJuly2015,itiscurrentlynotactive.
In-DatabaseArchivingOracleDatabase12cintroducesIn-DatabaseArchivingtoarchivethelowprioritydatainatable.Theinactivedataremainsinthedatabasebutisnotvisibletotheapplication.
Youcanmarkolddataforarchival,whichisnotactivelyrequiredintheapplicationexceptforregulatorypurposes.Althoughthearchiveddataisnotvisibletotheapplication,itisavailableforqueryingandmanipulation.Inaddition,thearchiveddatacanbecompressedtoimprovebackupperformance.
AtablecanbeenabledbyspecifyingtheROWARCHIVALclauseatthetablelevel,whichaddsahiddencolumnORA_ARCHIVE_STATEtothetablestructure.Thecolumnvaluemustbeupdatedtomarkarowforarchival.Forexample:
/*Createatablewithrowarchiving*/
CREATETABLEt_row_arch(
xnumber,
ynumber,
znumber)ROWARCHIVAL
/
WhenwequerythetablestructureintheUSER_TAB_COLSview,wefindanadditionalhiddencolumn,whichOracleimplicitlyaddstothetable:
/*Querythecolumnsinformationfromuser_tab_colsview*/
SELECTcolumn_id,column_name,data_type,hidden_column
FROMuser_tab_cols
WHEREtable_name='T_ROW_ARCH'
/
COLUMN_IDCOLUMN_NAME DATA_TYPEHID
-----------------------------------------
ORA_ARCHIVE_STATEVARCHAR2YES
1XNUMBERNO
2YNUMBERNO
3ZNUMBERNO
Letuscreatetestdatainthetable:
/Inserttestdatainthetable*/
BEGIN
INSERTINTOt_row_archVALUES(10,20,30);
INSERTINTOt_row_archVALUES(11,22,33);
INSERTINTOt_row_archVALUES(21,32,43);
INSERTINTOt_row_archVALUES(51,82,13);
commit;
END;
/
Fortestingpurpose,letusarchivetherowsinthetablewhereX>50byupdatingtheora_archive_statecolumn:
/*UpdateORA_ARCHIVE_STATEcolumninthetable*/
UPDATEt_row_arch
SETora_archive_state=1
WHEREx>50
/
COMMIT
/
Bydefault,thesessiondisplaysonlytheactiverecordsfromanarchival-enabledtable:
/*Querythetable*/
SELECT*
FROMt_row_arch
/
XYZ
------------------------
102030
112233
213243
Ifyouwishtodisplayalltherecords,changethesessionsetting:
/*Changethesessionparametertodisplaythearchivedrecords*/
ALTERSESSIONSETROWARCHIVALVISIBILITY=ALL
/
Sessionaltered.
/*Querythetable*/
SELECT*
FROMt_row_arch
/
XYZ
------------------------------
102030
112233
213243
518213
DefiningaPL/SQLsubprogramintheSELECTqueryandPRAGMAUDFOracleDatabase12cincludestwonewfeaturestoenhancetheperformanceoffunctionswhencalledfromSELECTstatements.WithOracle12c,aPL/SQLsubprogramcanbecreatedinlinewiththeSELECTqueryintheWITHclausedeclaration.ThefunctioncreatedintheWITHclausesubqueryisnotstoredinthedatabaseschemaandisavailableforuseonlyinthecurrentquery.SinceaprocedurecreatedintheWITHclausecannotbecalledfromtheSELECTquery,itcanbecalledinthefunctioncreatedinthedeclarationsection.Thefeaturecanbeveryhandyinread-onlydatabaseswherethedeveloperswerenotabletocreatePL/SQLwrappers.
OracleDatabase12caddsthenewPRAGMAUDFtocreateastandalonefunctionwiththesameobjective.
Earlier,theSELECTqueriescouldinvokeaPL/SQLfunction,providedthefunctiondidn’tchangethedatabasepuritystate.ThequeryperformancewoulddegradebecauseofthecontextswitchfromSQLtothePL/SQLengine(andviceversa)andthedifferentmemoryrepresentationsofdatatypeintheprocessingengines.
Inthefollowingexample,thefunctionfun_with_plsqlcalculatestheannualcompensationofanemployee
/*CreateafunctioninWITHclausedeclaration*/
WITHFUNCTIONfun_with_plsql(p_salNUMBER)RETURNNUMBERIS
BEGIN
RETURN(p_sal*12);
END;
SELECTename,deptno,fun_with_plsql(sal)"annual_sal"
FROMemp
/
ENAMEDEPTNOannual_sal
-----------------------------
SMITH209600
ALLEN3019200
WARD3015000
JONES2035700
MARTIN3015000
BLAKE3034200
CLARK1029400
SCOTT2036000
KING1060000
TURNER3018000
ADAMS2013200
JAMES3011400
FORD2036000
MILLER1015600
14rowsselected.
Note
IfthequerycontainingtheWITHclausedeclarationisnotatop-levelstatement,thenthetoplevelstatementmustusetheWITH_PLSQLhint.ThehintisusedifINSERT,UPDATE,orDELETEstatementsaretryingtouseaSELECTwithaWITHclausedefinition.FailuretoincludethehintresultsinanexceptionORA-32034:unsupporteduseofWITHclause.
AfunctioncanbecreatedwiththePRAGMAUDFtoinformthecompilerthatthefunctionisalwayscalledinaSELECTstatement.Notethatthestandalonefunctioncreatedinthefollowingcodecarriesthesamenameastheoneinthelastexample.ThelocalWITHclausedeclarationtakesprecedenceoverthestandalonefunctionintheschema.
/*CreateafunctionwithPRAGMAUDF*/
CREATEORREPLACEFUNCTIONfun_with_plsql(p_salNUMBER)
RETURNNUMBERis
PRAGMAUDF;
BEGIN
RETURN(p_sal*12);
END;
/
Sincetheobjectiveofthefeatureisperformance,letusgoaheadwithacasestudytocomparetheperformancewhenusingastandalonefunction,aPRAGMAUDFfunction,andaWITHclausedeclaredfunction.
TestsetupTheexerciseusesatesttablewith1millionrows,loadedwithrandomdata.
/*Createatableforperformanceteststudy*/
CREATETABLEt_fun_plsql
(idnumber,
strvarchar2(30))
/
/*Generateandloadrandomdatainthetable*/
INSERT/*+APPEND*/INTOt_fun_plsql
SELECTROWNUM,DBMS_RANDOM.STRING('X',20)
FROMdual
CONNECTBYLEVEL<=1000000
/
COMMIT
/
Case1:CreateaPL/SQLstandalonefunctionasitusedtobeuntilOracleDatabase12c.Thefunctioncountsthenumbersinthestrcolumnofthetable.
/*CreateastandalonefunctionwithoutOracle12cenhancements*/
CREATEORREPLACEFUNCTIONf_count_num(p_strVARCHAR2)
RETURNPLS_INTEGERIS
BEGIN
RETURN(REGEXP_COUNT(p_str,'\d'));
END;
/
ThePL/SQLblockmeasurestheelapsedandCPUtimewhenworkingwithapre-Oracle12cstandalonefunction.Thesenumberswillserveasthebaselineforourcase
study.
/*Setserveroutputontodisplaymessages*/
SETSERVEROUTPUTON
/*Anonymousblocktomeasureperformanceofastandalonefunction*/
DECLARE
l_el_timePLS_INTEGER;
l_cpu_timePLS_INTEGER;
CURSORC1IS
SELECTf_count_num(str)FROMt_fun_plsql;
TYPEt_tab_recISTABLEOFPLS_INTEGER;
l_tabt_tab_rec;
BEGIN
l_el_time:=DBMS_UTILITY.GET_TIME();
l_cpu_time:=DBMS_UTILITY.GET_CPU_TIME();
OPENc1;
FETCHc1BULKCOLLECTINTOl_tab;
CLOSEc1;
DBMS_OUTPUT.PUT_LINE('Case1:Performanceofastandalonefunction');
DBMS_OUTPUT.PUT_LINE('Totalelapsed
time:'||to_char(DBMS_UTILITY.GET_TIME()-l_el_time));
DBMS_OUTPUT.PUT_LINE('TotalCPU
time:'||to_char(DBMS_UTILITY.GET_CPU_TIME()-l_cpu_time));
END;
/
Performanceofastandalonefunction:
Totalelapsedtime:1559
TotalCPUtime:1366
PL/SQLproceduresuccessfullycompleted.
Case2:CreateaPL/SQLfunctionusingPRAGMAUDFtocountthenumbersinthestrcolumn.
/*CreatethefunctionwithPRAGMAUDF*/
CREATEORREPLACEFUNCTIONf_count_num_pragma(p_strVARCHAR2)
RETURNPLS_INTEGERIS
PRAGMAUDF;
BEGIN
RETURN(REGEXP_COUNT(p_str,'\d'));
END;
/
LetusnowchecktheperformanceofthePRAGMAUDFfunctionusingthefollowingPL/SQLblock.
/*Setserveroutputontodisplaymessages*/
SETSERVEROUTPUTON
/*AnonymousblocktomeasureperformanceofaPRAGMAUDFfunction*/
DECLARE
l_el_timePLS_INTEGER;
l_cpu_timePLS_INTEGER;
CURSORC1IS
SELECTf_count_num_pragma(str)FROMt_fun_plsql;
TYPEt_tab_recISTABLEOFPLS_INTEGER;
l_tabt_tab_rec;
BEGIN
l_el_time:=DBMS_UTILITY.GET_TIME();
l_cpu_time:=DBMS_UTILITY.GET_CPU_TIME();
OPENc1;
FETCHc1BULKCOLLECTINTOl_tab;
CLOSEc1;
DBMS_OUTPUT.PUT_LINE('Case2:PerformanceofaPRAGMAUDFfunction');
DBMS_OUTPUT.PUT_LINE('Totalelapsed
time:'||to_char(DBMS_UTILITY.GET_TIME()-l_el_time));
DBMS_OUTPUT.PUT_LINE('TotalCPU
time:'||to_char(DBMS_UTILITY.GET_CPU_TIME()-l_cpu_time));
END;
/
PerformanceofaPRAGMAUDFfunction:
Totalelapsedtime:664
TotalCPUtime:582
PL/SQLproceduresuccessfullycompleted.
Case3:ThefollowingPL/SQLblockdynamicallyexecutesthefunctionintheWITHclausesubquery.Notethat,unlikeotherSELECTstatements,aSELECTquerywithaWITHclausedeclarationcannotbeexecutedstaticallyinthebodyofaPL/SQLblock.
/*Setserveroutputontodisplaymessages*/
SETSERVEROUTPUTON
/*Anonymousblocktomeasureperformanceofinlinefunction*/
DECLARE
l_el_timePLS_INTEGER;
l_cpu_timePLS_INTEGER;
l_sqlVARCHAR2(32767);
c1sys_refcursor;
TYPEt_tab_recISTABLEOFPLS_INTEGER;
l_tabt_tab_rec;
BEGIN
l_el_time:=DBMS_UTILITY.get_time;
l_cpu_time:=DBMS_UTILITY.get_cpu_time;
l_sql:='WITHFUNCTIONf_count_num_with(p_strVARCHAR2)
RETURNNUMBERIS
BEGIN
RETURN(REGEXP_COUNT(p_str,'''||'\'||'d'||'''));
END;
SELECTf_count_num_with(str)FROMt_fun_plsql';
OPENc1FORl_sql;
FETCHc1bulkcollectINTOl_tab;
CLOSEc1;
DBMS_OUTPUT.PUT_LINE('Case3:Performanceofaninlinefunction');
DBMS_OUTPUT.PUT_LINE('Totalelapsed
time:'||to_char(DBMS_UTILITY.GET_TIME()-l_el_time));
DBMS_OUTPUT.PUT_LINE('TotalCPU
time:'||to_char(DBMS_UTILITY.GET_CPU_TIME()-l_cpu_time));
END;
/
Performanceofaninlinefunction:
Totalelapsedtime:830
TotalCPUtime:718
PL/SQLproceduresuccessfullycompleted.
ComparativeanalysisComparingtheresultsfromtheprecedingthreecases,it’sclearthattheOracle12cflavorofPL/SQLfunctionsout-performsthepre-12cstandalonefunctionbyahighmargin.Fromthefollowingmatrix,itisapparentthattheusageofthePRAGMAUDForWITHclausedeclarationenhancesthecodeperformanceby(roughly)afactorof2.
CaseDescription ElapsedTime
CPUtime
PerformancegainfactorbyCPUtime
StandalonePL/SQLfunctioninpre-Oracle12cdatabase 1559 1336 1x
StandalonePL/SQLPRAGMAUDFfunctioninOracle12c 664 582 2.3x
FunctioncreatedinWITHclausedeclarationinOracle12c 830 718 1.9x
NoteNotethatthenumbersmayslightlydifferinthereader’stestingenvironmentbutyoushouldbeabletodrawthesameconclusionbycomparingthem.
ThePL/SQLprogramunitwhitelistingPriortoOracle12c,astandaloneorpackagedPL/SQLunitcouldbeinvokedbyallotherprogramsinthesession’sschema.OracleDatabase12callowsuserstopreventunauthorizedaccesstoPL/SQLprogramunits.Youcannowspecifythelistofwhitelistprogramunitsthatcaninvokeaparticularprogram.ThePL/SQLprogramheaderorthepackagespecificationcanspecifythelistofprogramunitsintheACCESSIBLEBYclauseintheprogramheader.Allotherprogramunits,includingcross-schemareferences(evenSYSownedobjects),tryingtoaccessaprotectedsubprogramwillreceiveanexception,PLS-00904:insufficientprivilegestoaccessobject[objectname].
Thefeaturecanbeveryusefulinanextremelysensitivedevelopmentenvironment.Suppose,apackagePKG_FIN_PROCcontainsthesensitiveimplementationroutinesforfinancialinstitutions,thepackagedsubprogramsarecalledbyanotherPL/SQLpackagePKG_FIN_INTERNALS.TheAPIlayerexposesafixedlistofprogramsthroughapublicAPIcalledPKG_CLIENT_ACCESS.InordertorestrictaccesstothepackagedroutinesinPKG_FIN_PROC,theuserscanbuildasafetynetsoastoallowaccesstoonlyauthorizedprograms.
ThefollowingPL/SQLpackagePKG_FIN_PROCcontainstwosubprograms—P_FIN_QTR
andP_FIN_ANN.TheACCESSIBLEBYclauseincludesPKG_FIN_INTERNALSwhichmeansthatallotherprogramunits,includinganonymousPL/SQLblocks,areblockedfrominvokingPKG_FIN_PROCconstructs.
/*Packagewiththeaccessiblebyclause*/
CREATEORREPLACEPACKAGEpkg_fin_proc
ACCESSIBLEBY(PACKAGEpkg_fin_internals)
IS
PROCEDUREp_fin_qtr;
PROCEDUREp_fin_ann;
END;
/
TipTheACCESSIBLEBYclausecanbespecifiedforschema-levelprogramsonly.
Let’sseewhathappenswhenweinvokethepackagedsubprogramfromananonymousPL/SQLblock.
/*InvokethepackagedsubprogramfromthePL/SQLblock*/
BEGIN
pkg_fin_proc.p_fin_qtr;
END;
/
pkg_fin_proc.p_fin_qtr;
*
ERRORatline2:
ORA-06550:line2,column4:
PLS-00904:insufficientprivilegetoaccessobjectPKG_FIN_PROC
ORA-06550:line2,column4:
PL/SQL:Statementignored
Well,thecompilerthrowsanexceptionasinvokingthewhitelistedpackagefromananonymousblockisnotallowed.
TheACCESSIBLEBYclausecanbeincludedintheheaderinformationofPL/SQLproceduresandfunctions,packages,andobjecttypes.
GrantingrolestoPL/SQLprogramunitsBeforeOracleDatabase12c,aPL/SQLunitcreatedwiththedefiner’srights(defaultAUTHID)alwaysexecutedwiththedefiner’srights,whetherornottheinvokerhastherequiredprivileges.Itmayleadtoanunfairsituationwheretheinvokingusermayperformunwantedoperationswithoutneedingthecorrectsetofprivileges.Similarlyforaninvoker’srightunit,iftheinvokinguserpossessesahighersetofprivilegesthanthedefiner,hemightendupperformingunauthorizedoperations.
OracleDatabase12csecuresthedefiner’srightsbyallowingthedefiningusertograntcomplementaryrolestoindividualPL/SQLsubprogramsandpackages.Fromthesecuritystandpoint,thegrantingofrolestoschemalevelsubprograms,providesgranularcontrolastheprivilegesoftheinvokerarevalidatedatthetimeofexecution.
Inthefollowingexample,wewillcreatetwousers:U1andU2.TheuserU1createsaPL/SQLprocedureP_INC_PRICEthataddsasurchargetothepriceofaproductbyacertainamount.U1grantstheexecuteprivilegetouserU2.
TestsetupLet’screatetwousersandgivethemtherequiredprivileges.
/*Createauserwithapassword*/
CREATEUSERu1IDENTIFIEDBYu1
/
Usercreated.
/*Grantconnectprivilegestotheuser*/
GRANTCONNECT,RESOURCETOu1
/
Grantsucceeded.
/*Createauserwithapassword*/
CREATEUSERu2IDENTIFIEDBYu2
/
Usercreated.
/*Grantconnectprivilegestotheuser*/
GRANTCONNECT,RESOURCETOu2
/
Grantsucceeded.
TheuserU1containsthePRODUCTStable.Let’screateandpopulatethetable.
/*ConnecttoU1*/
CONNu1/u1
/*CreatethetablePRODUCTS*/
CREATETABLEproducts
(
prod_idINTEGER,
prod_nameVARCHAR2(30),
prod_catVARCHAR2(30),
priceINTEGER
)
/
/*Insertthetestdatainthetable*/
BEGIN
DELETEFROMproducts;
INSERTINTOproductsVALUES(101,'Milk','Dairy',20);
INSERTINTOproductsVALUES(102,'Cheese','Dairy',50);
INSERTINTOproductsVALUES(103,'Butter','Dairy',75);
INSERTINTOproductsVALUES(104,'Cream','Dairy',80);
INSERTINTOproductsVALUES(105,'Curd','Dairy',25);
COMMIT;
END;
/
Theprocedurep_inc_priceisdesignedtoincreasethepriceofaproductbyagivenamount.Notethattheprocedureiscreatedwiththedefiner’srights.
/*Createtheprocedurewiththedefiner'srights*/
CREATEORREPLACEPROCEDUREp_inc_price
(p_prod_idNUMBER,p_amtNUMBER)
IS
BEGIN
UPDATEproducts
SETprice=price+p_amt
WHEREprod_id=p_prod_id;
END;
/
TheuserU1grantsexecuteprivilegeonp_inc_pricetoU2.
/*GrantexecuteontheproceduretotheuserU2*/
GRANTEXECUTEONp_inc_priceTOU2
/
TheuserU2logsinandexecutestheprocedureP_INC_PRICEtoincreasethepriceofMilkby5units.
/*ConnecttoU2*/
CONNu2/u2
/*InvoketheprocedureP_INC_PRICEinaPL/SQLblock*/
BEGIN
U1.P_INC_PRICE(101,5);
COMMIT;
END;
/
PL/SQLproceduresuccessfullycompleted.
Thelastcodelistingexposesagrayarea.TheuserU2,thoughnotauthorizedtoviewPRODUCTSdata,manipulatesitsdatawiththedefiner’srights.
Weneedasolutiontotheproblem.Thefirststepistochangetheprocedurefromdefiner’s
rightstoinvoker’srights.
/*ConnecttoU1*/
CONNu1/u1
/*Modifytheprivilegeauthenticationfortheproceduretoinvoker's
rights*/
CREATEORREPLACEPROCEDUREp_inc_price
(p_prod_idNUMBER,p_amtNUMBER)
AUTHIDCURRENT_USER
IS
BEGIN
UPDATEproducts
SETprice=price+p_amt
WHEREprod_id=p_prod_id;
END;
/
Now,ifweexecutetheprocedurefromU2,itthrowsanexceptionbecauseitcouldn’tfindthePRODUCTStableinitsschema.
/*ConnecttoU2*/
CONNu2/u2
/*InvoketheprocedureP_INC_PRICEinaPL/SQLblock*/
BEGIN
U1.P_INC_PRICE(101,5);
COMMIT;
END;
/
BEGIN
*
ERRORatline1:
ORA-00942:tableorviewdoesnotexist
ORA-06512:at"U1.P_INC_PRICE",line5
ORA-06512:atline2
Inasimilarscenariointhepast,thedatabaseadministratorscouldhaveeasilygrantedselectorupdatedprivilegestoU2,whichisnotanoptimalsolutionfromasecuritystandpoint.Oracle12callowsuserstocreateprogramunitswithinvoker’srightsbutgranttherequiredrolestotheprogramunitsandnottheusers.So,aninvokerrightunitexecuteswithinvoker’sprivileges,plusthePL/SQLprogramrole.
Let’scheckoutthestepstocreatearoleandassignittotheprocedure.SYSDBAcreatestheroleandassignsittotheuserU1.UsingtheADMINorDELEGATEoptionwiththegrantenablestheusertogranttheroletootherentities.
/*ConnecttoSYSDBA*/
CONNsys/oracleassysdba
/*Createarole*/
CREATEROLEprod_role
/
/*GrantroletouserU1withdelegateoption*/
GRANTprod_roleTOU1WITHDELEGATEOPTION
/
Now,userU1assignstherequiredsetofprivilegestotherole.Theroleisthenassignedto
therequiredsubprogram.Notethatonlyroles,andnotindividualprivileges,canbeassignedtotheschemalevelsubprograms.
/*ConnecttoU1*/
CONNu1/u1
/*GrantSELECTandUPDATEprivilegesonPRODUCTStotherole*/
GRANTSELECT,UPDATEONPRODUCTSTOprod_role
/
/*Grantroletotheprocedure*/
GRANTprod_roleTOPROCEDUREp_inc_price
/
UserU2triestoexecutetheprocedureagain.Theprocedureissuccessfullyexecutedwhichmeansthevalueof“Milk”hasbeenincreasedby5units.
/*ConnecttoU2*/
CONNu2/u2
/*InvoketheprocedureP_INC_PRICEinaPL/SQLblock*/
BEGIN
U1.P_INC_PRICE(101,5);
COMMIT;
END;
/
PL/SQLproceduresuccessfullycompleted.
UserU1verifiestheresultwithaSELECTquery.
/*ConnecttoU1*/
CONNu1/u1
/*Querythetabletoverifythechange*/
SELECT*
FROMproducts
/
PROD_IDPROD_NAMEPROD_CATPRICE
----------------------------------------
101MilkDairy25
102CheeseDairy50
103ButterDairy75
104CreamDairy80
105CurdDairy25
MiscellaneousPL/SQLenhancementsBesidestheprecedingkeyfeatures,therearealotofnewfeaturesinOracle12c.Thelistoffeaturesisasfollows:
Aninvokerrightsfunctioncanberesult-cached—PriortoOracleDatabase12conlythedefiners’programswereallowedtocachetheirresults.Oracle12caddstheinvokinguser’sidentitytotheresultcachetomakeitindependentofthedefiner.ThecompilationparameterPLSQL_DEBUGhasbeendeprecated.Twoconditionalcompilationinquirydirectives$$PLSQL_UNIT_OWNERand$$PLSQL_UNIT_TYPEhavebeenimplemented.
TheOracleDatabase12c(12.1.0.2)In-MemoryoptionTheOracleDatabase12.1.0.2introducestheIn-Memoryoptionthathasthecapabilitytospeedupreal-timeanalyticsbyanorderofmagnitude.Thefasteranalyticscomplementsandenablesreal-timedecisionmaking.Long-runningreportsandad-hocanalyticalqueriesareexpectedtobenefitthemost.Thefeaturecanbeimplementedwithoutanyapplicationchangesandworkstransparentlywithnomanualhindrance,thusresultinginimprovedproductivity.
ThechallengeEnterpriseapplicationshavebeenreportedtohavemixedworkloads—thatis,OLTPworkloadsandanalyticsprocessing.Inthepast,therehavebeenacoupleofapproachestosegregatingtheworkloads.Mixedworkloadproductiondatabasescanrunonthesamesystem,butrunningbothofthemsimultaneouslywoulddegradetheOLTPperformance.Runningworkloadsonseparateserversystemsimpactsthereal-timedecisionmakingbecausedataontheanalyticsserverhastoberefreshedfromtimetotime.
TheproblemstatementandOracleDatabase12cIn-MemoryOracleDatabaseisatrustedrelationaldatabasemanagementsystemthatstoresdatainarowformat.Fortransactionaldatabases,datastoredinarowformatisamandatebecausetransactionsworkonarecordbasisandrequirealltheattributesofatableinasinglefetch.Ontheotherhand,dataanalyticsandreports,whichrunonfewcolumnsofdatawhilealsospanningmanyrows,workwellwiththecolumnarformat.Untilnow,enterpriseswereforcedtochooseeitherofthetwoformats.
OracleDatabase12cIn-Memoryallowsthedatabasetoberepresentedinarowformataswellasacolumnarformat,thusprovidingtheflavorofa“dual-format”architecturewithinthedatabase.Apieceofdatacanberepresentedinarowformataswellascolumnarformat.Thetransactionscontinuetofollowtherowformatofthedatawhiletheanalyticsworkloadworkwiththecolumnarformat.Theanalyticsgetmorereal-timeasthecolumnarformatacceleratesitbyanorderofmagnitude.Thebest-of-both-worldsstrategyisenabledbyswitchingontheIn-MemoryfeatureintheOracleDatabase.
TheIn-Memoryfeaturemarksamemoryarea(knownastheIn-MemoryColumnStore)withintheSystemGlobalArea(SGA).Thismemoryspaceisusedtoholdtheobjectsfrequentlyreferencedbytheanalyticsqueriesandreports.ItimpliesthatenablingtheIn-Memoryfeatureforadatabasedoesn’trequiredoublememoryrequirements.However,databasesmayrequiresomeadditionalmemorytoaccommodatetheiractiveobjectsintheIn-Memorystore.
OracleDatabase12cIn-MemoryoptionfeaturesTheOracleDatabase12cIn-Memoryfeaturewasreleasedasanoptioninthepatchsetrelease(12.1.0.2)ofOracleDatabase12cRelease1.Thefollowinglistoffeaturesincludessomemust-knowinformationaboutthisoption:
TheIn-Memorycolumnstoreisnotareplacementforthebuffercache;rather,itsupplementsit.In-MemoryColumnStoreisanewstaticpoolwithintheSystemGlobalArea(SGA).BeingIn-Memory,itisnon-persistentandnon-logging.ItisnotaffectedbyAutomaticMemoryManagementandtheresidentobjectsstaypopulateduntiltheyaremanuallyflushedout.AdministratorsorusersareauthorizedtoidentifythoseobjectswhichwhenpopulatedintheIn-Memorycolumnstore,wouldyieldthebestperformance.AllobjectsexceptIndexOrganizedTables,Clusteredtables,LONGcolumns,andOut-of-LineLOBscanbepopulatedintheIn-Memorycolumnstore.TheOracleDatabaseoptimizerisfullyawareoftheIn-memorystore;itdecideswhichquerywouldbenefitfromthebuffercacheorin-memorycolumnarstore.Itisalicensedoption,availablestartingfromOracleDatabase12.1.0.2Enterpriseedition.
TheOracleDatabase12cIn-MemoryArchitectureTheSystemGlobalAreacontainsanewstaticpool,knownastheIn-Memorycolumnstore.ThesegmentsthataremarkedandpopulatedintheIn-Memorycolumnstoreareorientedinthecolumnarformat.DivingdeepintothetechnicalaspectsofIn-Memorycolumnstore,thestaticpoolcomprisesoftwopools:theIMCU(or1MB)poolandtheSMU(or64KB)pool.TheIMCUpoolcomprisesIn-memorycompressionunits(IMCU)thatholdtheactualdatainacolumnarformat.ForeachIMCU,thereisaco-relatedSMUtostoretheIMCU’smetadataandatransactionjournal.Thedistributionof1MBand64KBpoolsarebasedcompletelyoninternalfactors.ThecurrentallocationcanbeviewedundertheV$INMEMORY_AREAdictionaryview.ThefollowingfigureshowsthearchitectureofSGAandtheIn-MemorycolumnstoreinOracleDatabase12c:
ControllingtheIn-MemorycolumnstoreTheIn-MemoryColumnStorecanbeconfiguredthroughanewsetofinitializationparameters,introducedinOracle12c.TheseparameterscontrolIn-Memorydynamicssuchassizing,theoptimizer’sbehavior,andworkerprocessestobedeployedforthepopulation.Hereisthelistofinitializationparameters:
INMEMORY_SIZE(default0):ThisconfigurestheIn-Memorystorebysettingthisparameterforaminimumof100MB.Thedatabasemustbebouncedforthechangestotakeeffect.INMEMORY_QUERY(defaultENABLE):ThisparametercontrolswhetherthequeriesshouldbeoptimizedusingtheIn-Memorystore.INMEMORY_MAX_POPULATE_SERVERS(default0):Configuresthenumberofworkerprocesses(max)tobeusedforIn-Memorycolumnstorepopulateoperations.INMEMORY_CLAUSE_DEFAULT:ThissetsthedefaultIn-Memoryclauseorsubclause.Bydefault,thevalueoftheclauseisNULL.INMEMORY_TRICKLE_REPOPULATE_SERVERS_PERCENT:Thissetsthepercentageofworkerprocessesthatcanperformtricklerepopulation.Thedefaultvalueoftheparameteris1%.INMEMORY_FORCE(defaultDEFAULT):SettingthistoOFFrestrictstheIn-memorycolumnstorepopulation.OPTIMIZER_INMEMORY_AWARE(defaultTRUE):ThiscontrolswhethertheoptimizershouldbeawareorunawareoftheIn-Memorycolumnstore.
TheINMEMORYclauseTheobjectsrequiredtobepopulatedintheIn-MemorycolumnstorecanhavetheadditionalINMEMORYclause.TheINMEMORYattributecanbespecifiedforatable,columns,partition,materializedview,oratablespace.InadditiontotheINMEMORYclause,thereareothersub-clausesforsomeimportantaspects,suchaspopulationpriorityandcompression.
ThefollowingIn-Memorysub-clausesareappliedbydefaultalongwiththeINMEMORYclause.Tooverridethedefaultbehavior,youmustspecifythedesiredvalue.
MEMCOMPRESS:Thesub-clausedeterminesthecompressionmodeofthein-memoryobjects.Theadmissiblecompressionmodesare:
NOMEMCOMPRESS:Nocompression.MEMCOMPRESSFORDML:Compressionforfrequentlytransactionalobjects.MEMCOMPRESSFORQUERYLOW(default):Balancedcompressionmodetooptimallycompressandensurespacesavings.Enhancesthequeryperformance.MEMCOMPRESSFORQUERYHIGH:Compressionmodethatfocusesonqueryperformancebutchecksthespacesavingstoo.MEMCOMPRESSFORCAPACITYLOW:Compressionmodeforoptimalspacesavings.MEMCOMPRESSFORCAPACITYHIGH:Compressionapproachisthehighestdegreeofspacesavings.
PRIORITY:ThePRIORITYsub-clausedetermineswhetheranobject,whichismarkedasINMEMORY,canbepopulatedautomaticallyormanually.TherearefivepossiblevaluesofPRIORITYclause:
CRITICAL:CriticalpriorityobjectsarepopulatedimmediatelyafterthedatabaseisopenedorthroughtheIn-MemoryCo-ordinator(IMCO)process’stimelywake-upHIGH:AfterthepopulationofCRITICALpriorityobjectscompletesandtheIn-MemorycolumnstorehasvacantspaceMEDIUM:AfterthepopulationofCRITICALandHIGHpriorityobjectscompletesandtheIn-memorycolumnstorehasvacantspaceLOW:AfterthepopulationofCRITICAL,HIGH,andMEDIUMpriorityobjectscompletesandtheIn-memorycolumnstorehasvacantspaceNONE(Default):TheNONEprioritysegmentsarepopulatedafterthefirstfullscan
DISTRIBUTE:TheDISTRIBUTEsub-clauseisusedinclusteredenvironments(OracleDatabaseRealApplicationCluster)todistributetheobjectdataacrosstheIn-MemoryColumnStoreonalltheclusternodes.DUPLICATE:TheDUPLICATEsub-clauseisexclusivelyforthemembersoftheOracleEngineeredSystemsfamily.ItallowstheduplicationoftheIn-memorycolumnstoreacrossselectiveorallnodesoftheclusterforhighavailability.
PerformanceoptimizationsOracleDatabaseIn-Memoryfeatureisdesignedforanalyticsperformance.Theoptimizationsthataccountforoverallperformanceareasfollows:
ColumnarFormatandVectorProcessing:Thecolumnformatenablesonlytherequiredcolumntobescanned,andnotthecompleterecord.ThecolumnformatsupportsSingleInstructionMultipleData(SIMD)processing,whichhelpsinprocessingmultipledatavaluesineachCPUinstruction.PredicateevaluationandJoinoperationspushdowntotheIn-Memorycolumnstore:PredicatescanbepusheddowntotheIMcolumnstoreforevaluation.TheIn-Memorycolumnstoremakesuseofbloomfilterstojoinmultipletablestogether.TheIn-Memorystorageindexprovidesmin-maxpruningthathelpsinpreventingtheIMCUsfromscanning:PredicatescanbecheckedagainsttheIMCUheader,whichmaintainsinformationaboutminimumandmaximumvalues.IthelpsindeterminingwhethertoscanorskipanIMCU.TheevaluationofaquerypredicatecanbeminimizediftheIMCUheadersatisfiesthepredicate:IftheIMCUheaderfullyorpartiallysatisfiesthepredicatecondition,thepredicateevaluationcanbepreventedorreducedforthecolumnarunits.
In-MemoryAdvisorForlargeapplicationdatabases,choosingthemostsuitableobjectstobepopulatedintheIn-MemoryColumnStorecanbeachallenge.OracleprovidesanIn-MemoryAdvisorkittorecommendthoseobjectswhosein-memoryformatwillyieldthemaximumbenefits.ThetoolanalysesthedatabaseworkloadthroughAutomaticWorkloadRepository(AWR)andActiveSessionHistory(ASH)repositories,plancardinalities,andparallelexecution.Oncetheanalysisiscompleted,itgeneratesHTMLadvisoryreports.Thereportsprovidethelistofobjectsthatwouldbenefitthemost,whenplacedintheIn-Memorycolumnstore.
TheIn-MemoryAdvisorispartofOracleTuningPackandcanbeinstalledinOracleDatabase11.2.0.3andabove.
OracleDatabaseIn-MemorybenefitsOracleDatabase12cIn-Memoryoffersadual-formatarchitecturetosupportmixedworkloads.Anobjectcanberepresentedinrowformataswellascolumnarformat.Thecolumnarformatisread-consistentandtransactional-consistentwiththedataondisk.TheIn-MemoryfeatureisembeddednativelyintheOracleDatabase.Therefore,itissupportedonallOracleDatabase-supportedplatforms.Also,itiscompatiblewithalldatabasetechnologiessuchasRealApplicationClusters,Multitenant,HighAvailability,andExadataEngineeredSystems.
SummaryThischapterfamiliarizesthereaderswithanoverviewofOracleDatabase12c.Thischapterprovidesvaluableinsighttodatabasedevelopersintheapplicationdevelopmentspace.Also,thechaptercoversthetopratedfeaturesofOracleDatabase12c,thatisMultitenantandDatabaseIn-Memory.Thischapterwillhelpyouunderstandthebasicbuildingblocksofamultitenantcontainerdatabase.
Inthenextchapter,wewillcoverthefundamentalsofPL/SQLcodedesignthroughcursors.
Chapter3.DesigningPL/SQLCodeThestructureofaPL/SQLblockisoneoftheelementarycomponentsofPL/SQLasitshowcasesitsmodelingcapabilities.Itenablesuserstodeclarevariables,includeproceduralconstructsintheexecutablesection,andembedexceptionmanagementwithintheprogram.
AllSQLstatementswithinaPL/SQLblockareexecutedasacursor.CursorsarePL/SQLconstructsthatenableinteractionwiththedatawithinaPL/SQLblock.CursordesigningisanimportantskillinPL/SQLprogrammingasitimpactsthedataaccessparadigmandalsocodeperformance.Inthischapter,wearegoingtofocusourdiscussiononcursors.Hereisthechapteroutline:
Cursorfundamentals
1. Howcursorswork?2. Implicitandexplicitcursors3. Cursorattributes4. Cursordesignguidelines
CursorvariablesImplicitREFCURSORparameterbindingIntroductiontosubtypes
CursorstructuresInPL/SQL,acursorstructureallowstheprocessingofaSELECTstatementandaccessestheresultreturnedbythatquery.EachandeverySQLstatementinaPL/SQLblockisacursor.AcursorisahandletothechunkofthememoryareawheretheSQLstatementsareprocessedandtheresultisstored.Foradedicateddatabase,thechunkofmemoryisintheUserGlobalArea(UGA)while,forsharedserverconnections,thecursorcontextareaisallocatedintheSystemGlobalArea(SGA).
Cursorscanbeoftwotypes:
Implicitcursors:EverySQLqueryintheexecutableorexceptionsectionofaPL/SQLblockisanimplicitcursor.SELECT..INTO,SELECT..BULKCOLLECTINTO,SELECTinCURSORFORloop,INSERT,UPDATE,DELETE,andMERGEareimplicitcursors.Explicitcursors:AcursordefinedbytheuserordeveloperinthedeclarationsectionofaPL/SQLprogramisanexplicitcursor.
CursorexecutioncycleAcursorisahandlertoexecuteanSQLqueryandlivesforthelifeofasession.Oncethecurrentsessionends,thecursornolongerexists.Afterthecursorgetscreatedimplicitlyorexplicitly,itgoesthroughthefollowingstagesofexecution.
OPEN:Assoonasthecursorgetscreated,Oracleallocatesaprivateareainthesession’suserglobalarea(UGA).ThisprivateareaisusedforSQLstatementprocessing.Priortoopeningacursor,itremainsasanullpointervariable.
NoteTheinitializationparameterOPEN_CURSORSgovernsthemaximumnumberofcursors(fromthelibrarycache)thatcanbeopenedinasession.
PARSE:OraclecheckstheSQLstatementforthesyntacticalcorrectness,semantics,andprivileges.BIND:IftheSQLstatementneedsadditionalinputvaluesforprocessing,therespectiveplaceholdersarereplacedbyactualvalues.EXECUTE:TheSQLstatementisexecutedfollowingtheconventionalexecutionprocess.OraclegeneratesthehashvaluefortheSQLstatementsandplacesitinthesharedpool.OraclealsoperformslibrarycachelookuptosearchforanypastexecutionsofthesameSQL.AsuccessfullookupinthelibrarycacheavoidshardparsingofSQLstatement.Ifthehashisnotfound,anewexecutionplanisgeneratedandtheSQLisprocessed.OncetheSQLqueryisexecuted,theresultsetisplacedintheUGA.FETCH:Fetchtherecordfromtheresultsetcorrespondingtothecurrentpositionoftherecordpointer.Therecordpointerleapsforwardbyoneaftereverysuccessfulfetch.CLOSE:Thecursorhandleisclosedandtheprivatecontextareaisflushedout.
YoucanquerytheV$OPEN_CURSORviewtogetthelistofcursorsusedinthecurrentsession.LetusexecutethefollowingPL/SQLanonymousblockandchecktheentriesinV$OPEN_CURSOR:
connectscott/tiger
/*DeclareaquickPL/SQLblock*/
DECLARE
count_empNUMBER;
count_depNUMBER;
BEGIN
/*Createtwoimplicitcursors*/
SELECTCOUNT(*)INTOcount_empFROMemp;
SELECTCOUNT(*)INTOcount_depFROMdept;
END;
/
PL/SQLproceduresuccessfullycompleted.
LetusquerytheV$OPEN_CURSORviewtochecktheopenandPL/SQLcachedcursors:
connsys/oracleassysdba
SELECTcursor_type,
sql_text
FROMv$open_cursor
WHEREuser_name='SCOTT'
ANDcursor_type!='DICTIONARYLOOKUPCURSORCACHED'
ORDERBYcursor_type
/
CURSOR_TYPESQL_TEXT
-----------------------------------------------------
OPENdeclarecount_recnumber;be
inselectcount(*)intocount
PL/SQLCURSORCACHEDSELECTCOUNT(*)FROMDEPT
PL/SQLCURSORCACHEDSELECTCOUNT(*)FROMEMP
Intheprecedingoutput,thetwoSELECTqueries(orimplicitcursorsofthePL/SQLblock)arePL/SQLcursor-cachedwhilethePL/SQLblockisintheOPENstate.
CursorattributesCursorattributesrevealthenecessaryinformationaboutthelastactivecursor.Cursorattributesarenotpersistedinthedatabasebutarealignedalongwiththequeryresultsetinthesessionmemory.Theseattributesare%ROWCOUNT,%ISOPEN,%FOUND,and%NOTFOUND.
Note%BULK_ROWCOUNTand%BULK_EXCEPTIONSareadditionalcursorattributesusedinbulkprocessingusingtheFORALLstatement.
Thecursorattributesarebrieflyexplainedasbelow:
%ROWCOUNT:TheattributereturnsthenumberofrowsfetchedoraffectedbytheSQLstatementinthecontextarea.Itmustbereferencedwithinthecursorexecutioncycle.Ifreferencedoutside,itraisestheINVALID_CURSORexception.%ISOPEN:TheattributeissettoTRUEifthecursoriscurrentlyopen;otherwiseitisFALSE.Programmersusethisattributeoutsidethecursorexecutioncycletocheckifthecursorisopenorclosed.%FOUND:TheattributereturnsTRUEiftherowpointerpointstoavalidrecord.Afterthelastrecordoftheresultsetisreached,theattributeissettoFALSE.%NOTFOUND:Theattributereturnsthereverseofthe%FOUNDattribute.
ImplicitcursorsEverySQLstatementintheexecutableorexceptionsectionofaPL/SQLblockisanimplicitcursor.Thedatabasetakesfullchargeofitsentireexecutioncycle,meaningthattheimplicitcursorisauto-created,auto-opened,auto-fetched,andauto-closed.AllofthesestepsaretakencarebytheOracleDatabase.SQLstatementscanbeSELECT,INSERT,UPDATE,DELETE,orMERGE,thusmakinganimplicitcursoranSQLcursor.
TheSELECTstatementforminganimplicitcursorisexpectedtoreturnexactlyonerow.Ifitfailstoreturnasinglerow,theimplicitcursorraisesTOO_MANY_ROWSorNO_DATA_FOUNDexception.Exceptionscanbetrappedandhandledwithaninformationalmessage.IfthecursorSQLisexpectedtoreturnmorethanonerow,youmustcreateanexplicitcursor.
NotethatSQL%prefixesthecursorattributesforimplicitcursors.
Cursorattributes Description
SQL%FOUNDThisattributereturnsTRUEifSELECTfetchesasinglerowortheDMLstatementaffectsaminimumofonerowinthetable.Otherwise,itissetasFALSE.
SQL%NOTFOUNDThisattributereturnsTRUEifSELECT…INTOfetchesnorowfromthedatabase.YoumightencounterNO_DATA_FOUNDexception.
SQL%ROWCOUNT
Thisattributereturns1fortheSELECTstatement.ForDMLstatements,itreturnsthenumberofrowsaffectedbytheDML.
However,theattributevalueisindependentofthetransactionstate.Ifthetransactionisrolledbacktoasavepoint,theattributevalueisnotrestoredtotheonebeforerollbackwasissued.
SQL%ISOPEN AlwaysFALSEforimplicitcursors.
NoteInOracleDatabase12c,themaximumnumberreturnedbySQL%ROWCOUNTis4,294,967,295.
ThefollowingPL/SQLblockcontainsaSELECT…INTOstatementintheexecutablesectionoftheblock:
/*EnabletheSERVEROUTPUTtoprinttheresults*/
SETSERVEROUTPUTON
/*DemonstrateimplicitcursorinPL/SQLexecutionblock*/
DECLARE
l_enameemp.ename%TYPE;
l_salemp.sal%TYPE;
BEGIN
/*Selectnameandsalaryofemployee7369*/
SELECTename,sal
INTOl_ename,l_sal
FROMemp
WHEREempno=7369;
DBMS_OUTPUT.PUT_LINE('Rowsselected:'||SQL%ROWCOUNT);
END;
/
Rowsselected:1
PL/SQLproceduresuccessfullycompleted.
TheprecedingPL/SQLblockreturns1becauseempnoistheprimarykeyintheemptableandthereexistsonlyonerowagainstthevalue7369.
Nowletustrytoupdateamulti-rowdatasetintheemployeestable.ThefollowingPL/SQLblockincreasesthesalaryofemployeeswhoareworkingindepartment10:
/*EnabletheSERVEROUTPUTtoprinttheresults*/
SETSERVEROUTPUTON
/*DemonstratethecursorattributeduringDMLinaPL/SQLblock*/
BEGIN
/*Increasethesalaryofemployeesfromdepartment10*/
UPDATEemp
SETsal=sal+1000
WHEREdeptno=10;
DBMS_OUTPUT.PUT_LINE('Rowsupdated:'||SQL%ROWCOUNT);
END;
/
Rowsupdated:3
PL/SQLproceduresuccessfullycompleted.
ExplicitcursorsApplicationdeveloperscanchoosetocreateacursormanually,performopenandfetchoperations,andclosethecursor.Suchcursorsareknownasexplicitcursors.Theyaremoredeveloper-friendlyastheyallowuserstomanagetheirexecutionstagesand,mostimportantly,handlemulti-rowdatasets.
AnexplicitcursorcanbeassociatedwithSELECTqueriesonly.Thecursorprototype,definedintheDECLAREsectionofaPL/SQLblock,shouldcontainavalidname.ThefollowingPL/SQLblockshowsthecursorprototypingandhandlingstagesintheexecutablesection.
DECLARE
CURSOR[CursorName][Parameters]
RETURN[Returntype]
IS
[SELECTstatement];
BEGIN
OPEN[CursorName];
FETCH…INTO[scalarorcompositevariables];
CLOSE[CursorName];
END;
IntheexecutablesectionofaPL/SQLblock,auserhastoopenacursorasOPEN[cursorname].ThedatacanbefetchedusingFETCH[cursorname]INTO[variablesorrecordvariable].Oncethefetchoperationisover,acursorcanbeclosedusingtheCLOSE[cursorname]statement.Hereiswhathappensateachofthesestages:
OPENstage:
1. Opencursor:Itallocatesaprivateworkareaintheuser’ssessionmemoryforcursorprocessing.
2. ParseSQL:ItvalidatestheSQLqueryforsyntaxandprivileges.3. BindSQL:Thisprovidesaninputvaluetothebindvariablesinthequery.4. Executethequery:ItexecutestheparsedSQLstatement.
FETCHstage:Thisstageiteratesthedatasetforeachfetchrequest.Itfetchesthedataintoblockvariables(orrecords)andincrementstherecordpointer.CLOSEstage:ThisstageclosesthecursorandreleasesthememorybacktoSGA.
Oraclesupportsparameterizationofexplicitcursors.IfaSELECTstatementhastobeexecutedwiththesamepredicatesbutdifferentvalues,itisadvisabletouseparameterizedcursors.Parameterizationofacursorisapowerfulprogrammingfeatureasitcanimprovecodingstandardsbyreducingthenumberofexplicitcursorconstructsinaprogram.
Structurally,aparameterizedcursorisanexplicitcursorwithparameters.Parametersmayormaynothavedefaultvalues.Thedevelopersuppliestheparametervaluesatthetimeofopeningthecursorintheprogrambody.Optionally,youcanalsostronglyprototypeaparameterizedcursorbyspecifyingRETURNclause.Thefollowingcursordefinitiontakesthedepartmentnumberasaparameter:
/*Cursortofetchemployeedetailsfromadepartment*/
CURSORCUR_EMP(P_DEPTNONUMBER)
IS
SELECT*
FROMemp
WHEREdeptno=P_DEPTNO;
Youcanalsospecifydefaultvalueforthecursorparameters.Forexample:
/*Cursortofetchemployeedetailsfromadepartment*/
CURSORCUR_EMP(P_DEPTNONUMBERDEFAULT10)
IS
SELECT*
FROMemp
WHEREdeptno=P_DEPTNO;
Youcanrestrictthestructureofcursorreturntypetoprotectitsaccess.
/*Cursortofetchemployeedetailsfromadepartment*/
CURSORCUR_EMP(P_DEPTNONUMBER)
RETURNemp%ROWTYPE
IS
SELECT*
FROMemp
WHEREdeptno=P_DEPTNO;
Ifyouwishtoperformatransaction(updateordelete)onacursorresultset,youcanusetheWHERECURRENTOFclauseinaDMLstatement.TheWHERECURRENTOFclauseupdatesordeletesathecurrentrowofthecursorresultset.ItismandatorytodeclarethecursorwithaSELECTFORUPDATEquerytosecurearow-levelexclusivelockonthecursorresultset.Thelockisreleasedonlyafterthetransactioniscommittedorrolledback.
Forexample,thecursorcur_inc_comminthefollowingPL/SQLblocklockstheemployeerecordsinthecursorresultset.TheUPDATEstatementmodifiestheemployee’scommission.
DECLARE
CURSORcur_inc_commIS
SELECTempno,comm
FROMemp
FORUPDATEOFcomm;
BEGIN
FORiINcur_inc_comm
LOOP
UPDATEemp
SETcomm=comm*1.2
WHERECURRENTOFcur_inc_comm;
ENDLOOP;
END;
/
NotethatyoucanreproducetheWHERECURRENTOFscenariobyusingtheROWIDpseudocolumn.
Cursorattributesplayakeyroleinaccessingtheexplicitcursorexecutioncycle.Theattributesareauto-setateachstageandthefollowingtableshowsthebehavioralflow:
Event %FOUND %NOTFOUND %ISOPEN %ROWCOUNT
BeforeOPEN Exception Exception FALSE Exception
AfterOPEN NULL NULL TRUE 0
BeforethefirstFETCH NULL NULL TRUE 0
AfterthefirstFETCH TRUE FALSE TRUE 1
BeforethenextFETCH TRUE FALSE TRUE 1
AfterthenextFETCH TRUE FALSE TRUE n+1
BeforethelastFETCH TRUE FALSE TRUE n+1
AfterthelastFETCH FALSE TRUE TRUE n+1
BeforeCLOSE FALSE TRUE TRUE n+1
AfterCLOSE Exception Exception FALSE Exception
CursorvariablesAcursorvariableenablesacursorhandlertobeassociatedwithmultipleSQLqueries.Withrespecttofunctionality,itissimilartoanexplicitcursorbutwithcertainimplementationchanges.Oneofthefundamentaldifferencesisthat,unlikeacursor,itisavariableofacursortype.Therefore,itcanpotentiallybereferencedinasimilarwaytootherprogramvariables.
Asavariable,itcanbepassedasaparametertosubprogramsorusedasareturntypeofaPL/SQLfunction.Cursorvariablescanbequitehandywhensharingresultsetsbetweentwosubprogramsorwhenaclientpullsadatasetfromthedatabase.
CursorvariablesarecreatedbydefiningavariableoftheREFCURSORtypevariableoranSYS_REFCURSORtypevariable.
NoteCursorFORloopdoesnotsupportcursorvariables
TheREFCURSORsyntaxisasfollows:
TYPE[CURSORVARIABLENAME]ISREFCURSOR[RETURN(returntype)]
Intheprecedingsyntax,theRETURNtypeofacursorvariablemustbearecordtype.Itisrequiredinstrongrefcursorstofixthereturntypeoftheresultset.
Inthefollowingexample,thePL/SQLblockdeclaresarefcursorasacursortypeandasubsequentcursorvariable.WewillopenthecursorvariablesfordifferentSELECTstatementsinseparateexecutioncycles.
/*EnabletheSERVEROUTPUTparametertoprinttheresults*/
SETSERVEROUTPUTON
DECLARE
/*DeclareaREFcursortype*/
TYPEC_REFISREFCURSOR;
/*DeclareaCursorvariableofREFcursortype*/
CURC_REF;
l_enameemp.ename%TYPE;
l_salemp.sal%TYPE;
l_deptnodept.deptno%TYPE;
l_dnamedept.dname%TYPE;
BEGIN
/*OpenthecursorvariableforfirstSELECTstatement*/
OPENcurFOR
SELECTename,sal
FROMemp
WHEREename='JAMES';
FETCHcurINTOl_ename,l_sal;
CLOSEcur;
DBMS_OUTPUT.PUT_LINE('Salaryof'||L_ENAME||'is'||L_SAL);
/*ReopenthecursorvariableforsecondSELECTstatement*/
OPENcurFOR
SELECTdeptno,dname
FROMdept
WHEREloc='DALLAS';
FETCHcurINTOl_deptno,l_dname;
CLOSEcur;
DBMS_OUTPUT.PUT_LINE('Departmentname'||l_dname||'for'||l_deptno);
END;
/
SalaryofJAMESis950
DepartmentnameRESEARCHfor20
PL/SQLproceduresuccessfullycompleted.
StrongandweakrefcursortypesAREFCURSORcanbetypedeitherstrongorweak.
AREFCURSORisstrongifitsreturntypeisfixedatthetimeofdeclaration.TheRETURNclauseisusedtospecifytherecordtype.AstrongrefcursorcanbeopenedforaSELECTstatement,whichreturnsthespecifiedrecordtype.
Forexample,astrongrefcursorhavingthereturntyperecordstructureoftheemployeestable:
TYPEc_strong_rfISREFCURSORRETURNemp%ROWTYPE;
Auser-definedrecordcanbedeclaredandassignedasthereturntypeofastrongrefcursor.ThefollowingPL/SQLdeclaresalocalrecordandcursorvariableoftheREFCURSORtype.
/*Demonstratethestrongrefcursorwheretypeisalocalrecord
structure*/
DECLARE
TYPEmyrecISRECORD
(mynameVARCHAR2(10),
myclassVARCHAR2(10));
TYPEmycurISREFCURSORRETURNmyrec;
cur_varmycur;
AREFCURSORwithoutareturntypemakesitweakandSELECTstatementswithadifferentnumberofprojectedcolumnscanbeassociatedwithit.
Thecursorattributesofacursorvariablearesameasthoseofanexplicitcursor.
WorkingwithcursorvariablesBynow,youmayhaverealizedthattheexecutioncycleofacursorvariableisthesameasthatofanexplicitcursor.OnceopenedforaSELECTquery,therecordscanbefetchedbeforethecursorisclosed.
ThefollowingPL/SQLblockdeclaresastrongcursorvariablethatreturnsarecordofEMPrecordtype,butthecursorvariableisopenedforadifferentrecordstructure(DEPTrecordtype).TheblockfailstocompileandraisesaPLSexception.
/*EnabletheSERVEROUTPUTparametertoprinttheresults*/
SETSERVEROUTON
/*Demonstratetheusageofcursorvariable*/
DECLARE
/*Declarethelocalvariables*/
l_emp_detailsemp%ROWTYPE;
l_row_numnumber;
l_random_strvarchar2(20);
/*Declarearefcursoranditsvariable*/
TYPEc_typeISREFCURSORRETURNemp%ROWTYPE;
cur_varc_type;
BEGIN
/*OpenthecursorforSELECTqueryonDEPTtable*/
OPENcur_varFOR
SELECT*
FROMdept;
/*Iteratetheresultsettodisplaythefetchcount*/
LOOP
FETCHcur_varINTOl_emp_details;
EXITWHENcur_var%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Displayresults='||cur_var%rowcount);
ENDLOOP;
/*Closethecursorvariable*/
CLOSEcur_var;
END;
/
SELECT*
*
ERRORatline16:
ORA-06550:line16,column5:
PLS-00382:expressionisofwrongtype
ORA-06550:line15,column3:
PL/SQL:SQLstatementignored.
Ifthecursorvariableisopenedforaquerywhoserecordstructurehasfewerattributesthantherefcursor’sreturnrecord,itraisestheprecedingexception.Ifthelatterhasmore,itraisesPLS-00394:wrongnumberofvaluesintheINTOlistofaFETCHstatement.
SYS_REFCURSORSYS_REFCURSORisanOraclebuilt-incursorvariabledatatypethatdeclaresaweakREFCURSORvariablewithoutdeclaringtherefpointertype.ThegenericcursorvariableisextensivelyusedwhenpassingacursorvariableasaparameterinstoredsubprogramswiththereturntypeofaPL/SQLfunction.
SYS_REFCURSORactsasacursorvariabletypeinthefollowingsyntax:
DECLARE
[Cursorvariablename]SYS_REFCURSOR;
YoucanuseSYS_REFCURSORasparametertypeinOraclesubprogramsshownbelow:
PROCEDUREP_DEMO(P_DATAOUTSYS_REFCURSOR)
IS…
...
END;
CursorvariablesasargumentsAcursorvariablecanbepassedasaformalparametertoaPL/SQLsubprogram.Subprogramscansharethepointervariabletoaccesstheresultsetsbetweenthem.
Thefollowingprocedureacceptsthedepartmentnumberasaninputanddisplaysthesalaryline-graphsortedbyjobcodes:
/*Procedureusingcursorvariableasformalparameter*/
CREATEORREPLACEPROCEDURE
p_sal_graph(p_deptNUMBER,p_emp_dataOUTSYS_REFCURSOR)
IS
/*Declarealocalrefcursorvariable*/
TYPEcur_empISREFCURSOR;
cur_salcur_emp;
BEGIN
/*OpenthelocalrefcursorvariablefortheSELECTquery*/
OPENcur_salFOR
SELECTempno,job,LPAD('*',sal/100,'.')graph
FROMemp
WHEREdeptno=P_DEPT
ORDERBYjob;
/*AssignthecursorOUTparameterwiththelocalcursorvariable*/
p_emp_data:=cur_sal;
END;
/
Procedurecreated.
/*DeclareahostcursorvariableinSQL*PLUS*/
VARIABLEM_EMP_SALREFCURSOR;
/*ExecutetheprocedureP_SAL_GRAPH*/
EXECP_SAL_GRAPH(30,:M_EMP_SAL);
PL/SQLproceduresuccessfullycompleted.
/*Printthehostcursorvariable*/
PRINTM_EMP_SAL
EMPNOJOBGRAPH
-------------------------------------------------------------
7900CLERK........*
7698MANAGER...........................*
7844SALESMAN..............*
7521SALESMAN...........*
7499SALESMAN...............*
7654SALESMAN...........*
6rowsselected.
Cursorvariables–restrictionsThefollowinglistshowstherestrictionsontheusageofcursorvariables:
CursorvariablescannotbedeclaredasthepublicconstructinapackagespecificationCursorvariablescannotbesharedremotelyacrossserversCursorvariablescannotbeopenedforaSELECTFORUPDATEqueryCursorvariablesarenotphysicallystoredintheOracleDatabaseCursorvariablescannotbeassignedtoNULL
CursordesignconsiderationsThefactorsthatcanimpactthecursordesignareasfollows:
ImplicitversusExplicitcursor:IfaSELECTqueryisconfirmedtoreturnonlyonerecord,itshouldbeusedasSELECT…INTO,thusmakinganimplicitcursor.Anotherconsiderationcouldbecursorre-usabilityasimplicitcursorsarefasterthanexplicitcursors.UseParameterizedcursors:ExplicitcursordesigndependsonwhetherornotacursorwillbereusedinaPL/SQLblock.Ifthecursorqueryisexpectedtobere-runforsimilarpredicatesbutdifferentinputvalues,itcanbemadeparameterized.Parameterizedcursorsenhancethereusabilityofacursor.
Thequeryinthefollowingcursordefinitionfiltersemployeerecordsbytheirhiredate:
CURSORcurIS
SELECTename,deptno
FROMemp
WHEREhiredate<TO_DATE('01-01-1985','DD-MM-YYYY');
Ifthequerystandstobereusedwithinthesameprogram,itcanbeparameterized:
CURSORcur(p_dateDATE)IS
SELECTename,deptno
FROMemp
WHEREhiredate<p_date;
Usageofcursorvariables:AcursorvariableofREFCURSORcanbedynamicallyassociatedwithmultipleSQLqueries.
Cursordesign–guidelinesHerearesomeofthebestpracticesthatcanbefollowedduringapplicationdevelopmenttomakethebestuseofcursors.
Useaparameterizedcursoriftheexplicitcursorhastobeopenedmultipletimesfordifferentinputvalues.Youshouldfollowthecompleteexecutioncycleofthecursor.Anexplicitcursormustbeopened,fetched,andclosed.Ifitisnotclosed,thecursorresources(datastructures)arenotclearedfromtheUGA,untiltheblockexecutionisover.Exceptfor%ISOPEN,allthecursorattributesmustbereferencedwithinthecursorexecutioncycle.Italsoholdstrueforimplicitcursors.Useof%ROWTYPEmustbeencouragedtofetcharecordfromthecursorresultset.Itnotonlyreducestheoverheadofmaintainingmultiplelocalvariables,butitalsoinheritsthestructureoftheSELECTcolumnlist.Forexample,considerthefollowingcodesnippet:
/*Cursortoselectemployeeswithitsannualsalary*/
CURSORcur_deptIS
SELECTename,deptno,(sal*12)annual_sal
FROMemp;
l_cur_deptcur_dept%ROWTYPE;
Notethatthecolumnsthatarecreatedvirtuallyforcalculativepurposesmusthaveanaliasnameforreferencethroughtherecordvariable.
AcursorFORloopassociatesacursorwiththeFORloopconstruct.ItisapowerfulfeatureinPL/SQLtosimplifyandenhancecodewritingtechniques.ItimplicitlytakescareofallthestagesofcursorexecutionsuchasOPEN,FETCH,andCLOSE.
/*DemonstrateworkingwithcursorFORloop*/
DECLARE
CURSORcur_deptIS
SELECTename,deptno
FROMemp;
BEGIN
FORcINcur_dept
LOOP
…
ENDLOOP;
END;
ImplicitstatementresultsinOracleDatabase12cOracleDatabase12callowsastoredsubprogramtoreturnaresultsetimplicitlyusingtheDBMS_SQLpackage,andnotjustthroughtheREFCURSORvariable.Thenewfunctionalityisdesignedtoeasethemigrationofnon-OracleapplicationprogramstoOracle.
PriortothisenhancementinOracleDatabase12c,theonlywayaPL/SQLstoredsubprogramcouldsharearesultsetwasthroughOUTREFCURSORparameters.Later,parameterbindingwasrequiredattheclientendtoretrievetheresultsets.
Thecursorisreturnedtothecallingenvironmentusingnewoverloadedsubprograms:RETURN_RESULTandGET_NEXT_RESULT.TheGET_NEXT_RESULTcanbeusedifthecursorqueryreturnsmultipleresultsets.TheprototypeforRETURN_RESULTisasfollows:
PROCEDURERETURN_RESULT(param_resINOUTSYS_REFCURSOR,
to_clientINBOOLEANDEFAULTTRUE);
PROCEDURERETURN_RESULT(param_resINOUTINTEGER,
to_clientINBOOLEANDEFAULTTRUE);
Theparam_resparametertakeseitherthevariableofSYS_REFCURSORtypeorcursorid,whichcanberetrievedfromDBMS_SQL.OPEN_CURSOR.Theto_clientparameterdeterminesiftheresultsetcanbereturnedtotheclientprogramorcallingsubprogram.
Letusre-createtheprocedureP_SAL_GRAPH(createdearlier)usingtheenhancement.
/*Createproceduretoimplicitlyreturntheresultset*/
CREATEORREPLACEPROCEDUREp_sal_graph_12c(p_deptINNUMBER)
AS
/*DeclareaSYS_REFCURSORvariable*/
cur_salSYS_REFCURSOR;
BEGIN
/*Openthecursorfordepartment*/
OPENcur_salFOR
SELECTempno,job,LPAD('*',sal/100,'.')graph
FROMemp
WHEREdeptno=P_DEPT
ORDERBYjob;
/*UseDBMS_SQL.RETURN_RESULTtoreturnthecursor*/
DBMS_SQL.RETURN_RESULT(cur_sal);
END;
/
Nowwewillinvokethisprocedurefordepartment30inSQL*Plus.Wegetidenticalresultswithmuchreducedefforts:
/*Executetheprocedurefordepartmentid30*/
EXECp_sal_graph_12c(30);
PL/SQLprocedureissuccessfullycompleted.
ResultSet#1
EMPNOJOBGRAPH
---------------------------------------------------------
7900CLERK........*
7698MANAGER...........................*
7844SALESMAN..............*
7521SALESMAN...........*
7499SALESMAN...............*
7654SALESMAN...........*
6rowsselected.
SubtypesAsubtypeisadatatypethatgetsevolvedfromanexistingscalardatatype.Thepurposeofcreatingsubtypes,thoughnotmandatory,istocustomizetheprimarydatatypesbycontrollingcertainfeaturessuchasnullability,range,orsign.Anunconstrainedsubtypeisoftenusedinplaceofprimarydatatypestomaintainapplicationstandards.
Thesubtypeinheritsthebehaviorofitsparentbasetypeandextendsitfurtherbyadistinguishingfeature.Forexample,NATURALNisasubtypeofBINARY_INTEGER,whichpreventstheentryofnullsandnegativevalues.Similarly,SIGNTYPEpermitsonlythreefixedvalues:-1,0,or1.
Thefollowingtableshowsthebasetypesandsubtypesundereachscalardatatype:
Number Character Date/Time Boolean
NUMBER VARCHAR DATE BOOLEAN
DECIMAL/DEC VARCHAR2 INTERVAL
DOUBLEPRECISION NVARCHAR2 TIMESTAMP
FLOAT CHAR
INTEGER/INT NCHAR
NUMERIC CHARACTER
REAL LONG
SMALLINT LONGRAW
PLS_INTEGER RAW
BINARY_DOUBLE ROWID
BINARY_FLOAT STRING
BINARY_INTEGER UROWID
POSITIVE
POSITIVEN
NATURAL
NATURALN
SIGNTYPE
SubtypeclassificationSubtypescanbepredefinedoruser-defined.Pre-definedsubtypesaresystem-builtandmaintainedintheSTANDARDpackagebyOracleDatabase.HereisasmallextractfromtheSTANDARDpackagelistingthesubtypesoftheNUMBERfamily:
/*NUMBERfamilyfromSTANDARDpackage*/
typeNUMBERisNUMBER_BASE;
subtypeFLOATisNUMBER;
subtypeINTEGERisNUMBER(38,0);
subtypeINTisINTEGER;
subtypeSMALLINTisNUMBER(38,0);
subtypeDECIMALisNUMBER(38,0);
subtypeNUMERICisDECIMAL;
subtypeDECisDECIMAL;
subtypeBINARY_INTEGERisINTEGERrange'-2147483647'..2147483647;
subtypeNATURALisBINARY_INTEGERrange0..2147483647;
subtypeNATURALNisNATURALnotnull;
subtypePOSITIVEisBINARY_INTEGERrange1..2147483647;
subtypePOSITIVENisPOSITIVEnotnull;
subtypeSIGNTYPEisBINARY_INTEGERrange'-1'..1;
NoteFLOATisanunconstrainedsubtypeofNUMBER.ConstrainedsubtypessuchasNATURALandNATURALNworkmostlyonrangesandnullability.
User-definedsubtypesarecreatedontopofpredefinedtypeswithaspecificmanipulation.TheyaredefinedintheDECLAREsectionofaPL/SQLblockorsubprogram:
SUBTYPE[SUBTYPENAME]IS[PREDEFINEDTYPE][CONSTRAINT|RANGE(range
specification)]
ThefollowingPL/SQLblockdeclaresasubtypeoftheNUMBERbasetypethathasbeenconstrainedintherangeof1to10.Ifavariableofsubtypedatatypeisassignedanout-of-rangevalue,theVALUE_ERRORexceptionisraised.
DECLARE
/*Createasubtypewithvaluerangebetween1to10*/
SUBTYPEIDISBINARY_INTEGERRANGE1..10;
L_NUMID;
BEGIN
/*Assignavaluebeyondrange*/
L_NUM:=11;
END;
/
DECLARE
*
ERRORatline1:
ORA-06502:PL/SQL:numericorvalueerror
ORA-06512:atline5
TypecompatibilitywithsubtypesSubtypesareinterchangeablewiththeirbasetypesaslongasthesubtypedefinitionisnotviolated.Inthefollowingprogram,theSUBTYPEIDisaBINARY_INTEGERwithanassignedrangebetween1and10.TheprogramraisestheVALUE_ERRORexceptionifanout-of-rangevalueisassignedtothesubtypevariable:
DECLARE
/*Createasubtypewithvaluerangebetween1to10.Declarethesubtype
variable*/
SUBTYPEIDISbinary_integerrange1..10;
L_NUMID;
L_BNBINARY_INTEGER;
BEGIN
/*AssignaNUMBERvariabletoSUBTYPEvariable*/
L_NUM:=4;
L_BN:=15;
L_NUM:=L_BN;
END;
/
DECLARE
*
ERRORatline1:
ORA-06502:PL/SQL:numericorvalueerror
ORA-06512:atline8
SummaryInthischapter,wediscussedtheimportanceofcursorstructuresinPL/SQLcode.Wecoveredtheworkingofacursor,theexecutioncycle,designconsiderations,andguidelines.TheusageofcursorscanbeimperativewhiledevelopingPL/SQLapplications.
Inthenextchapter,weshallcovercompositedatatypes,andyouwillunderstandhowcollectionscanboostPL/SQLcodeperformanceandperformdatacaching.
PracticeexerciseWhatarethepossiblereasonsthatcausetheINVALID_CURSORexceptiontooccur?
1. Cursorresultsethasnotbeenfetched.2. Thecursordoesnothaveparameters.3. Thevalueofthe%ROWCOUNTattributehasbeenreferencedafterclosingthe
cursor.4. Cursorresultsethasbeenfetchedintoanonmatchingvariable.
IdentifytheguidelinestobeconsideredwhendesigningcursorsinaPL/SQLblock:
1. Explicitcursorsmustbeusedirrespectiveofthenumberofrecordsreturnedbythequery.
2. CursorFORloopsmustbeusedasitimplicitlytakescareofOPEN,FETCH,andCLOSEstages.
3. Cursordatamustbefetchedasarecord.4. UseROWNUMtoindextherecordsinthecursorresultsets.
WhileprocessingDMLsasimplicitcursorsinaPL/SQLexecutableblock,implicitcursorattributescanbeusedanywhereintheblock.
1. True.2. False.
Fromthefollowingoptions,identifythetwocorrectstatementsabouttheREFCURSORtype?
1. Refcursorsarereferencepointerstocursorobjects.2. REFCURSORtypescanbedeclaredinthepackagespecification.3. SYS_REFCURSORisastrongrefcursortype.4. Acursorvariablecannotbeusedasargumentsinstoredsubprograms.
TheRETURNtypeforarefcursorcanbedeclaredusing%TYPE,%ROWTYPE,orauser-definedrecord.
1. True.2. False.
Whichtwostatements,amongthefollowing,aretrueaboutcursorvariables?
1. CursorvariablescanprocessmorethanoneSELECTstatement.2. Acursorvariablecanbepassedasprogramargumentsacrosssubprogramsand
eventotheclientendprograms.3. Acursorvariablecanbedeclaredasapublicconstructinthepackage
specification.
4. Cursorvariablescanbestoredinadatabaseasdatabasecolumns.
Similartostaticexplicitcursors,cursorvariablescanalsobeopenedintheFORloop
1. True.2. False.
Whichofthefollowingistruewhilecreatingsubtypesfromatablerecordstructure?
SUBTYPE[Name]IS[TABLE]%ROWTYPE
1. Thesubtypeinheritscompletecolumnstructureoftherecordstructure.2. Thesubtypeinheritsthedefaultvaluesofthedatabasecolumnsintable.3. Thesubtypeinheritstheindexinformationofthedatabasecolumns.4. ThesubtypeinheritsnoneexcepttheNOTNULLconstraintinformationofthe
databasecolumns.
Chapter4.UsingCollectionsAcollectionisasingle-dimensionalstructureofhomogeneouselements.Behaviorallyspeaking,itisquitesimilartoanarrayandaliststructureavailableinotherthirdgenerationlanguages.FirstintroducedinOracle7asPL/SQLtables,Oracle8irebrandedcollectionsasIndex-bytables.Oracle8ialsointroducedpersistentcollectiontypes,namelynestedtablesandvarrays.OracleDatabase9irenamedIndex-by-tablestoassociativearrays.
OracleDatabaseoffersawidescopeofusabilityofcollectionsinPL/SQLprogramming.Thelanguagesemanticsnotonlyallowyoutocreateandmaintaincollections,butalsoprovidesmultiplemethodsforarrayoperations.ThischapterhelpsyoutounderstandthecollectiontypesinOracleand,mostimportantly,whichtypessuitagivenproblem.Thechapteroutlinelookslikethis:
Anintroductiontocollections
CategorizationSelectionofanappropriatecollectiontype
AssociativearraysNestedtablesVarraysPL/SQLcollectionmethodsManipulatingcollectionelementsCollectiondesignconsiderations
IntroductiontocollectionsAcollectionisanarraylikehomogeneoussingle-dimensionalstructure,whichholdsasetofelementsofsimilardatatype.Eachcellinacollection,andhence,eachelement,isuniquelyidentifiedbyitspositionindexorthesubscript.TheelementorthevaluecontainedinacellcanbeofavalidSQLdatatypeorauser-definedtype.Therearethreetypesofcollections:associativearray;nestedtable;andvarray.
Acollectioncanbeboundedorunboundedonthebasisofit’scollectionsize.Boundedcollectionshaveafixednumberofelements,asinarrays.Unboundedcollectionscanhaveanynumberofelements.Varraysareboundedcollectionswhiletheassociativearraysandnestedtablesareunbounded.
Onthebasisofpersistenceinthedatabase,acollectioncanbeeitherapersistentornon-persistentcollection.ApersistentorSQLcollectioncaneitherbecreatedintheOracleDatabaseschemaordeclaredwithinthePL/SQLblock.APL/SQLornon-persistentcollectionisdeclaredinaPL/SQLblockonly.Anestedtableandavarrayarepersistentcollections.Anassociativearrayisalwaysanon-persistentcollection.
CollectiontypesAnassociativearrayisanon-persistentunboundedcollectionwhichmeansthatanassociativearraycannotbecreatedintheOracleDatabaseschema,butlocallydeclaredwithinthedeclarativesectionofaPL/SQLblock.
AnestedtableisapersistentcollectionofhomogeneouselementsthatcanbecreatedinadatabaseasaschemaobjectaswellasdeclaredwithinaPL/SQLblock.Anestedtablebeinganunboundedcollection,hasnolimitonthenumberofelements.
Avarrayisasingle-dimensionalhomogeneouscollectionthatcanbecreatedinadatabaseaswellasinPL/SQL.Beingaboundedcollection,itcanholdonlyafixednumberofelements.
AssociativearraysAssociativearraysinOraclearesimilartoconventionallistsinotherprogramminglanguages.AnassociativearrayisanunboundedarrayofcellsandalwaysdefinedinthedeclarativesectionofaPL/SQLprogram.Whileacellisidentifiedbyanindexofnumberorstringtype,itcanholdavalueofascalardatatypeoruser-definedcompositetype.
ThesyntaxtodeclareanassociativearrayinaPL/SQLblockisasfollows:
TYPE[COLLNAME]ISTABLEOF[ELEMENTDATATYPE]NOTNULL
INDEXBY[INDEXDATATYPE]
Inthesyntax,the[INDEXDATATYPE]signifiesthedatatypeofanarraysubscript.ItcanbeBINARY_INTEGER,PLS_INTEGER,POSITIVE,NATURAL,SIGNTYPE,orVARCHAR2.ThedatatypesthatarenotsupportedasindextypesareRAW,NUMBER,LONG-RAW,ROWID,andCHAR.
The[ELEMENTDATATYPE]canbeoneofthefollowing:
PL/SQLscalardatatype:NUMBER(alongwithitssubtypes),VARCHAR2(anditssubtypes),DATE,BLOB,CLOB,orBOOLEANInferreddata:Thedatatypeinheritedfromatablecolumn,cursorexpressionorpredefinedpackagevariableUser-definedtype:Auser-definedobjecttypeorcollectiontype
Herearesomesampledeclarationsofanassociativearray:
/*AssociativearrayofCLOBindexedbyanumber*/
TYPEclob_tISTABLEOFCLOBINDEXBYPLS_INTEGER;
/*Arrayofemployeeidsindexedbytheemployeenames*/
TYPEempno_tISTABLEOFemp.empno%TYPENOTNULL
INDEXBYemp.ename%type;
ThefollowingPL/SQLprogramdeclaresanassociativearrayofsomeelementswithastringtypesubscript.TheFIRSTandNEXTcollectionmethodsarediscussedindetailinthePL/SQLcollectionmethodssectioninthischapter:
/*EnabletheSERVEROUTPUTontodisplaytheoutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declareanassociativearrayandalocalvariableofcollectiontype*/
TYPEstring_asc_arr_tISTABLEOFNUMBER
INDEXBYVARCHAR2(10);
l_strstring_asc_arr_t;
l_idxVARCHAR2(10);
BEGIN
/*Assignthetotaldaysineachquarter*/
l_str('JAN-MAR'):=90;
l_str('APR-JUN'):=91;
l_str('JUL-SEP'):=92;
l_str('OCT-DEC'):=93;
l_idx:=l_str.FIRST;
WHILE(l_idxISNOTNULL)
LOOP
DBMS_OUTPUT.PUT_LINE('Valueat'||l_idx||'is'||l_str(l_idx));
l_idx:=l_str.NEXT(l_idx);
ENDLOOP;
END;
/
ValueatAPR-JUNis91
ValueatJAN-MARis90
ValueatJUL-SEPis92
ValueatOCT-DECis93
PL/SQLproceduresuccessfullycompleted.
Similarly,thefollowingPL/SQLblockpopulatesanassociativearrayofstringvalueswithrandomvalues:
/*EnabletheSERVEROUTPUTontodisplaytheoutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLBlock*/
DECLARE
/*Declareanarrayofstringindexedbynumericsubscripts*/
TYPErandom_tISTABLEOFVARCHAR2(12)INDEXBYPLS_INTEGER;
l_randomrandom_t;
BEGIN
/*InsertthevaluesusingaFORloop*/
FORIIN1..100
LOOP
l_random(I):=DBMS_RANDOM.STRING('X',10);
ENDLOOP;
/*Displaythevaluesrandomly*/
DBMS_OUTPUT.PUT_LINE(l_random(5));
DBMS_OUTPUT.PUT_LINE(l_random(10));
DBMS_OUTPUT.PUT_LINE(l_random(50));
END;
/
5NHU5R5UMU
98P7NUDZZB
E6AG6TR07S
PL/SQLproceduresuccessfullycompleted.
Thefeaturesofassociativearraysareasfollows:
Anassociativearraycanbesparse,meaningtheindexneednotbeconsecutive.Beinganon-persistentcollection,itcannotparticipateinDMLtransactions.
However,elementsofanassociativearraycanbeusedintheDMLwithinaFORALLstatement.Itcanbepassedasanargumenttootherlocalsubprograms.SortingofanassociativearraydependsontheNLS_SORTparameter.Anassociativearraydeclaredinapackagespecificationbehavesasapersistentarrayinasession.
NestedtablesAnestedtableisapersistentSQLcollectionthatisusedasalisttoholdelementsofthesamedatatype.ItcanalsobecreatedinthedatabaseanddefinedinaPL/SQLprogram.Itisanunboundedcollectionandtheuserdoesn’thavetomaintainthecellindex.Oracleautomaticallyassignsthecellindexas1tothefirstcellandmovesonwardsincrementally.Anestedtablecollectiontypeinitiallystartsoffasadensecollectionbutitbecomessparseduetodeleteoperations.
NoteAdensecollectionreferstoacollectionthatistightlypopulatedwhichmeansnoemptycellsbetweenthelowerandupperindexesofthecollection.Adensecollectionmaybecomesparsebyperformingdeleteoperations.
Whenanestedtableiscreatedasaschemaobjectinthedatabase,itcanbereferencedinaPL/SQLblockasavariableparameter.Acolumnofnestedtabletypescanbeincludedinatable.Anattributeofnestedtabletypescanexistinanobjecttype.Inadatabaseschema,anestedtablecanbedeclaredusingtheCREATETYPE…statement:
CREATE[ORREPLACE]TYPEtype_nameISTABLEOF[element_type][NOTNULL];
/
Intheprecedingsyntax,[element_type]canbeanSQL-supportedscalardatatype,adatabaseobjecttype,oraREFobjecttype.TheunsupportedelementtypesareBOOLEAN,LONG,LONG-RAW,NATURAL,NATURALN,POSITIVE,POSITIVEN,REFCURSOR,SIGNTYPE,STRING,PLS_INTEGER,SIMPLE_INTEGER,BINARY_INTEGERandallothernon-SQLsupporteddatatypes.
WhenanestedtableisdeclaredinaPL/SQLprogram,itbehavesasaone-dimensionalarraywithoutanyindextypeorupperlimitspecification.Itcanbereferencedonlywithintheprograminwhichitisdeclared.AtabletypedefinitioninaPL/SQLblockfollowsthebelowsyntax:
DECLARE
TYPEtype_nameISTABLEOFelement_type[NOTNULL];
Theelement_typeisaprimitivedatatype(exceptcursorvariables)orauser-definedtype.
ModifyanddropanestedtableobjecttypeToincreasetheprecisionofnestedtableelements,usetheALTERTYPEcommandwithCASCADEorINVALIDATEoptions:
ALTERTYPE[typename]MODIFYELEMENTTYPE[modifiedelementtype]
[CASCADE|INVALIDATE];
TheCASCADEandINVALIDATEoptionsdeterminewhetherthecollectionalterationhastocascadeorinvalidatethedependents.
ThenestedtabletypecanbedroppedusingtheDROPcommand,asshowninthefollowingsyntax(notethattheFORCEkeyworddropsthetypeirrespectiveofitsdependents):
DROPTYPE[collectionname][FORCE]
DesignconsiderationsofanestedtableAsadatabasedeveloper,youmustunderstandthefactorsthatinfluencenestedtabledesignandlayout.Forinstance,retrievalofanout-of-linestorednestedtablestructurealongwiththetablecolumnscouldpotentiallyimpactthequerydesign.Thissectiontalksaboutkeyaspectsthatshouldbeconsideredduringnestedtabledesign.
NestedtablestorageOraclemaintainsaseparatestoragetabletostorethenestedtabledata.Thisstoragetableisintegrallyconnectedtotheparenttablethroughasystem-generated16-bytevalueknownasNESTED_TABLE_ID.Thisvalueisusedtocorrelatetheparentrowvalueandtheconnectedstoragetablerows.
Nestedtableinanindex-organizedtableAnestedtablewithaprimarykeybehavesasanindex-organizedtable(IOT).IftheprimarykeyisconstitutedwithNESTED_TABLE_ID,theparentandchildrowsareclusteredtogether,whichhelpsinfastretrievalofchildrows.Inaddition,nestedtablecompressioncanbeenabledusingtheCOMPRESSclause.Anestedtableincompressedmodepreventstherepetitionofaparentkeyforasetofchildrowsinthestoragetable,thusoptimizingthespaceconsumption.Thisformatoforganizationinnestedtablescanbebeneficialwhentheapplicationretrievesanestedtableasacompleteunit.
Alternatively,indexingNESTED_TABLE_IDinthestoragetablecanalsoacceleratetheaccessandretrievalofchildrows.
NestedtablelocatorsNestedtablelocatorsareusefulwhenaparentrowcorrelatestoalargesetofchildrows.Insteadofperformingjoinsandreturninglargedatasets,Oracleretrievesalocatorthatcanbeusedtoaccessthechildrecordswheneverrequired.Therearetwowaystofetchthecollectiontypeasalocation:
SpecifyRETURNASLOCATORinthestorageclauseUsetheNESTED_TABLE_GET_REFShintintheSELECTstatement
NestedtableastheschemaobjectThefollowingexampledemonstratesthecreationofanestedtabletypeinthedatabaseandusingitasacolumndatatypeinatable.TheobjecttypeNT_SCORESrecordsthescoresofabatsmaninacrickettournament:
/*Createthenestedtableinthedatabase*/
CREATETYPEnt_scoresASTABLEOFNUMBER;
/
Typecreated.
ThemetadatainformationforNT_SCORESisavailableintheUSER_TYPESandUSER_COLL_TYPESdictionaryviews:
/*Selectquerytogetnestedtablemetadataascollectiontype*/
SELECTtype_name,typecode,type_oid
FROMUSER_TYPES
WHEREtype_name='NT_SCORES'
/
TYPE_NAMETYPECODETYPE_OID
--------------------------------------------------------------
NT_SCORESCOLLECTION1218C13A817D0D9FE0530F02000A6119
NotethattheTYPECODEvalueshowsthetypeoftheobjectinthedatabaseanddifferentiatescollectiontypesfromuser-definedobjecttypes.Let’snowquerytheUSER_COLL_TYPESdictionaryviewtoquerythecollectiontypeandelementtypeofthenestedtable:
SELECTtype_name,coll_type,elem_type_name
FROMuser_coll_types
WHEREtype_name='NT_SCORES'
/
TYPE_NAMECOLL_TYPEELEM_TYPE_NAME
---------------------------------------------
NT_SCORESTABLENUMBER
TheCREATETABLEstatementcreatesatablewithacolumnoftheNT_SCOREStabletype.Althoughanestedtabletypecolumninatableresemblesatablewithinatable,Oraclecreatesaseparatestoragetablefromtheparenttable.TheNESTEDTABLE[Column]STOREAS[storagetable]clausespecifiesthestoragetableforthenestedtabletypecolumn.Atthetimeofrecordcreation,thedatainthestoragetableisconnectedtotherowintheparenttablethrougharowidentifier:
CREATETABLEt_bat_scores
(nameVARCHAR2(30),
posNUMBER,
scoreNT_SCORES)
NESTEDTABLEscoreSTOREASnt_scores_st
/
Tablecreated.
Bydefault,thestorageoptionsforthestoragetablearethesameasthatofthemaintable.Ifyouwantthestoragetableonadifferenttablespace,youcanspecifytheTABLESPACEclausealongsidetheNESTEDTABLEclause:
NESTEDTABLEscoreSTOREASnt_scores_st
(TABLESPACEnt_tbs_storage)
/
IfyoumovetheparenttabletoadifferenttablespaceusingtheALTERTABLE…MOVEstatement,thenthestoragetabledoesn’tmoveunlessyouexplicitlymovethestoragetableasfollows:
ALTERTABLEnt_scores_stMOVETABLESPACEnt_tbs_storage
/
OperationsonanestedtabletypecolumnIntermsofdatacontainedinacolumn,thenestedtabletypecolumnstorestheobjecttypeinstance,insteadofscalardatavalues.Thestructureoftheobjecttypeinstancemustbenotedwhileinsertingtherecordsinthetableandqueryingthedatafromthetable.
Thissectiontakesyouthroughthedifferentoperationsonthenestedtabletypecolumnandtheobjecttypeinstance.
Createanestedtableinstance
Let’sinserttherunsscoredbythefirsttwobatsmenoftheteaminthelastfiveinnings.Notetheobjecttypeinstancecanbeinsertedinanestedtabletypecolumnusingacollectiontypeconstructor.Itisadefaultconstructorwiththesamenameasthecollectionandallmemberattributes:
INSERTINTOt_bat_scores(name,pos,score)VALUES
('Duckworth',1,nt_scores(115,37))
/
INSERTINTOt_bat_scores(name,pos,score)VALUES
('Duckworth',2,nt_scores(71,29,13))
/
INSERTINTOt_bat_scores(name,pos,score)VALUES
('Lewis',1,nt_scores(34,65,23))
/
INSERTINTOt_bat_scores(name,pos,score)VALUES
('Lewis',2,nt_scores(0,1))
/
commit
/
Queryingthetabledata,youcanseethenestedvaluesthatistheinstancesofnestedtables:
SELECT*
FROMt_bat_scores
/
NAMEPOSSCORE
-----------------------------------------------------------
Duckworth1NT_SCORES(115,37)
Duckworth2NT_SCORES(71,29,13)
Lewis1NT_SCORES(34,65,23)
Lewis2NT_SCORES(0,1)
Inthenextinnings,DuckworthopensatNo.1positionandscores125,whileLewisscores45atNo.2position.Youwouldwanttoupdatetheexistingobjectinstancesandnotcreateaduplicateentryforthebatsmen.Oracleallowsthepiecewiseinsertsandupdatesontheobjectinstances.ThepiecewisescoreisinsertedusingthefollowingINSERTstatement:
INSERTINTOTABLE(SELECTscore
FROMt_bat_scores
WHEREname='Duckworth'
ANDpos=1)
VALUES(125)
/
INSERTINTOTABLE(SELECTscore
FROMt_bat_scores
WHEREname='Lewis'
ANDpos=2)
VALUES(45)
/
COMMIT
/
Afterthenewscoresareupdatedinthetable,theobjectinstanceslooklikethis:
SELECT*
FROMt_bat_scores
/
NAMEPOSSCORE
------------------------------------------------------------
Duckworth1NT_SCORES(115,37,125)
Duckworth2NT_SCORES(71,29,13)
Lewis1NT_SCORES(34,65,23)
Lewis2NT_SCORES(0,1,45)
Duetoashortrun,Duckworthlosesarunandhisscoreisnow124.Thischangehastoreflectbackinthetable.ThefollowingUPDATEstatementhelpsyouperformpiecewiseupdates.ThefollowingSELECTqueryverifiesthevalueupdate:
UPDATETABLE(SELECTscore
FROMt_bat_scores
WHEREname='Duckworth'andpos=1)P
SETP.COLUMN_VALUE=124
WHEREP.COLUMN_VALUE=125
/
SELECT*
FROMt_bat_scores
/
NAMEPOSSCORE
--------—---------
Duckworth1NT_SCORES(115,37,124)
Duckworth2NT_SCORES(71,29,13)
Lewis1NT_SCORES(34,65,23)
Lewis2NT_SCORES(0,1,45)
Queryinganestedtablecolumn
Whenatablewithanestedtablecolumnisqueried,thenestedtablecolumnappearsasaninstanceofnestedtableobjecttype.Wealreadysawthisinactioninthelastsection.
TheTABLEexpressioncanbeusedtounnestoropentheinstanceanddisplaythedatainrelationalformat.TheTABLEexpressionisusedtoaccesstheattributesofnestedtabletype.Oracleimplicitlyjoinstheparentrowwiththenestedtablerowinthequeryoutput:
SELECTT.name,T.pos,T1.column_value
FROMt_bat_scoresT,TABLE(T.score)T1
/
NAMEPOSCOLUMN_VALUE
---------------------------------
Duckworth1115
Duckworth137
Duckworth1124
Duckworth271
Duckworth229
Duckworth213
Lewis134
Lewis165
Lewis123
Lewis20
Lewis21
Lewis245
12rowsselected.
IntheprecedingSELECTquery,COLUMN_VALUEisanOraclepseudo-columnthatisusedintheSELECTqueriestosignifythenestedtablecolumnwithnoattributename.
NestedtablecollectiontypeinPL/SQLInPL/SQL,anestedtablecanbedeclaredanddefinedinthedeclarationsectionofaPL/SQLblockasalocalcollectiontype.ThePL/SQLvariableofnestedtabletypemustbeinitializedbeforeusingitintheprogrambody.OracleraisestheexceptionORA-06531:Referencetouninitializedcollectionifanuninitializedcollectiontypevariableisaccessedintheprogrambody.
Collectioninitialization
WhenusedinaPL/SQLprogram,thevariablesofnestedtableorvarraycollectiontypesmustbeinitialized.Associativearraysarelocalnon-persistentarrays,sonoinitializationisrequiredforthem.Thissectionhasbeenincludedtogiveabriefdescriptionofcollectioninitializationmethods:
Initializeacollectioninthedeclarativesectionbyusingthedefaultconstructor:
/*StartthePL/SQLblock*/
DECLARE
TYPEcoll_nt_tISTABLEOFNUMBER;
/*Collectionvariableinitializationusingadefaultconstructor*/
L_LOCAL_VAR1coll_nt_t:=coll_nt_t(10,20);
/*collectionvariableinitializationwithanemptycollection*/
L_LOCAL_VAR2coll_nt_t:=coll_nt_t();
BEGIN
…
…
END;
InitializeacollectionintheexecutablesectionthroughassignmentortheSELECT…INTOstatement:
Intheexecutablesection,aSELECTstatementcanpullacollectioninstance(ofthesamecollectiontype)intothelocalcollectionvariable.ThismethodofcollectioninitializationispermissibleonlywhenthecollectiontypeexistsasaschemaobjectandisusedtodeclareaPL/SQLvariable.
Inourearlierillustrations,nt_scoresisanestedtableinthedatabase.Letususethesametypetodeclarealocalcollectionvariable:
/*StartthePL/SQLblock*/
DECLARE
l_loc_numnt_scores;
l_loc_idxnt_scores;
BEGIN
/*InitializingthecollectionvariablewithSELECT…INTO*/
SELECTnumINTOl_loc_num
FROMtab_use_nt_col
WHEREid=1;
/*Initializingthecollectionvariablewithanassignment*/
l_loc_idx:=l_loc_num;
END;
/
ThefollowingPL/SQLblockdeclaresanestedtableinthedeclarativesection.Observethescopeandvisibilityofthecollectionvariable.NotethattheCOUNTmethodhasbeenusedtodisplaythearrayelements:
/*EnabletheSERVEROUTPUTtodisplaytheresults*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarealocalnestedtablecollectiontype*/
TYPEnt_localISTABLEOFNUMBER;
l_arraynt_local:=nt_local(10,20,30);
BEGIN
/*UseFORlooptoparsethearrayandprinttheelements*/
FORIIN1..l_array.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE('Showing'||i||'value:'||l_array(I));
ENDLOOP;
END;
/
Showing1value:10
Showing2value:20
Showing3value:30
PL/SQLproceduresuccessfullycompleted.
QueryingthenestedtablemetadataAsacollectiontype,thenestedtable’smetadatacanbequeriedfromtheUSER_TYPESorUSER_COLL_TYPESviews.Forthenestedtabletypecolumninatable,Oracle’sUSER_NESTED_TABLESandUSER_NESTED_TABLE_COLSdatadictionaryviewsmaintaintheinformationoftheparentandthenestedtables.TheUSER_NESTED_TABLESstaticviewmaintainstheinformationaboutthemappingofanestedtablecollectiontypewithitsparenttable.
ThefollowingSELECTstatementonUSER_NESTED_TABLESqueriesthedetailsofthestoragetableassociatedwiththeparenttable:
SELECTparent_table_name,
parent_table_column,
table_name,
table_type_name,
storage_spec
FROMuser_nested_tables
WHEREparent_table_name='T_BAT_SCORES'
/
PARENT_TABLE_NAPARENT_TABTABLE_NAMETABLE_TYPESTORAGE_SPEC
-----------------------------------------------------------------
T_BAT_SCORESSCORENT_SCORES_STNT_SCORESDEFAULT
Letusnowquerythenestedstoragetableintheprecedingdictionaryviewtolistallitsattributes:
SELECTCOLUMN_NAME,DATA_TYPE,DATA_LENGTH,HIDDEN_COLUMN
FROMuser_nested_table_cols
wheretable_name='NT_SCORES_ST'
/
COLUMN_NAMEDATA_TYPDATA_LENGTHHID
------------------------------------------------------------
NESTED_TABLE_IDRAW16YES
COLUMN_VALUENUMBER22NO
TheCOLUMN_VALUEattributeisthedefaultpseudo-columnofthenestedtableastherearenonamedattributesinthecollectionstructure.Theotherattribute,NESTED_TABLE_ID,isahidden,unique,16-byte,system-generatedrawhashcode,whichstorestheparentrowidentifieralongsidethenestedtableinstancetodistinguishtheparentrowassociation.Itsvalueisthesameasthesystemsuppliedid(SYS_NCXXXX$)valueintheparenttable.
NestedtablecomparisonfunctionsOracleprovidesSQLfunctionsthatcanbeappliedtonestedtablesformultisetpurposes.Thefunctionsarebrieflydescribedinthefollowingtable:
Collectionfunction Description
SET Returnsdistinctelementsofanestedtable
CARDINALITY Returnsthecountofelementsinanestedtable
[NOT]SUBMULTISET ReturnsTRUE,ifanestedtableisasubsetoftheothernestedtable
POWERMULTISET(SQLonly) Generatesallpossiblenon-emptysub-multisetsfromaninputcollection.Maximumcardinalityis32.
POWERMULTISET_BY_CARDINALITY
(SQLonly)Generatesthenon-emptysub-multisetsfromaninputcollection,filteredbythegivencardinality.
MultisetoperationsonnestedtablesThesetoperators(UNION,INTERSECT,andMINUS)inSQLareusedtocombinetheresultsfrommorethanoneSQLqueryintoasingleresultset.OracleDatabase10gintroducedmultisetoperatorstoallowsetoperationsonnestedtables.Amultisetoperationcombinesmorethanonenestedtablesandreturnsacollectionresultingfromamultisetoperator.
Themultisetoperationsaddauniqueandexclusivecapabilitytonestedtables.Insteadoffollowingthetrivialloop-through-collectionapproachtorow-comparetwocollectionsforcommonordifferenceelements,youcannowcompareacollectionasanobject.
NoteMultisetoperatorsareavailableinPL/SQL,andSQLtoo.
Themultisetoperatorsarelistedasbelow:
MULTISETUNION[ALL|DISTINCT]:combinestwonestedtablesofthesametypeandreturnsanestedtablecontainingtheelementsfromboththeinputcollections.YoucanuseALLorDISTINCTtoalloworpreventduplicationofelements.ALListhedefault.MULTISETINTERSECT[ALL|DISTINCT]:combinestwonestedtablesofthesametypeandreturnsanestedtablecontainingtheelements,whicharecommoninthetwonestedtables.IfyouusetheDISTINCToption,Oracleremovestheduplicatevaluesfromthefinalresultset.MULTISETEXCEPT[ALL|DISTINCT]:workswithtwonestedtablesofthesametypeandreturnsanestedtablecontainingtheelements,whicharepresentinthefirstbutnotinthesecond.IfyouusetheDISTINCToption,Oracleremovesthecommonelements.
TipFormultisetoperations,theinputnestedtablesshouldbeofthesametypewithcomparableelements.Ifyouareworkingwithcomplexcollectiontypesthatisanestedtablewithcomplexattributes,youmustusetheMAPordermethodtoenablesortingofthecollectionelements.Theresultofamultisetoperationisofthesamecollectiontypeastheoperands.
ThefollowingPL/SQLblockdemonstratestheusageofmultisetoperators.
/*CreateanestedtablecollectionobjectinSCOTTschema*/
CREATEORREPLACETYPElist_of_lettersASTABLEOFVARCHAR2(1);
/
/*Enabletheserveroutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declaretwolocalcollectionvariables*/
str1list_of_letters:=list_of_letters('O','R','A','C','L','E');
str2list_of_letters:=list_of_letters('D','A','T','A','B','A','S','E');
/*Localproceduretoprintthecollectionelements*/
PROCEDUREprint_nt(strINlist_of_letters)
IS
BEGIN
FORiin1..str.COUNT
LOOP
DBMS_OUTPUT.PUT(str(i)||'.');
ENDLOOP;
DBMS_OUTPUT.NEW_LINE;
DBMS_OUTPUT.PUT_LINE(RPAD('',50,'-'));
ENDprint_nt;
BEGIN
/*Multisetintersectoperation*/
DBMS_OUTPUT.PUT('MULTISETINTERSECT=>');
PRINT_NT(str2MULTISETINTERSECTstr1);
/*Multisetintersectdistinctoperation*/
DBMS_OUTPUT.PUT('MULTISETINTERSECTDISTINCT=>');
PRINT_NT(str2MULTISETINTERSECTDISTINCTstr1);
/*Multisetunionoperation*/
DBMS_OUTPUT.PUT('MULTISETUNION=>');
PRINT_NT(str1MULTISETUNIONstr2);
/*Multisetuniondistinctoperation*/
DBMS_OUTPUT.PUT('MULTISETUNIONDISTINCT=>');
PRINT_NT(str1MULTISETUNIONDISTINCTstr2);
/*Multisetexceptoperation*/
DBMS_OUTPUT.PUT('MULTISETEXCEPT=>');
PRINT_NT(str2MULTISETEXCEPTstr1);
/*Multisetexceptdistinctoperation*/
DBMS_OUTPUT.PUT('MULTISETEXCEPTDISTINCT=>');
PRINT_NT(str2MULTISETEXCEPTDISTINCTstr1);
END;
/
MULTISETINTERSECT=>A.E.
-------------------------------------------------
MULTISETINTERSECTDISTINCT=>A.E.
-------------------------------------------------
MULTISETUNION=>O.R.A.C.L.E.D.A.T.A.B.A.S.E.
-------------------------------------------------
MULTISETUNIONDISTINCT=>O.R.A.C.L.E.D.T.B.S.
-------------------------------------------------
MULTISETEXCEPT=>D.T.A.B.A.S.
-------------------------------------------------
MULTISETEXCEPTDISTINCT=>D.T.B.S.
-------------------------------------------------
VarrayOracleDatabase8iintroducedvarraysasamodifiedformatofanestedtable.Thevarrayorvariablesizearrayisquitesimilartonestedtablesbutboundedinnature.Thevarraydeclarationincludesthecountofelementsthatavarraycanaccommodate.Theminimumvarrayindexis1,thecurrentsizeisthetotalnumberofelements,andthemaximumlimitisthevarraysize.Atanymoment,thecurrentsizecannotexceedthemaximumlimit.Varraysareappropriatelyusedwhenyouknowthemaximumnumberofelementsinacollectionstructure.
Likenestedtables,varrayscanbecreatedinthedatabaseasschemaobjectsaswellasinaPL/SQLblock.Whencreatedinthedatabaseasaschemaobject,varrayscanbereferencedinPL/SQLprogramunitsasvariables,parametersandfunctionreturntypes.Atablecanhaveacolumnofavarraytype.Anobjecttypecanhaveanattributeofavarraytype.Thesyntaxforvarrays,whendefinedasadatabasecollectiontype,isasfollows:
CREATE[ORREPLACE]TYPEtype_nameIS{VARRAY|VARYINGARRAY}(size_limit)
OFelement_type
Whenavarraytypecolumnisincludedinatable,itisstoredinlinewiththecorrespondingrowintheparenttable.Therefore,thereisnoneedtohaveaseparatestoragetable.Ifthevarraycolumnsizeexceeds4kilobytes,Oraclefollowstheout-of-linestoragemechanismandstoresthevarrayasanLOB.
NoteThein-linestoragemechanismofvarrayshelpsOracletoreducethediskI/Os.
WhendeclaredinaPL/SQLblock,avarraycanbereferencedwithinthecurrentblockonly.InPL/SQL,varrayscanbedeclaredasfollows:
DECLARE
TYPEtype_nameIS{VARRAY|VARYINGARRAY}(size_limit)OF
element_type[NOTNULL];
Inthesyntax,size_limitdeterminesthemaximumcountofelementsinthearray.Ifthevarraysizehastobemodifiedaftercreation,followthisALTERTYPEsyntax:
ALTERTYPE[varrayname]MODIFYLIMIT[newsize_limit]
[INVALIDATE|CASCADE];
NoteThevarraysizecanonlybeincreasedbyusingtheALTERTYPE…MODIFYstatement.Evenifthecurrentmaximumsizeisnotutilized,Oracledoesn’tallowtheripping-offofavarraysize.Ifyoutrytoreducethevarraysize,OracleraisesthecompilationerrorPLS-00728:thelimitofaVARRAYcanonlybeincreasedandtoamaximum2147483647.
TheINVALIDATEandCASCADEoptionssignifytheinvalidationorpropagationeffectonthedependentobjectsasaresultofthetypealteration.
Note
VarrayasaschemaobjectThefollowingexampledemonstratestheusageofavarrayasaschemaobject.Thevarraycapturestheannualproductionvaluesrecordedbyageographyfortheyears.
Let’screateavarrayofacompositeobjecttype:
CREATEORREPLACETYPEot_num_2ASOBJECT
(strVARCHAR2(25),
numNUMBER
);
/
CREATEORREPLACETYPEv_geo_prodASVARRAY(5)OFot_num_2;
/
Formetadatainformation,we’llquerytheUSER_TYPESandUSER_COLL_TYPESviews:
SELECTtype_name,typecode,type_oid
FROMUSER_TYPES
WHEREtype_name='V_GEO_PROD'
/
TYPE_NAMETYPECODETYPE_OID
---------------------------------------------------------
V_GEO_PRODCOLLECTION122DC43ECA0412EEE0530F02000AC98A
SELECTtype_name,coll_type,elem_type_name
FROMuser_coll_types
WHEREtype_name='V_GEO_PROD'
/
TYPE_NAMECOLL_TYPEELEM_TYPE_NAME
----------------------------------------------------------------
V_GEO_PRODVARYINGARRAYOT_NUM_2
ThefollowingCREATETABLEscriptcreatesatableusingthevarrayobjecttype.Notethatthereisnostoragetablerequiredforvarrays:
CREATETABLEt_annual_prod
(prod_codeVARCHAR2(8),
yearNUMBER,
productionV_GEO_PROD)
/
Atthisstage,ifweneedtomodifythevarraystructurethatis,toincreasethelimitsize,wecandosousingtheALTERTYPE…MODIFYstatement.Hereisanexamplethatincreasesthevarraylimitsizeto10:
ALTERTYPEv_geo_prodMODIFYLIMIT10INVALIDATE;
Thepreviousscriptinvalidatesalldependentobjects.TheotheroptionisCASCADE,whichcascadesthechangestothedependentobjects.TheCASCADE[NOT]INCLUDINGTABLEDATAoptioncontrolswhethertheunderlyingdataimageofvarraytypeinstancesneedstobeupdatedorjustthetablemetadata.
Ifthesizeofvarraycolumnvalueexceeds4000bytes,ithastobestoredasanLOB.For
thispurpose,youmustincludetheLOBstorageinformationinthevarraymetadata.We’llcreateavarraycolumnwithLOBstoragefordemopurposeanddropitlater:
CREATETYPEref_geo_prodASVARRAY(10)OFot_num_2;
/
ALTERTABLEt_annual_prod
ADD(gl_prodref_geo_prod)
VARRAYgl_prodSTOREASLOBprod_lob
/
ALTERTABLEt_annual_prodDROPCOLUMNgl_prod
/
OperationsonvarraytypecolumnsSimilartonestedtables,thecolumnsofvarraystoreinstancesofvarrayobjecttypes.However,fundamentaldifferencesfromnestedtablesimpactcertainoperationsinvarrays.Oneofthemajordifferencesisthatpiecewiseoperationsarenotpossiblewithvarrays.
Insertingvarraycollectiontypeinstance
ThefollowingINSERTstatementscreatetworecordsintheT_ANNUAL_PRODtable.Thevarrayinstanceusesacollectionconstructor,whiletheobjecttypeinstanceusesthedefaultobjecttypeconstructortoprovidetheinputvalues:
INSERTINTOt_annual_prod
VALUES('PROD-A',2010,v_geo_prod(ot_num_2('NAS',50),
ot_num_2('EMEA',32),
ot_num_2('APAC',47)))
/
INSERTINTOt_annual_prod
VALUES('PROD-A',2011,v_geo_prod(ot_num_2('NAS',54),
ot_num_2('APAC',57),
ot_num_2('EMEA',37)))
/
COMMIT
/
Withvarrays,piecewiseinsertsarenotpossible.Ifyouhavetoaddanewvarrayelement,youmustfollowthevarraycolumnatomicupdateprocess.
Queryingvarraycolumn
Avarraycolumncanbequeriedeitherasanobjecttypeinstanceorinarelationalformat.Let’scheckthewaystoquerydatafromT_ANNUAL_PRODtable(ignoretheoutputformattingissues):
setlines150
colproductionformata50
SELECT*FROMt_annual_prod
/
PROD_CODYEARPRODUCTION(STR,NUM)
----------------------------------------------------------------
PROD-A2010V_COUNTRY_PROD(OT_NUM_2('NAS',50),
OT_NUM_2('EMEA',32),OT_NUM_2('APAC',47))
PROD-A2011V_COUNTRY_PROD(OT_NUM_2('NAS',54),
OT_NUM_2('APAC',57),OT_NUM_2('EMEA',37))
Thepreviousresultcontainstheinstancesofvarraysaswellastheobjecttype.Thefollowingquerysimplyselecttheobjecttypeinstances:
SELECTT.prod_code,T.year,value(t1)val
FROMt_annual_prodT,TABLE(T.production)T1
/
PROD_CODYEARVAL(STR,NUM)
-------------------------------------------------------
PROD-A2010OT_NUM_2('NAS',50)
PROD-A2010OT_NUM_2('EMEA',32)
PROD-A2010OT_NUM_2('APAC',47)
PROD-A2011OT_NUM_2('NAS',54)
PROD-A2011OT_NUM_2('APAC',57)
PROD-A2011OT_NUM_2('EMEA',37)
Well,thislooksgood.Tounnestalltheobjectvaluesofaninstanceinarelationalformat,youcanusetheTABLEclause.Hereisthequery:
SELECTT.prod_code,T.year,T1.str,T1.num
FROMt_annual_prodT,TABLE(T.production)T1
/
PROD_CODYEARSTRNUM
-----------------------------------------------------
PROD-A2010NAS50
PROD-A2010EMEA32
PROD-A2010APAC47
PROD-A2011NAS54
PROD-A2011APAC57
PROD-A2011EMEA37
6rowsselected.
Iftherowsexistintheparenttablewithoutanychildinstance,youcanspecifythe(+)signasyouwoulddowithouterjoins.Forexample,thepreviousquerycanberewrittenas:
SELECTT.prod_code,T.year,T1.str,T1.num
FROMt_annual_prodT,TABLE(T.production)(+)T1
/
Updatingthevarrayinstance
Forvarrays,piecewiseinsertsandupdatesarenotpossible.Onlyatomicchangesareallowed,whichmeansthatanentirevarrayinstancehastobemodifiedtoupdateavarrayelement.
ThefollowingPL/SQLblockupdatestheproductionvaluesofEMEAintheyear2010throughaconstructor.NotetheuseofaSQLvarrayinthePL/SQLblock:
/*StartthePL/SQLblock*/
DECLARE
/*Createalocalvarrayvariableandinitializewiththenewvarray
instance*/
l_new_geoprodv_geo_prod:=v_geo_prod(ot_num_2('NAS',50),
ot_num_2('EMEA',42),ot_num_2('APAC',47));
BEGIN
/*Updatetheproductioninstancewiththelocalvarrayvariable*/
UPDATEt_annual_prod
SETproduction=l_new_geoprod
WHEREprod_code='PROD-A'
ANDyear=2010;
COMMIT;
END;
/
VarrayinPL/SQLThefollowingPL/SQLshowsthelocaldeclarationofavarrayobjectinaPL/SQLblock:
/*EnabletheSERVEROUTPUTtodisplaytheresults*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarealocalvarraytype,definecollectionvariableandinitialize
it*/
TYPElocal_varrayISVARRAY(4)OFVARCHAR2(100);
l_objlocal_varray:=local_varray('ORCL','SAP','IBM');
BEGIN
/*Iteratethearrayobjecttoprintthevarrayelements*/
FORIIN1..l_obj.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE('Varrayelements:'||l_obj(I));
ENDLOOP;
END;
/
Varrayelements:ORCL
Varrayelements:SAP
Varrayelements:IBM
PL/SQLproceduresuccessfullycompleted.
ComparingthecollectiontypesThefollowingtablecomparesthecollectiontypesbasedontheconsiderations.
Comparingfactor Nestedtable Varray Associativearray
Maximumsize Unboundandgrowsdynamically. Bounded.However,varraysize,can
onlybeincreasedthereafter.Unboundandgrowsdynamically.
Sparsity Startsdensebutmaybecomesparseduetodeletions. Alwaysdense. Canbesparse.
Storageconsiderations
Out-of-linestorageinaseparatestoragetable.
In-linestorageupto4000bytes.
Forout-of-linestorage,theLOBclausemustbespecified.
Non-persistentcollectionusesprogrammemorythatisUGA.
Queryingability
Anestedtabletypecolumncanbequeriedasaninstance.However,unnestingofaninstanceispossibleusingtheTABLEorCASTclause.
Avarraytypecolumncanbequeriedasaninstance.However,unnestingofaninstanceispossibleusingtheTABLEorCASTclause.
Non-persistentcollection.
DMLoperations
Piecewiseandatomicoperationspossible. Onlyatomicoperationsarepossible.
OnlyatomicoperationsallowedwithinaPL/SQLblock.
Ordering Unorderedindex Retainstheindexorder. Retainstheindexorder.
PerformanceThejoinbetweentheparentandstoragetablemightbeadecidingfactor.OptimizeusingIOTsandlocators.
Varraysstoredin-linegivebetterperformancethannestedtablesbecausenojoinsaremadeduringdataretrieval.
Performancedependentonthesizeofassociativearraysandblockoperations.
Thecommonexceptionsthatyoumightencounterduringthecollectiondesignphaseareasfollows:
COLLECTION_IS_NULL:ThisexceptionoccurswhenthecollectionisNULLNO_DATA_FOUND:ThisexceptionoccurswhentheelementcorrespondingtoasubscriptdoesnotexistSUBSCRIPT_BEYOND_COUNT:ThisexceptionoccurswhentheindexexceedsthenumberofelementsinthecollectionSUBSCRIPT_OUTSIDE_LIMIT:ThisexceptionoccurswhentheindexisnotalegalvalueVALUE_ERROR:Thisexceptionoccurs,ifyoutrytoaccessanelementwithoutanindex
SelectingtheappropriatecollectiontypeHereareafewguidelinesthatcanhelpyoudecidetheappropriateusageofcollectiontypeinprograms:
Associativearrays:
UsewhenyouhavetotemporarilyholdtheprogramdatainahashmaplikeastructureoranarrayNotethatthereisnomethodtocompareassociativearraysCanbeusedforkey-valuedatamodelswithstringkeys
Nestedtables:
Canbeusedformodelingone-to-manyrelationshipswithintheparenttableYoucancomparecollectionsusingequalityandnon-equality,ormultisetoperatorsCanbeusedForperformingpiecewisetransactionsonthechildrows
Varray:
UsewhenyouknowthemaximumcountofelementsinthecollectionstructureExceptfornullity,youcannotperformcomparisonoperationsTheorderoftheelementshastobepreserved
Oracle12cenhancementstocollectionsOracleDatabase12callowsajoinbetweenatableandacollectiontype.IfanSQLcollectiontypeisusedasareturntypeofafunction,thetableandthefunctionoutputcanbejoinedusingCROSSAPPLYandOUTERAPPLY.Thefunctionmustuseavaluefromthejoiningtableasaparameterandreturnacollectionvariableofanestedtableorvarraytype.
Forthepurposeofillustration,letuscreatethetesttablesusingdictionaryviewsfromtheOracleDatabase.ThetableT_TBS_OBJcontainsthetablespaceinformationandT_SEGMENTScontainsthesegmentscreatedonthesetablespaces:
/*CreatetableT_TBS_OBJ*/
CREATETABLEt_tbs_obj
AS
SELECTtablespace_name,status,allocation_type
FROMuser_tablespaces
/
/*CreatetableT_SEGMENTS*/
CREATETABLEt_segments
AS
SELECTsegment_name,segment_type,tablespace_name,bytes,blocks
FROMuser_segments
/
We’llcreatethenestedtablecollectiontobeusedinthestring:
CREATETYPEnt_stringASTABLEOFVARCHAR2(128);
/
ThefunctionF_GET_SEGMENTSreturnsthesegmentscreatedonagiventablespaceasanestedtablecollectiontype:
/*Createafunctiontoreturnsegmentscreatedonatablespace*/
CREATEORREPLACEFUNCTIONf_get_segments(p_nameVARCHAR2)
RETURNnt_string
AS
l_segnt_string;
BEGIN
/*SelectquerytofetchthesegmentsfromT_SEGMENTS*/
SELECTCAST(COLLECT(segment_name)asnt_string)
INTOl_seg
FROMt_segments
WHEREtablespace_name=p_name;
RETURNl_seg;
END;
/
ThefollowingqueryusestheCROSSAPPLYmethodtojointhetableandthefunction.Notethattheoutputliststhetablespacenameandthesegmentscreatedonit.Uniquely,therearetwotablespacesthatisUSERSandORCL.Whatabouttheremainingtablespaces?Let’s
figurethatoutinthenextcodelisting:
SELECT*
FROMt_tbs_objCROSSAPPLYf_get_segments(tablespace_name)
/
TABLESPACE_NAMESTATUSALLOCATIONCOLUMN_VALUE
----------------------------------------------------------------
USERSONLINESYSTEMDEPT
USERSONLINESYSTEMEMP
USERSONLINESYSTEMSALGRADE
ORCLONLINESYSTEMT_BAT_SCORES
ORCLONLINESYSTEMT_ANNUAL_PROD
ORCLONLINESYSTEMT_OBJ
ORCLONLINESYSTEMT_TMP_DB
ORCLONLINESYSTEMT_ROW_ARCH
ORCLONLINESYSTEMT_DEF_COLS
ORCLONLINESYSTEMT_FUN_PLSQL
ORCLONLINESYSTEMNT_SCORES_ST
USERSONLINESYSTEMPK_DEPT
USERSONLINESYSTEMPK_EMP
USERSONLINESYSTEMSYS_C0010393
USERSONLINESYSTEMSYS_C0010392
USERSONLINESYSTEMSYS_FK0000093178N00003$
16rowsselected.
NotethatthereareothertablespacessuchasSYSTEMandSYSAUXwithnousersegmentscreatedonthem.Byvirtueofcrossjoin,thetablespaceswithnosegmentswereeliminatedfromtheoutput.Insuchcase,wecanusetheOUTERAPPLYjoinmethod:
SELECT*
FROMt_tbs_objOUTERAPPLYf_get_segments(tablespace_name)
/
TABLESPACE_NAMESTATUSALLOCATIONCOLUMN_VALUE
---------------------------------------------------------------
SYSTEMONLINESYSTEM
SYSAUXONLINESYSTEM
UNDOTBS1ONLINESYSTEM
TEMPONLINEUNIFORM
USERSONLINESYSTEMDEPT
USERSONLINESYSTEMEMP
USERSONLINESYSTEMSALGRADE
ORCLONLINESYSTEMT_BAT_SCORES
ORCLONLINESYSTEMT_ANNUAL_PROD
ORCLONLINESYSTEMT_OBJ
ORCLONLINESYSTEMT_TMP_DB
ORCLONLINESYSTEMT_ROW_ARCH
ORCLONLINESYSTEMT_DEF_COLS
ORCLONLINESYSTEMT_FUN_PLSQL
ORCLONLINESYSTEMNT_SCORES_ST
USERSONLINESYSTEMPK_DEPT
USERSONLINESYSTEMPK_EMP
USERSONLINESYSTEMSYS_C0010393
USERSONLINESYSTEMSYS_C0010392
USERSONLINESYSTEMSYS_FK0000093178N00003$
PL/SQLcollectionmethodsOracleprovidesasetofmethodsthatcanworkwithcollectionsfordevelopmentoperations.Thedevelopmentoperationscanbedeletinganelement,trimmingthecollectiontype,orfetchingfirstandlastsubscripts.Thesyntaxforallthecollectionmethodsisasfollows:
[COLLECTION].METHOD(PARAMETERS)
EXISTSTheEXISTSfunctioncheckstheexistenceofanelementinacollection.Thegeneralsyntaxofthisfunctionis[COLLECTION].EXISTS(<index>).Itacceptsthesubscriptastheinputargumentandsearchesforitintheassociatedcollection.Iftheelementcorrespondingtotheindexexists,itreturnsTRUE,orelsereturnsFALSE.Itistheonlymethodthatdoesn’traiseanyexceptionwhenusedwithacollection.
ThefollowingPL/SQLblockdeclaresalocalnestedtablecollectionanditstwovariables.Whileonearrayisuninitialized,theotheroneisinitializedwithsampledata.Itcheckstheexistenceofthefirstelementinbotharrays:
/*EnabletheSERVEROUTPUTontodisplaytheoutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarealocalnestedtablecollection*/
TYPEcoll_method_demo_tISTABLEOFNUMBER;
/*Declarecollectiontypevariables*/
L_ARRAY1coll_method_demo_t;
L_ARRAY2coll_method_demo_t:=coll_method_demo_t(45,87,57);
BEGIN
/*Checkifthefirstcellexistsinthearray1*/
IFL_ARRAY1.EXISTS(1)THEN
DBMS_OUTPUT.PUT_LINE('Element1foundinArray1');
ELSE
DBMS_OUTPUT.PUT_LINE('Element1NOTfoundinArray1');
ENDIF;
/*Checkifthefirstcellexistsinthearray2*/
IFL_ARRAY2.EXISTS(1)THEN
DBMS_OUTPUT.PUT_LINE('Element1foundinArray2');
ELSE
DBMS_OUTPUT.PUT_LINE('Element1NOTfoundinArray2');
ENDIF;
END;
/
Element1NOTfoundinArray1
Element1foundinArray2
PL/SQLproceduresuccessfullycompleted.
COUNTTheCOUNTfunctioncountsthenumberofelementsinaninitializedcollection.Foruninitializedcollections,themethodraisestheCOLLECTION_IS_NULLexception.
NoteTheCOUNTfunctionreturnszerowhen:
Anestedtableorvarraycollectionisinitializedwithanemptycollection
Anassociativearraydoesn’thaveanyelements
Itcanbeusedwithallthreetypesofcollections.
ThefollowingPL/SQLblockdeclaresalocalnestedtablecollectionandavariableofnestedtabletype.Letuschecktheelementcountinboththecollectionvariables:
/*EnabletheSERVEROUTPUTontodisplaytheoutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarethelocalcollectiontype*/
TYPEnt_localISTABLEOFNUMBER;
/*Declareandinitializethecollectionvariables*/
l_loc_varnt_local:=nt_local(10,20,30);
BEGIN
DBMS_OUTPUT.PUT_LINE('Thearraysizeis'||l_loc_var.count);
END;
/
Thearraysizeis3
PL/SQLproceduresuccessfullycompleted.
LIMITTheLIMITfunctionreturnsthemaximumnumberofelementsthatcanbestoredinaVARRAYcollectiontype.ThemethodraisestheCOLLECTION_IS_NULLexceptionforuninitializedcollections.
NoteForassociativearraysornestedtables,theLIMITmethodreturnsNULL.
ThefollowingPL/SQLblockdeclaresalocalvarraytypeandavariableofitstype.Thevarraytypevariablehasbeeninitializedwithtestdata.ObservethedifferencebetweentheCOUNTandLIMITmethods:
/*EnabletheSERVEROUTPUTontodisplaytheoutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarelocalvarrayanditsvariable*/
TYPEva_localISVARRAY(10)OFNUMBER;
l_arrayva_local:=va_local(10,20,30);
BEGIN
/*Displaythecurrentcount*/
DBMS_OUTPUT.PUT_LINE('Thevarraysizeis'||L_ARRAY.COUNT);
/*Displaythemaximumlimit*/
DBMS_OUTPUT.PUT_LINE('Thevarraymaxsizeis'||L_ARRAY.LIMIT);
END;
/
Thevarraysizeis3
Thevarraymaxsizeis10
PL/SQLproceduresuccessfullycompleted.
FIRSTandLASTTheFIRSTandLASTfunctionsreturnthefirstandlastelementsofacollection.Foranemptycollection,boththemethodsreturnaNULLvalue.Thesemethodscanbeusedwithallthreetypesofcollections.TheFIRSTandLASTmethodsraisetheexceptionCOLLECTION_IS_NULLtouninitializedcollections.
ThefollowingPL/SQLblockdemonstratestheuseoftheFIRSTandLASTmethodswithaninitializedcollection:
/*EnabletheSERVEROUTPUTontodisplaytheoutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLbock*/
DECLARE
/*Displayalocalnestedtablecollection*/
TYPEcoll_method_demo_tISTABLEOFNUMBER;
L_ARRAYcoll_method_demo_t:=coll_method_demo_t(10,20,30);
BEGIN
/*Displaythefirstandlastelements*/
DBMS_OUTPUT.PUT_LINE('Firstelement:'||L_ARRAY(L_ARRAY.FIRST));
DBMS_OUTPUT.PUT_LINE('Lastelement:'||L_ARRAY(L_ARRAY.LAST));
END;
/
Firstelement:10
Lastelement:30
PL/SQLproceduresuccessfullycompleted.
PRIORandNEXTThePRIORandNEXTfunctionstakeaninputindexandreturnitspreviousandnextindex.IfthePRIORandNEXTfunctionsareusedwithfirstandlastindexesrespectively,theresultisNULL.
Boththemethodscanbeusedwithallthreetypesofcollections.ThePRIORandNEXTmethodsraiseCOLLECTION_IS_NULLexceptionwhenappliedtouninitializedcollections.ThefollowingPL/SQLshowstheusageofthePRIORandNEXTmethodswithaPL/SQLtypecollection:
/*EnabletheSERVEROUTPUTontodisplaytheoutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarealocalnestedtablecollection*/
TYPEnt_localISTABLEOFNUMBER;
L_ARRAYnt_local:=nt_local(10,20,30,100,48,29,28);
l_num_idxNUMBER;
BEGIN
/*Capturetheelementbefore4thindex*/
l_num_idx:=l_array.prior(4);
DBMS_OUTPUT.PUT_LINE('Indexbefore4thelement:'||l_num_idx);
/*Deletethefifthelement*/
l_array.delete(5);
/*Capturetheelementafter4thindex*/
l_num_idx:=l_array.next(4);
DBMS_OUTPUT.PUT_LINE('Indexafter4thelement:'||l_num_idx);
END;
/
Indexbefore4thelement:3
Indexafter4thelement:6
PL/SQLproceduresuccessfullycompleted.
IntheprecedingPL/SQLblock,thelocalnestedtablecollectionwasrenderedsparseafterthefifthelementwasdeleted.
EXTENDTheEXTENDfunctionisusedtoappendelementstoapersistentcollection.Itcannotbeusedwithassociativearrays.Beinganoverloadedfunction,EXTENDcanbeusedtoappendafinitenumberofelementswithadefaultvalue:
EXTEND:ItappendsthecollectionwithaNULLelement.EXTEND(x):ItappendsthecollectionwithanxnumberofNULLelements.EXTEND(x,y):Itappendsthecollectionwithxelementswithvaluesasthatoftheyelement.Iftheyelementdoesn’texist,thesystemraisesaSUBSCRIPT_BEYOND_COUNTexception.
ThefollowingPL/SQLblockdemonstratestheextensionofacollectiontypeusingallthreesignaturesoftheEXTENDmethod.ThefirstextensionappendsthefourthNULLelementtothearray.ThesecondextensionappendsthefifthandsixthNULLelementstothearray.Thethirdextensionappendstheseventhandeighthelementsas10(thevalueofthefirstelement)tothearray:
/*EnabletheSERVEROUTPUTontodisplaytheoutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarelocalnestedtablecollectiontype*/
TYPEnt_localISTABLEOFNUMBER;
/*Declarecollectiontypevariableandinitializeit*/
L_ARRAYnt_local:=nt_local(10,20,30);
l_num_idxNUMBER;
BEGIN
/*Extendthecollectionusingdefaultsignature*/
l_array.extend;
l_num_idx:=l_array(l_array.last);
DBMS_OUTPUT.PUT_LINE(L_ARRAY.LAST||'elementis='||l_num_idx);
/*ExtendthecollectionbyaddingtwoNULLelements*/
l_array.extend(2);
l_num_idx:=l_array(l_array.last);
DBMS_OUTPUT.PUT_LINE(L_ARRAY.LAST||'elementis='||l_num_idx);
/*Extendthecollectionbyaddingtwoelementswithavalue*/
l_array.extend(2,1);
l_num_idx:=l_array(l_array.last);
DBMS_OUTPUT.PUT_LINE(L_ARRAY.LAST||'elementis='||l_num_idx);
END;
/
4elementis=
6elementis=
8elementis=10
PL/SQLproceduresuccessfullycompleted.
TheEXTENDmethodraisestheCOLLECTION_IS_NULLexceptionforuninitializedcollections.Ifavarrayisattemptedforextensionbeyonditsmaximumallowedlimit,OracleraisesanSUBSCRIPT_BEYOND_LIMITexception.
TRIMTheTRIMfunctionisusedtocuttheelementsfromapersistentcollection.Itcannotbeusedwithassociativearraytypecollections.TRIMisanoverloadedmethod,whichcanbeusedinthefollowingtwosignatures:
TRIM:Ittrimsoneelementfromtheendofthecollection.TRIM(n):Ittrimsnelementsfromtheendofthecollection.Ifnexceedsthetotalcountofelementsinthecollection,thesystemraisesaSUBSCRIPT_BEYOND_COUNTexception.NoactionisdefinedforNULLvalueofn.
ThefollowingPL/SQLblockshowstheoperationoftheTRIMmethodonaninitializedPL/SQLtablecollectiontype:
/*EnabletheSERVEROUTPUTontodisplaytheoutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarealocalnestedtablecollectiontype*/
TYPEnt_localISTABLEOFNUMBER;
/*Declareacollectionvariableandinitializeit*/
l_arraynt_local:=nt_local(10,20,30,40,50);
l_num_idxNUMBER;
BEGIN
/*Trimthelastelementofthecollection*/
l_array.trim;
l_num_idx:=l_array(l_array.last);
DBMS_OUTPUT.PUT_LINE(L_ARRAY.LAST||'elementis='||l_num_idx);
/*Trimthelast2elementsofthecollection*/
DBMS_OUTPUT.PUT_LINE('Trimmingthearray…');
l_array.trim(2);
l_num_idx:=l_array(l_array.last);
DBMS_OUTPUT.PUT_LINE(L_ARRAY.LAST||'elementis='||l_num_idx);
END;
/
4elementis=40
Trimmingthearray…
2elementis=20
PL/SQLproceduresuccessfullycompleted.
TheTRIMmethodraisesaCOLLECTION_IS_NULLexceptionforuninitializedcollections.
DELETETheDELETEfunctionisusedtodeleteelementsfromagivencollection.TheDELETEoperationleavesthecollectionsparse.AnyreferencetothedeletedindexwouldraiseaNO_DATA_FOUNDexception.TheDELETEmethodraisesaCOLLECTION_IS_NULLexceptionforuninitializedcollections.Itcanbeusedwithallthreetypesofcollections.
Theoverloadedmethodcanbeusedinthefollowingsignatures:
DELETE:ItflushesoutalltheelementsofacollectionDELETE(n):ItdeletesthenthindexfromthecollectionDELETE(n,m):Itperformsrangedeletion,wherealltheelementswithintherangeofthesubscriptsnandmaredeleted
ThefollowingPL/SQLblockdeclaresacollectionalongwithitscollectionvariable.Thisprogramdisplaysthefirstelementofthecollectionbeforeandafterthedeletionofthefirstsubscript:
/*EnabletheSERVEROUTPUTontodisplaytheoutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarethelocalnestedtablecollection*/
TYPEnt_localISTABLEOFNUMBER;
/*Declareandinitializeacollectionvariable*/
l_arraynt_local:=nt_local(10,20,30,40,50);
l_num_idxNUMBER;
BEGIN
/*Capturetheelementatthefirstplace*/
l_num_idx:=l_array(l_array.first);
DBMS_OUTPUT.PUT_LINE('1stelementis'||l_num_idx);
/*Deletethe1stelementfromthecollection*/
L_ARRAY.DELETE(1);
/*Capturetheelementatthefirstplace*/
l_num_idx:=l_array(l_array.first);
DBMS_OUTPUT.PUT_LINE('1stelementis'||l_num_idx);
END;
/
1stelementis10
1stelementis20
PL/SQLproceduresuccessfullycompleted.
Oracledoesn’tallowthedeletionofindividualelementsinavarraycollection.Eitheralltheelementsofavarrayareremovedusingthe[VARRAY].DELETEmethodortheelements
canbetrimmedfromtheendofthevarraycollection:
/*EnabletheSERVEROUTPUTontodisplaytheoutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarethelocalvarraycollection*/
TYPEva_arrayISVARRAY(10)OFNUMBER;
/*Declareacollectionvariableandinitializeit*/
L_ARRAYva_array:=va_array(10,20,30,40,50);
BEGIN
/*Deletethesecondelementofvarray*/
L_ARRAY.DELETE(2);
END;
/
L_ARRAY.DELETE(2);
*
ERRORatline8:
ORA-06550:line8,column3:
PLS-00306:wrongnumberortypesofargumentsincallto'DELETE'
ORA-06550:line8,column3:
PL/SQL:Statementignored.
TipItisrecommendedthattheTRIMandDELETEmethodsmustnotbeoperatedtogetherorsimultaneouslyonacollection.TheDELETEmethodretainsaplaceholderforthedeletedelementwhiletheTRIMmethoddestroystheelementfromthecollection.Therefore,theoperationsequenceDELETE(last)followedbyTRIM(1)wouldresultintheremovalofasingleelementonly.
SummaryThischaptercoversoneofthemoreinterestingfeaturesofPL/SQLprogramming—collections.WediscussedandlearnedthethreetypesofcollectionsinPL/SQLthatisassociativearrays,nestedtablesandvarrays.Readersshouldunderstandtheapplicationofthesecollectiontypesindifferentsituations.Thecomparativestudyofallthreewouldhelpreaderstodifferentiatebetweeneachoneandchoosethemostappropriateoneintheirdevelopment.
ThenextchapterwillexploreanotherdistinctivecapacityofPL/SQLasalanguage,thatisintheuseofexternalprocedures.
PracticeexerciseWhichtwostatementsaretrueaboutassociativearrays?
1. Associativearrayscanhavenegativesubscripts.2. Associativearraysarealwaysdensecollections.3. Associativearraysdon’tneedinitializationinaPL/SQLblock.4. Theupperlimitofassociativearrayscanbydynamicallymodified.
Whichofthefollowingstatementsistrueaboutnestedtables?
1. Nestedtablesarestoredinasegmentdifferentfromthatofaparenttable.2. Nestedtablecolumnscanhavestringsubscripts.3. Nestedtablescangrowdynamicallyuptoanyextent.4. Adatabasecolumnofnestedtablecollectiontypecanbeseparatelyqueriedby
itsstoragename.
Onlyvarrayscanhavesequentialnumbersassubscripts.
1. True2. False
Whichofthefollowingassociativearraydeclarationsis/arecorrect:
DECLARE
TYPET1ISTABLEOFNUMBERINDEXBYBOOLEAN;
TYPET2ISTABLEOFVARCHAR2(10)INDEXBYNUMBER;
TYPET3ISTABLEOFDATEINDEXBYSIGNTYPE;
TYPET4ISTABLEOFEMPLOYEES%ROWTYPEINDEXBYPOSITIVE;
BEGIN
…
…
END;
1. T12. T23. T34. T4
Whichofthefollowingstatementsis/aretrueaboutvarrays?
1. ThelimitofvarrayelementscanbemodifiedduringruntimeusingtheALTERTABLEstatement.
2. AvarrayelementcanbedeletedusingtheDELETEmethod.3. Foranemptycollectionofvarraytype,thevalueofLASTisequaltoCOUNT.4. Varrayscanexistassparsecollections.
WhatwillbetheoutputofthefollowingPL/SQLblock:
DECLARE
TYPETISTABLEOFNUMBER;
L_NUMT:=T(1,2);
BEGIN
DBMS_OUTPUT.PUT_LINE(L_NUM(1));
L_NUM:=T(10,20);
DBMS_OUTPUT.PUT_LINE(L_NUM(1));
END;
1. 1and1.2. 1and10.3. OracleraisesaCOLLECTION_IS_NULLexceptionatline5.4. 10and10.
TheEMPLOYEEStablestoresthedetailsof14employees.IdentifythesolutionoftheerrorinthefollowingPL/SQLprogram:
DECLARE
TYPEEMP_VARRAY_TISVARRAY(10)OFEMPLOYEES%ROWTYPE;
L_EMPEMP_VARRAY_T:=EMP_VARRAY_T();
BEGIN
DBMS_OUTPUT.PUT_LINE(L_EMP.COUNT);
SELECT*
BULKCOLLECTINTOL_EMP
FROMEMPLOYEES;
DBMS_OUTPUT.PUT_LINE(L_EMP.COUNT);
END;
/
0
DECLARE
*
ERRORatline1:
ORA-22165:givenindex[11]mustbeintherangeof[1]to[10]
ORA-06512:atline6
1. Thevarraysizemustbeincreasedto14orahigherlimit.2. Thevarrayvariablemustbeinitialized.3. Dataforonly10employeesmustbeselectedintoavarrayvariable.4. TheVarraydefinitioniswrong;arecordtypecannotbeusedasanelement
typeofavarraycollection.
Whichofthefollowingstatementsarewrongaboutthecollectionmethods?
1. EXISTSraisesaNO_DATA_FOUNDexceptioniftheelementfortheinputsubscriptdoesnotexist.
2. DELETEcanbeusedwithvarrays.3. LIMITreturnsthecurrentlimitofnestedtablecollections.4. TRIMremovesanelementofthecollectionfromtheend.
Chapter5.UsingAdvancedInterfaceMethodsOracleenablestheapplicationdeveloperstocreatePL/SQLroutinesthatcaninvokeprogramswritteninnon-Oracleprogramminglanguages.AnexternalprogramcanbeaC,C++based,orJava-basedprogram.ExternalprocedureswereintroducedinOracle8itoaddextensibilitytotheOracleDatabaseenginebyallowingthenon-Oracleprogramstoexecuteinthedatabasekernel.Thischaptercoverstheexternalproceduresandtheirimplementationinthefollowingtopics:
UnderstandingexternalroutinesArchitectureandbenefitsExecutingexternalCprogramsfromPL/SQLExecutingexternalJavaprogramsfromPL/SQL
OverviewofExternalProceduresOracleprovidesarichplatformforapplicationprogrammingthroughPL/SQLandthesupportformultilanguageprograms.Programminglanguagesthatallowthetechnicaltranslationofrealworldproblemshavedifferentfeaturesandadvantages,forexample,PL/SQListightlyintegratedwithSQLandcomputation-basedlogiccanberunefficientlyinC.Someofthecrucialfactorsthatdeterminethechoiceofaprogramminglanguagecanbecodeperformance,portability,andsecurity.Therefore,youmightseeapplicationdevelopmentinvolvingmultipleprogramminglanguages.
OraclePL/SQLallowsuserstocreateaPL/SQLprogramthatcallsaCorJavaprocedure.Thespecialpurposeinterfaceallowstheuserstoutilizethestrengthsandfeaturesofmultipleprogramminglanguagesandsupportcodereusability.
ExternalProceduresAnexternalprocedureisstoredinadynamiclinkedlibrary(DLL)orasimilarunit,whichisprototypedinacallspecificationusingOraclePL/SQL.WheneveraPL/SQLprocedureiscalled,thelanguagecompilerloadsthetargetlibraryatruntimeandexecutestheexternalprogramasaPL/SQLprocedure,entirelyandnativelywithintheOracleDatabase.Aninterestingcapabilityofanexternalprocedureisthatthecallspecificationisindependentofthecodechangestotheprogram.
Theprecedingdiagramshowsahigh-leveloverviewofthecomponentsinvolvedinanexternalprocedurecall.Wewilldiscussthemindetailinthischapter.
ExternalproceduresenhancethedevelopmentplatformoftheOracleDatabases.AC-basedorJava-basedprogram,whenexecutedfromthedatabaseserver,avoidsthenetworkroundtripsmadeforclient-to-databasecommunication.
ComponentsofexternalprocedureexecutionflowInthissection,wewilllearnaboutthedatabasecomponentsinvolvedintheexecutionofanexternalprocedure.
TheextprocagentTheextprocagentplaysthemostvitalroleininterfacingexternalproceduresintheOracleDatabase.ItisaprocessstartedbytheOracleDatabaseordatabaselistener,whichfacilitatestheexecutionofanexternalprocedurewheneverrequired.Itcarriesrelevantinformationsuchasthelibrarypath,procedurename,andarguments.Itreturnstheresultoftheexecutionbacktothedatabaseprocessingengine.
Inadedicatedservermode,eachsessionwillhaveanewinstanceoftheextprocprocess.Inamultiuserapplication,multiplesessionswithmultipleextprocprocessesmayresultinadisproportionateallocationofmemoryresources.Inasharedservermode,amultithreadedextprocagentcanprovidetheefficientutilizationofserverresourcesbymaintainingasharedpooloftheextprocprocesses.
TheLibraryobjectAnexternalprocedurecanbeexecutedasasharedlibraryinOracle.Alibraryisanoperatingsystemfile,whichcanbedynamicallyloadeduponrequest.OnaWindowsmachine,youmightbeawareofthelibraryfileswitha.dllextension,whileonUnixanditsflavors,thelibraryisstoredwitha.soextension.Alibrarycanbesharedbymultipleexternalprocedures.TheexternalprocedurecanbewritteninC,C++,Fortran,COBOL,orVisualBasic.Asharedlibrarycanbesharedacrossmultipledatabasesessions,thusoptimizingthememoryconsumption.
Fortherepresentationofthesharedlibraryacrossaschema,aschemaobjectiscreatedasanaliaslibrary.Thislibrarycanbecreatedusingthefollowingsyntax:
CREATELIBRARY[schema].library_name
{IS|AS}'library_path'
[AGENT'agent_link'];
AlibrarycanbecreatedbySYSorauserwiththeCREATELIBRARYprivilege.AuserwiththeEXECUTEprivilegeonthelibrarycanreferitinthecallspecifications.Thelibrarypathmustbeaccessiblebytheextprocprocess,thatis,eitheritmustbeexplicitlyspecifiedinEXTPROC_DLLSorthelibrarymustresideinthe$ORACLE_HOME/bin/or$ORACLE_HOME/lib/folders.
NoteEXTPROC_DLLSisanenvironmentparametersetinextproc.ora,(discussedlaterinthischapter).
CalloutandCallbackTherearetworelevantterms—calloutandcallback—associatedwiththehandlingofanexternalprogram.
WhenthePL/SQLprocedureinvokesanexternalprocedure,thecallisreferredtoasacallout.IftheexternalprocedureinvokesanSQLstatement,whichdrivesthedatabaseengine,thecallisreferredtoasacallback.
CallSpecificationAcallspecificationisrequiredtopublishanexternalprocedure.Itenablestheregistrationofanexternalprocedure,databaselibrary,parametermapping,memorymanagement,andexternalprocedureexecution.ItconsistsofasetofstatementsembeddedinaPL/SQLsubprogram.ItcanbespecifiedinstandalonePL/SQLsubprograms,PL/SQLpackagespecificationsorbody,andabstractdatatypes.
Thesyntaxforacallspecificationisasfollows:
ASLANGUAGE[C|JAVAmethodsignature]
[LIBRARY(libraryname)]
[NAME(externalprogramname)]
[WITHCONTEXT]
[AGENTIN(formalparameters)]
[PARAMETERS(parameterlist)]
TheASLANGUAGEclausespecifiesthepublicationofCandJavaprograms.TheASEXTERNALclauseisusedtosupporttheexternalprogramswithlegacyapplications.ForJavaprograms,youneedtospecifythecompletesignature.
TheLIBRARYisavalidschemaobject.Itisamandatoryclause.YoumusthavetheEXECUTEprivilegeonthelibrary.
TheNAMEistheexternalprocedurenamethathastobeexecutedinthelibrary.ItisamandatoryinputonlyifthecallingPL/SQLsubprogramisnameddifferentlyfromtheexternalprocedure.
ThePARAMETERSclausespecifiestheparameteralongwiththedatatype,therespectiveposition,andthepassbymethod(passbyvalueorreference).Theremightbesomechallengesinprovidingtheparameterlistbecauseofthedisparatedatatypesavailableacrosstheprogramminglanguages,supportfornullability,andprecision.
HowanExternalProcedureexecutesWheneverthePL/SQLruntimeengineencountersanexternalprocedurecall,theOracleDatabasestartstheextprocprocess.Thedatabasepassesontheinformationreceivedfromthecallspecificationtotheextprocprocess,whichhelpsittolocatetheexternalprocedurewithinthelibraryandexecuteitusingthesuppliedparameters.Theextprocprocessloadsthedynamiclinkedlibrary,executestheexternalprocedure,andreturnstheresultbacktothedatabase.
NoteTheextprocprocessrunsseparatelyfromthemaindatabasekernelprocesses.Evenifitcrashes,itwouldn’timpacttheOracledatabaseinstance.
Ifanyoftheprecedingstepsfailtoexecute,anexceptionisraised.Thefollowingisalistofcommonlyencounteredexceptions:
ORA-28576:LostRPCconnectiontoexternalprocedureagent:ThisexceptionisraisedwhentheOraclelistenerisnotabletoestablishtheconnectionwiththeextprocprocess.ORA-28595:Extprocagent:InvalidDLLpath:ThisexceptionisraisedwhentheextprocprocessisnotabletolocatetheDLLinthespecifiedlocation.Youneedtoensurethatthelibrarypathisaccessiblebytheprocess.ORA-06521:PL/SQLErrormappingfunction:Thisexceptionisraisedwhentheexternalprogramiswronglyprototypedinthecallspecification.Thereasonscouldbeaparameterdatatypemismatchorthewrongprogramname.
EnvironmentsetupTheextprocprocessattemptstolocatethelibraryfilesinanaccessiblelocation.Thelocationofthetargetlibrariescaneitherbespecifiedwiththelistenerorinanextproc.orafile.Bydefault,theextprocprocesswillbestartedbytheOracleDatabase.Ifyouwanttocontinuewiththedefaultbehavior,itisrecommendedtospecifythelibrarypathsinextproc.ora.
Ifyouareworkingwithdistributeddatabasesoramultithreadedextprocagent,youcanoverridethedefaultbehaviorbymodifyinglistener.orafile.
TNSNAMES.oraTheTNSNAMES.orafilethatgetsconfiguredatthetimeofthedatabasesoftwareinstallation(orcanbeconfiguredlater),includesanentryfortheORACLR_CONNECTION_DATAservicetosupportexternalservices.ThisserviceverifiesthenetworkconnectionbyusingtheADDRESSparametervalueandconnectsusingtheCONNECT_DATAparametervalue.Thefollowingistheentryintnsnames.orafile:
ORACLR_CONNECTION_DATA=
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521))
)
(CONNECT_DATA=
(SID=CLRExtproc)
(PRESENTATION=RO)
)
)
TheADDRESSparametervaluechecksforthelistener,whichcanreceiveIPC(InternetProcedureCalls)requeststhroughtheKEYvalue,EXTPROC1521.ThePROTOCOLparameterhasafixedIPCvaluetoestablishtheinteractionbetweentheserverandexternalservicerequests.OncetheADDRESSsetupmatchesthecurrentactivelistener,itusestheCONNECT_DATAparametervaluetospawntheextprocprocess.ThePRESENTATIONparameterisaperformanceoptimizingparameterthatdirectsthedatabaseservertoconcentrateandrespondtotheclientthroughaprotocol—Remote-Ops(RO).
TipCLRExtprocisalistenermodethatallowsaPL/SQLprogramstoaccessexternalprograms.
EXTPROC.oraInthedefaultconfiguration,youwillneedtosettheEXTPROC_DLLSenvironmentvariableinextproc.orafortheextprocprocess.Thesyntaxtobeusedisasfollows:
SETEXTPROC_DLLS=<librarypath>
ThepossiblevaluesfortheenvironmentvariableareONLY,ANY,oracolon(:),separatedbytheactualDLLpath.
NULL(default):Theextprocprocesscanonlyloadthelibrarieslocatedinthe$ORACLE_HOME/binand$ORACLE_HOME/libpaths.ONLY:[DLL:DLL…]:Thisprovidesmaximumprotectionbylimitingthenumberoflibrariesonthesystem.Theextprocprocessloadseitheroftheselibraries.[DLL:DLL…]:ThisallowsyoutospecifytheDLLpathsseparatedbyacolon.Theextprocprocesscanloadthelibrarieslocatedinthesepathsorfromthe$ORACLE_HOME/binand$ORACLE_HOME/libfolders.ANY:ThisallowsanyDLLontheservertobeloadedbytheextprocprocess.
TipUseasemicolonasadelimiterwhilespecifyinglibrariesonaWindowsserver.
Inadistributeddatabasesystem,youneedtousethemultithreadedextprocprocesstobespawnedbytheOraclelistenerandnotthedatabase.TheadvantageofhavingthemultithreadedextprocagentinanOracleDatabasesharedserverarchitectureisoptimizedresourceconsumption.Itusesasharedpoolofextprocagentthreadswhicharesequentiallyassignedinandatabasesessionsinaqueue.Themultithreadedextprocagentensurestheefficientutilizationofthesystemresources.
NoteWhenrunninganOracledatabaseserverinsharedmode,theagentprocessandlistenermustresideonthesamephysicalserver.
ExecutingexternalCprogramsfromPL/SQLLet’suswalkthroughanillustrationonhowtoexecuteanexternalprocedure,writtenintheClanguage,intheOracleDatabase.
Step1:CreatingandcompilingtheCprogram.
ThefollowingCprogram(GetMax.c)findsthemaximumofthetwonumbervalues:
#include<stdio.h>
/*Definethefunctionreturningthemaxbetweentwonumbers*/
intGetMax(intnum1,intnum2)
{
/*localvariabledeclaration*/
intresult;
if(num1>num2)
result=num1;
else
result=num2;
returnresult;
}
CompiletheprogrambyusingaCcompiler.
sh-4.3#gcc-cGetMax.c
Step2:GeneratingtheDLLandcreatingthelibraryobjectintheOracleDatabase.
WewillnowgeneratetheDLLfortheCprogram:
sh-4.3#gcc-sharedGetMax.c-oGetMax.dll
Thelibrarylocation
Thedefaultpathssearchedbytheextprocprocessforloadingtherequiredlibraryare$ORACLE_HOME/binand$ORACLE_HOME/lib.Fortestingpurposes,wewillcontinuewiththedefaults.Forthisreason,thesettinginextproc.oraremainsunchanged(toNULL),asfollows:
SETEXTPROC_DLLS=
Wewillplacethesharedlibrarygeneratedbythecompilerinthe$ORACLE_HOME/libfolder.Ifyouwanttouseanon-defaultpath,settheEXTPROC_DLLSenvironmentvariableintheextproc.ora($ORACLE_HOME/hs/)file.
ThefollowingscriptcreatesthelibraryobjectintheSCOTTschema.NotethattheSYShasgrantedtheSCOTTusertheCREATELIBRARYprivilege:
/*ConnectasSYSDBA*/
CONNsys/oracleASSYSDBA
/*GranttheCREATELIBRARYprivilege*/
GRANTCREATELIBRARYTOSCOTT
/
Grantsucceeded.
Now,theSCOTTusercancreatealibraryinthedatabaseforthesharedlibrarypath.
/*ConnectasSCOTTuser*/
CONNscott/tiger
/*Createthealiaslibraryobjectusingthe.soDLLpath*/
CREATEORREPLACELIBRARYGetMaxDll
AS'/u01/app/oracle/product/12.1.0.2/db_1/lib/GetMax.so'
/
Librarycreated.
ThelibrarymetadatacanbequeriedfromtheUSER_LIBRARIESdictionaryview.Thisviewcapturesthedataforthelibrariesownedbythecurrentuser:
SELECTlibrary_name,
file_spec,
dynamic,
status
FROMuser_libraries
/
LIBRARY_NAFILE_SPECDSTATUS
--------------------------------------------------
GETMAXDLL/u01/app/oracle/product/12.1.0.2YVALID
/db_1/lib/GetMax.so
Step3:CreatingthePL/SQLwrapperfunctionwithacallspecification.
FortheGetMaxexternalprogram,let’screateacallspecification.Withinthecallspecification,wewillprovidethelibraryname,Cprogramname,andparameters:
/*Createthefunctionwithcallspecification*/
CREATEORREPLACEFUNCTIONf_get_max
(p_num1PLS_INTEGER,p_num2PLS_INTEGER)
RETURNPLS_INTEGER
/*CallSpecificationstarts*/
ASLANGUAGEC
/*SpecifythePL/SQLlibraryobjectname*/
LIBRARYGetMaxDll
/*Specifytheexternalfunctionname*/
NAME"GetMax"
/*Specifytheparameters*/
PARAMETERS(p_num1,p_num2);
/
Functioncreated.
Step4:TestingthePL/SQLprocedure.
ThefollowinganonymousPL/SQLblockinvokestheF_GET_MAXfunction:
/*EnabletheSERVEROUTPUTtodisplaytheblockoutput*/
SETSERVEROUTPUTON
DECLARE
/*Declarelocalvariables*/
aPLS_INTEGER:=10;
bPLS_INTEGER:=30;
cPLS_INTEGER;
BEGIN
/*CalltheF_GET_MAXfunction*/
c:=F_GET_MAX(a,b);
/*Displaytheoutput*/
DBMS_OUTPUT.PUT_LINE('Themaximumnumberis-'||c);
END;
/
Themaximumnumberis-30
PL/SQLproceduresuccessfullycompleted.
That’sthecorrectresult.WehavejustexecutedaCprogramfromOraclePL/SQL.AssoonasthePL/SQLblockexecutionstarts,youcantracetheextprocprocessbylistingtheprocesses.Theextprocprocessisactiveuntiltheendofthesession.
[oracle@devhost~]$ps-ef|grepextproc
oracle52641015:01?00:00:00
/u01/app/oracle/product/12.1.0.2/db_1/bin/extproc(DESCRIPTION=(LOCAL=YES)
(ADDRESS=(PROTOCOL=BEQ)))
oracle52665115015:01dev/100:00:00grepextproc
TherestrictionsonCexternalproceduresarelistedasfollows:
ThefeatureislimitedtotheplatformsthatsupportdynamicallylinkedlibrariesTheextprocprocessandPL/SQLprocedureneedtobeonthesamehostThelibraryclausecannotpointtoaremotelocationthroughadatabaselinkThemaximumnumberofparameterstoanexternalprocedureis128Parametersofcursorvariabletypesarenotsupportedwithexternalprocedures
SecuringExternalProcedureswithOracleDatabase12cTheOracleDatabasecreatestheextprocprocessandrunsundertheoperatingsystemuser,thatstartsthelistenerorrunsanOracleserverprocess.Quiteoften,youwillseetheextprocprocessrunningastheoracleuser.TheextprocprocessisnotphysicallyassociatedwiththeOracleDatabase.
OracleDatabase12cenablesenhancedsecurityforextprocbyauthenticatingitagainstauser-suppliedcredential.ThisnewfeatureallowsthecreationofausercredentialandassociatesitwiththePL/SQLlibraryobject.Whenevertheapplicationcallsanexternalprocedure,theextprocprocessauthenticatestheconnectionbeforeloadingthesharedlibrary.
TheDBMS_CREDENTIALpackageallowstheconfigurationofthecredentialthroughmembersubprograms.TheCREATELIBRARYstatementhasbeenenhancedforcredentialspecification.Anewenvironmentvariable,ENFORCE_CREDENTIAL,canbespecifiedinextproc.oratocontroltheauthenticationbytheextprocprocess.ThedefaultvalueoftheparameterisFALSE.Anothernewenvironmentvariable,GLOBAL_EXTPROC_CREDENTIAL,servesasthedefaultcredentialandisonlyusedwhenthecredentialisnotspecifiedforalibrary.IfENFORCE_CREDENTIALisFALSEandnocredentialhasbeendefinedinthePL/SQLlibrary,therewillbenouserauthentication;thismeanstheextprocprocesswillauthenticatebyusingtheprivilegesoftheuserrunningtheOracleserver.
ThefollowingPL/SQLblockcreatesacredentialbyusingDBMS_CREDENTIAL.CREATE_CREDENTIAL.ThiscredentialisbuiltusingtheORADEVuser:
BEGIN
DBMS_CREDENTIAL.CREATE_CREDENTIAL(
credential_name=>'devhost_auth',
user_name=>'oradev',
password=>'oradev')
END;
/
ThelibrarydefinitionwillincludeanadditionalCREDENTIALclause:
CREATEORREPLACELIBRARYmyextlib
AS'HelloWorld.so'
CREDENTIALdevhost_auth
/
Whentheextprocprocessreadsthecallspecificationandfindsthesharedlibrarywithasecuredcredential,itauthenticatesthelibraryonbehalfofthecredentialandthenloadsit.
ExecutingJavaprogramsfromPL/SQLLiketheCprograms,JavaprogramscanalsonativelyexecuteintheOracleDatabase.However,unlikeCexternalprograms,theJavaclassesandJavasourcefilesarestoredasschemaobjectsinthedatabase.
ExternalJavaprogramsarenotexecutedthroughOS-basedsharedlibrariesbutuseaJavasharedlibraryorlibunitforexecution.Libunitsaresimilartodynamicallylinkedlibrariesbuttheyaremappedone-to-onetotheJavaclassandarenotsharableacrosstheothermethods.
ThelibunitisloadedandexecutedbytheJavaVirtualMachine(JVM)whichresidesnativelyintheOracleDatabase.TheJVMusestheJavapoolcomponentofthesharedglobalareatoexecutetheJava-basedexternalprogram.
LoadingaJavaclassintoadatabaseAJavaprogramcanbeloadedintoanOracleDatabasebyusingtheCREATEJAVAstatementortheLOADJAVAutility.
TheCREATEJAVAstatementenablestheJavaVirtualMachinelibrarymanagertoloadaJavaclassintotheOracleDatabaseandgeneratetheRDBMSsharedlibraryorlibunitinthetargetdirectory.TheCREATEJAVAstatementsyntaxisasfollows:
CREATEJAVACLASSUSINGBFILE(directory,javaclass)
JavaclassescanalsobeloadedbyusingtheLOADJAVAutility.ThecommandlineutilityuploadstheJavaclassasalargeobjectinasystem-generatedtableandgeneratesthesharedlibrary.
Theloadjavautilitycanbeusedasperthefollowingsyntax:
loadjava{-user|-u}username/password[@database][option…]
filename[filename]...
TipYoucanuseloadjava-h|-helptogetahelperindex.
StepstoexecuteaJavaclassfromanOraclePL/SQLunitInthissection,wewillillustratetheloadingofaJavaclassintoanOracleDatabaseandinvokeitbyusingaPL/SQLprocedure.
Step1:CreatingaJavaclass.
TheComputeJavaclassincludesthefollowingtwomethodstoaddandmultiplytwonumbers:
publicclassCompute{
publicstaticintSum(intx,inty){
returnx+y;
}
publicstaticintCross(intx,inty){
returnx*y;
}
}
Step2:LoadingtheJavaclassintoOracle.
WewillnowuploadtheJavaclassintotheOracleDatabasebyusingtheloadjavautility:
[oracle@devhost~]$loadjava-userscott/tigerCompute.java
Asuccessfuluploadoperationgetsterminatedwithoutanyconfirmationmessage.YoucanconfirmtheloadoperationbyqueryingtheJavaclassintheUSER_JAVA_CLASSES,USER_OBJECTSandUSER_SOURCEdictionaryviews:
/*QuerytheUSER_JAVA_CLASSESview*/
SELECTname,kind,accessibility,source
FROMuser_java_classes
/
NAMEKINDACCESSIBILITYSOURCE
---------------------------------------
ComputeCLASSPUBLICCompute
/*QuerytheUSER_OBJECTSview*/
COLobject_nameformata30
SELECTobject_name,object_type,status
FROMUSER_OBJECTS
WHERETRUNC(created)=TRUNC(SYSDATE)
ORDERBYtimestamp
/
OBJECT_NAMEOBJECT_TYPESTATUS
---------------------------------------------------------
SYS_LOB0000093463C00002$$LOBVALID
SYS_IL0000093463C00002$$INDEXVALID
SYS_C0010407INDEXVALID
CREATE$JAVA$LOB$TABLETABLEVALID
JAVA$OPTIONSTABLEVALID
ComputeJAVASOURCEINVALID
ComputeJAVACLASSINVALID
7rowsselected.
YoucanignoretheinvalidstatusoftheJAVASOURCEandJAVACLASSobjects.Theybothwillgetvalidateduponinvocation.
TheJAVA$OPTIONStablestoresthecompileroptions:
SELECT*
FROMJAVA$OPTIONS
/
WHATOPTVALUE
-------------------------------------------------------
ComputeencodingUTF-8
Thesystem-generatedCREATE$JAVA$LOB$TABLEtablestorestheJavaclassasaSecureFilelargeobject.
NoteStartingwithOracleDatabase12c,SecureFileisthedefaultstoragemechanismforlargeobjects.
Let’sdrilldownbyasteptofurthercheckoutthetablestructurefromtheUSER_TAB_COLSdictionaryview:
SELECTtable_name,
column_name,
data_type
FROMuser_tab_cols
WHEREtable_name='CREATE$JAVA$LOB$TABLE'
/
TABLE_NAMECOLUMN_NAMEDATA_TYPE
-----------------------------------------------------
CREATE$JAVA$LOB$TABLELOADTIMEDATE
CREATE$JAVA$LOB$TABLELOBBLOB
CREATE$JAVA$LOB$TABLENAMEVARCHAR2
VerifytheLOBstorageasaSecureFilefortheLOBcolumninthetable:
SELECTtable_name,column_name,securefile
FROMuser_lobs
WHEREtable_name='CREATE$JAVA$LOB$TABLE'
/
TABLE_NAMECOLUMN_NAMESEC
----------------------------------------------
CREATE$JAVA$LOB$TABLELOBYES
Step3:PublishingtheJavaclassmethodbyusingacallspecification.
Let’screateaPL/SQLwrapperthatwillincludeacallspecificationtoregistertheJavaprogramandspecifytheparametermapping.Notethat,unlikeCprogrampublishing,youdon’tneedtospecifythelibraryunitandexternalprocedurename.TheASLANGUAGEprovidestheinterfacebetweentheJavaclassandOraclePL/SQL.
Thesyntaxforthecallspecificationisasfollows:
{IS|AS}LANGUAGEJAVA
NAME'method_fullname(parameters)
[returnjava_type_fullname]';
WeshallnowcreatethecallspecificationfortheComputeJavaclass.ThestandalonefunctionacceptstwonumbersandreturnstheirsumusingtheSummethod:
/*FunctiontopublishJavaclassmethod*/
CREATEORREPLACEFUNCTIONF_COMPUTE_SUM
(P_XNUMBER,P_YNUMBER)
RETURNNUMBER
AS
/*Specifytheexternalprogramsbaselanguage*/
LANGUAGEJAVA
NAME'Compute.Sum(int,int)returnint';
/
Functioncreated.
Step4:VerifyingtheJavaclassexecutionmethod.
Let’sinvoketheF_COMPUTE_SUMfunctiontoverifytheexecutionoftheJavaclassmethod:
variablexnumber;
variableynumber;
exec:x:=100;
PL/SQLproceduresuccessfullycompleted.
exec:y:=95;
PL/SQLproceduresuccessfullycompleted.
variableresultnumber;
exec:result:=f_compute_sum(:x,:y);
PL/SQLproceduresuccessfullycompleted.
printresult
RESULT
----------
195
SummaryExternalproceduresdemonstratetheextensibilityfeatureofanOracleDatabasethatallowsaprogramdevelopedinnon-Oraclescriptinglanguagetobeexecutednativelyinthedatabasekernel.Thereaderswillfinditinterestingtoexplorehowtheycanenablecomplexalgorithmstorunontheserverside.
Inthenextchapter,wewillbediscussingadatasecurityfeaturecalledVirtualPrivateDatabase.Fromadataaccessstandpoint,thisfeatureisquiteimportantandeasytoimplementwithbiggerbenefits.
PracticeexerciseWhichofthefollowingstatementsaretrueabouttheextprocprocess?
1. ItloadsthesharedlibraryoftheexternalCprogram.2. ItisstartedbythePL/SQLruntimeengine.3. Itisasession-specificprocess.4. TheextprocprocesscompilestheCprogramwhileloading.
Oracle7introducedtheexternalprocedurefeatureforsendinge-mailsfromPL/SQL.
1. True2. False
DeterminetheeffectofdroppingthelibraryobjectthathasbeenusedinaPL/SQLcallspecificationwhileitisstillinuse:
1. ThePL/SQLwrappermethodgetsinvalidated.2. Thesharedlibrarygetscorrupted.3. ThePL/SQLwrappermethodstillworksfineasithasalreadybeenexecuted
once.4. ThePL/SQLwrappermethodgivesnooutput.
ExaminethefollowingTNSNAMES.oraandLISTENER.oraentriesandchoosethecorrectoption:
//TNSNAMES.ora
ORACLR_CONNECTION_DATA=
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521))
)
(CONNECT_DATA=
(SID=extproc)
(PRESENTATION=RO)
)
)
//LISTENER.ora
SID_LIST_LISTENER=
(SID_LIST=
(SID_DESC=
(SID_NAME=CLRExtproc)
(ORACLE_HOME=C:\ORCL\11.2.0\dbhome_1)
(PROGRAM=EXTPROC1521)
(ENVS=
"EXTPROC_DLLS=ONLY:C:\ORCL\product\11.2.0\dbhome_1\BIN\Ext.dll")
)
)
LISTENER=
(DESCRIPTION_LIST=
(DESCRIPTION=
(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))
)
)
1. TheKEYvalueunderADDRESSofORACLR_CONNECTION_DATAmustbeextproc.2. TheSIDvalueunderCONNECT_DATAofORACLR_CONNECTION_DATAmustbe
CLRExtproc.3. TheKEYvalueunderADDRESSofLISTENERmustbeextproc.4. ThePROGRAMvalueofSID_LIST_LISTENERmustbeextproc.
Whichofthefollowingstatementsabouttheloadjavautilityaretrue?
1. ItgeneratesasharedlibraryfortheJavaprograms.2. ItloadstheJavaprogramintheOracleDatabase.3. TheloadjavautilityrequiresaJavacompilertorun.4. ItloadstheJavaclassfileintotheJavapoolinthedatabaseinstance.
ExternalprogramsinJavadon’trequirethesharedlibrariestobeexecutedfromPL/SQL.
1. True2. False
AnexternalCprogramlookslikethis:
#include<stdio.h>
#include<conio.h>
intGetDouble(intnum)
{
returnnum*2;
getch();
}
ThePL/SQLwrappermethodlookslikethis:
CREATEORREPLACEFUNCTIONF_GET_DOUBLE(P_NUMNUMBER)
RETURNNUMBER
ASEXTERNALLIBRARYNUMLIB
NAME"GETDOUBLE"
LANGUAGEC
PARAMETERS(P_NUMINT);
WhenyoucallthePL/SQLwrapper,yougetthefollowingexception:
DECLARE
*
ERRORatline1:
ORA-06521:PL/SQL:Errormappingfunction
ORA-06522:UnabletoloadsymbolfromDLL
ORA-06512:at"ORADEV.F_GET_DOUBLE",line1
ORA-06512:atline4
Identifythecauseforthisexception:
1. TheNUMLIBlibraryhasbeenincorrectlyplaced.2. TheCprogramhassyntacticalerrors.3. TheCprogramnameinthecallspecification(thePL/SQLwrapper)shouldbe
GetDoubleinsteadofGETDOUBLE.4. Theextprocprocessisnotworkingproperly.
Chapter6.VirtualPrivateDatabaseInformationsecurityisoneofthekeychallengesthatorganizationshavetoaddresstoprotectdataprivacyanditsregulation.Leakageofsensitiveinformationorunauthorizedaccesstodatamightleadtohazardousconsequences.Withthestringentprotocolsofdatadistributionandsteepriseoftheinternetusage,datasecuritycanposeatediousquestiontotheorganizations.Informationthatispronetoinvasionscanbepersonaldetails,financialdata,creditcardinformation,businessleads,oranintellectualproperty.Arelationaldatabasecanexposepotentialareasofinjectionintheformofnetworkaccess,overprivilegeduseraccounts,non-databasefileaccess,nonsanitizedinputs,andproliferationofproductiondatatounregulatedenvironments.Knowingthefatalconsequencesofdatabreaches,thedatasecuritysolutionsmustbeefficienttobypasstheattacksfromthedatabaselayer,network,andapplication.
Inthischapter,wewillwalkthroughanoverviewofOracle’sDatabaseSecuritysolution.WewillfocusontheimplementationofaVirtualPrivateDatabasetodevelopsecureapplications.Inaddition,wewillhighlightthekeysecurityenhancementsinOracleDatabase12c.
OracleDatabaseSecurityoverviewVirtualPrivateDatabaseOracleDatabase12cSecurityenhancements
OracleDatabaseSecurityoverviewOracleoffersacomprehensivesuiteofdatabasesecuritysolutionsthataimtosecurethedatabasesandapplicationsbyprotectingsensitiveinformation,detectingthreatsandattacks,andmanagingsecuritypoliciesalongthelinesoforganizationalcompliance.Thedefense-in-depthapproachofOraclecanbecategorizedunderpreventive,detective,andadministrativecontrolsthatensureallthevulnerableareasofanapplicationarecovered.Apowerfulsecuritystrategycanbedevelopedandlaiddownbyusingtherightmixofsecurityfeatures.Thefactorsimpactingtheformulationofasecuritystrategycanbethreatanticipation,datasensitivity,datadistributionanduserclassification,compliance,andinternalregulations.
Eachoftheabovecategoriesincludesvariousproductsandtechnicalfeatures.Thefollowingdiagrambifurcatesthesecuritypillarsintosecuritymeasures:
OracleDatabasesecurityfeatureunderthreecategories
TheOracleDatabaseSecuritysolutionincludesthefollowingdatabaseproducts:
OracleAdvancedSecurity:OracleAdvancedSecurityisalicensedoptionavailablewiththeOracleDatabaseEnterpriseEdition.Thisoptionincludesvariousfeaturesthatcanbeimplementedatthedatabaseleveltopreventdatahackingandreducethedirectexposureofsensitiveinformationtoanunauthorizeduser.IthelpsprotectthedatafrommaliciousattacksandcomplywiththesecurityregulationslikePaymentCardIndustryDataSecurityStandard(PCI-DSS)andHealthInsurancePortabilityandAccountabilityAct(HIPAA).Forexample,youcanencryptthecustomer’sbankaccountinformationinthedatabase.Similarly,thesensitiveinformationinthedatabasecanberedactedforsupportorcallcenterexecutives.
TheOracleAdvancedSecurityoptionincludes:
DataRedaction:TheDataRedactionfeaturewasintroducedinOracleDatabase12ctoapplyon-the-flymaskingpoliciestothesensitiveinformationinthedatabase.ThefeaturehasbeenbackportedtoOracleDatabase11.2.0.4.Dataredactioncanbeahandyfeatureasitiscost-efficientanddynamicallyobfuscatesthedata.ThisfeatureiscoveredindetailintheOracleDatabase12cSecurityEnhancementssectionofthischapter.TransparentDataEncryption(TDE):Theencryptionfeaturepreventsthedata,whichislyinginstorage,fromoutsideattacks.Thedataisstoredinanencryptedformat,whichgetsauto-decrypted.ItisinstalledatthetimeoftheOracleDatabasesoftwareinstallation.Itisaneasy-to-implementtransparentsolutionandrequiresnochangestotheexistingSQLqueries.
NoteSecurefileencryptionispartoftheAdvancedSecurityoption.
TheotherfeaturesincludedundertheAdvancedSecurityoptionareDataPumpExportfileencryptionandRMANBackupencryptiontodisk.
VirtualPrivateDatabase(VPD):ThisisasecurityfeatureavailableinOracleDatabaseEnterpriseEditionthatcontrolsthedatavisibilityandaccessibilitydependingonthedatabaseuserauthorization.FirstintroducedinOracle8i,thefeatureworkswithVPDpoliciesandsessioncontexts.Allqueriesissuedbyauserareappendedbyanadditionalpredicatetorestricttherowsintheresultset.ItisalsoknownasFineGrainedAccessControlorRowLevelSecurity.RealApplicationSecurity(RAS):ThisfeaturewasintroducedinOracleDatabase12ctosupportthediversifiedsecurityrequirementsinanenterpriseapplicationmodel.ItpresentsanadvancedversionoftheVirtualPrivateDatabasetechnology.Notonlythedatavisibility,aRealApplicationSecuritypolicyalsoallowsyoutocontrolthetransactionalpermissionsontheapplicationobjects.Itisoneofthesmartestsecuritysolutionsthatcancontroltheprivilegesofanapplicationuseronthebusinessobjects.OracleKeyVault(OKV):OracleKeyVaultprovidesarobustkeymanagementplatformthatcanbeusedasthecentralizedrepositoryofTDEmasterkeys,Oraclewallets,Javakeystores,SSHkeys,andothersecuritycredentialfiles.TheOKVstoreallowstheend-to-endadministrationofthekeylifecycleincludingcreation,retention,andkeyrotation.OracleDatabaseVault:OracleDatabaseVaultenablesasecuritysolutiontosafeguardtheapplicationdatafromprivilegeddatabaseusersandadhocaccess.Amultifactordatabasevaultpolicyimposesdeterrentcontrolsontheuseraccesstothedatabaseandreportsviolations,ifany.ItisapowerfulproactivesolutionthathelpsinreducingtheattacksurfaceforhighlyprivilegeduserslikeSYSTEM,SYSDBA,orauserwithalargesetofrolesandprivileges.OracleprovidesdefaultvaultpoliciesfortheOracleE-BusinessSuite(versions11.5.10,12.0,and12.1),OraclePeopleSoftapplication,OracleSiebelCRM(version7.7andhigher),andSAPapplications.PrivilegeAnalysis:ThenewfeatureinOracleDatabase12canalyzestheprivileged
users,roles,anddatabasetoreporttheusedandunusedprivileges.Basedontheanalysis,thesecurityadministrator(ortheDBA)candeterminewhethertoretainorrevoketheprivilegesofthedevelopersordatabaseusers.Thisfeatureisquiteimportantfromthepointofviewofapplicationsecurityandhelpsreducetherisksfrominternalusers.OracleDataMaskingandSubsetting:TheOracleDataMaskingandSubsettingpackmaskstheoriginalcopyoftheapplicationdatabyphysicallyobfuscatingthesensitiveinformationineitherthecompleteapplicationdatabaseorjustitssubset.Themaskeddatacanthenbeproliferatedforanalytical,testing,orregulatorypurposes.Thesensitiveinformationandreferentialintegritymodelcanbediscoveredbasedontheprebuiltdatapatterns.Aportionofalargedatabasecanbeextractedbasedonfactorssuchaspercentage,thenumberofrows,orcolumnpredicates.Thispackcontainsavarietyofmaskingformatsandtransformationsthatcanbeappliedtotheapplicationdata.OracleLabelSecurity(OLS):OracleLabelSecurity,firstintroducedinOracle8i,isadatabaseoptionavailableintheenterpriseeditionoftheOracleDatabase.Itenablestheclassificationofdatabylabels.Thesecuritypoliciescontroltheuseraccessprivilegesandauthorizationontheapplicationbythedatalabels.Thisoptionisveryusefulinimplementingmultilevelsecurityinlargelegacyapplications.OracleAuditVaultandDatabaseFirewall(AVDF):ThisproductcanbedeployedinallOracleDatabaseeditionsandnon-OracleproductssuchasMicrosoftSQLServer,IBMDB2forLUW,SAPSybaseASE,MySQLdatabasesandOracleBigDataAppliance.YoucandefinetherulestocaptureandblocktheunauthorizedSQLaccesstotheapplicationdata.Anotherfeatureofthisproductistheconsolidationofthedatabaseauditwiththesystemandnetworkauditinformation,whichthengeneratesalertsandreports.
NoteStrongauthenticationservicessuchasKerberos,PKI,andRADIUSalongwithnetworkencryptionareavailableinalltheeditionsoftheOracleDatabase.
Fine-GrainedAccessControlInanenterpriseapplication,userisolationorrole-basedmultitenancyensuresthatdataisaccessedbytheauthorizedusersonly.InaSoftwareasaService(SaaS)modelapplication,tenantisolationisoneoftheprimedemands.Applicationusersareauthorizedtoaccessonlytheirworldofdataandnotpeekintootheruser’sdata.
Fine-grainedaccesscontrol(FGAC)enablestheenforcementofsecuritypoliciesontheaccessofrowsandcolumnsbasedontheuser’sroleandauthorization.Forexample,anHRrepresentativeisauthorizedtoviewthedetailsofemployeesthatbelongonlytohisvertical.Similarly,arelationshipofficerinabankisauthorizedtoaccesstheaccountdetailsofthosecustomersthatbelongtohisbranch.TheFGACfeatureprovidesyouwiththemechanismtoexposetheauthorizedpieceofdataonlytotheapproveduser.
HowFGACworksFine-grainedaccesscontrolenablesthecreationofsecuritypoliciesthatcanbeassociatedwithatableorview.Uponinvocation,thesecuritypolicyevaluatesthepolicyfunctionthatreturnsapredicateclause,whichisdynamicallyappendedtotheSQLqueriesissuedbytheuser.Thus,theuserviewsonlytheauthorizedrowsfromthetableoraview.Thesecuritypolicycanlimiteitherrowsorcolumnsorboth.
Inthefollowingfigure,auserfromdepartment10queriestheEMPtable.HeissuesaSELECTstatementtoviewtheemployeedetails.OracleinvokestheFGACpolicyattachedtotheEMPtableandappendsapredicate(thatis,theWHEREclause)totheSELECTquery.ThemodifiedSELECTqueryisthenexecutedintheHRschemaofthedatabase.
HowFine-GrainedAccessControlworks
Thefollowingarethesalientfeaturesoffine-grainedaccesscontrol:
OracleprovidestheDBMS_RLSpackageforthemanagementofsecuritypoliciessuchascreation,drop,enable,anddisableApolicycanbesettobeinvokedonlywhengivencolumnsareaccessedMultiplesecuritypoliciescanbeassociatedwithatableorviewAllsecuritypoliciesandthepredicatesareappendedwiththeANDclause
VirtualPrivateDatabaseTheworkingprincipleoftheVirtualPrivateDatabasetechnologyisthatusersshouldhaveisolatedanddistinguisheddataaccess.VirtualPrivateDatabase(VPD)isafeaturethatisbuiltonfine-grainedaccesscontrolandusesapplicationcontextstodefineandaddthepredicatestotheSQLqueries.SimilartoFGAC,VirtualPrivateDatabaselaysdownthesecurityframeworkthroughthesecuritypoliciesintheOracleDatabaseandassociatesthemdirectlytotables,views,orsynonyms.Thesecuritypoliciesactasasafetynetontheobjects,andbynomeanstheycanbebypassed.
HowdoesVirtualPrivateDatabasework?WheneverauserissuesanSQLqueryagainstaVirtualPrivateDatabaseprotectedtable,Oracleinvokesthepolicyandevaluatesthepolicyfunction.ThepolicyfunctionisaPL/SQLfunctionthatreturnsapredicateoraWHEREclause.Thequeryisthenrewrittenusingdynamicviewstoaddthepredicateclause.Themodifiedqueryisexecutedagainstthedatabaseserverandtheresultsetisreturnedtotheuser.ThepredicateortheWHEREclauseparticipatesintheexecutionofthequery,thatis,thecolumnindexeswillimpactthequeryexecutionplan.
NotethattheVirtualPrivateDatabaseprotectsonlytheSELECT,INDEX,andDMLoperations(INSERT,UPDATE,andDELETE).Itdoesn’tworkwithDDL’slikeTRUNCATEorALTERTABLEstatements.
Column-levelVirtualPrivateDatabaseRow-levelsecuritycanalsobeimposedontablesandviewswheneverauserselectssensitivecolumns.Thesensitivecolumnscanbespecifiedatthetimeofthepolicycreation,thatis,theSEC_RELEVANT_COLSparameteroftheDBMS_RLS.ADD_POLICYprocedure.
Thecolumn-levelpolicyworksonlyfortheSELECTqueries.Whenauserselectssensitivecolumns(implicitlyorexplicitly),thenon-authorizedrowsareexcludedfromtheresultset.Forexample,ifanHRrepresentativequeriespublicinformationsuchasthenameanddepartmentofemployees,thequerywilllistalltherecordsfromthetable.IfheattemptstoselectthesecuredcolumnslikeSAL,theresultsetwillbelimitedbytherow-levelsecuritycondition.
YoucanincludealltherowswiththesensitivecolumnvaluesmarkedasNULL.ItcanbeachievedbyspecifyinganattributeknownasSEC_RELEVANT_COLS_OPTintheDBMS_RLS.ADD_POLICYprocedure.
VirtualPrivateDatabasewithOracleDatabase12cMultitenantVirtualPrivateDatabaseissupportedwithinapluggabledatabase.Youcannotcreateasecuritypolicyintherootcontainer,thatis,thecontainerdatabase.
VirtualPrivateDatabasecomponentsTheVPDtechnologymakesuseoftheapplicationpackage,policyfunction,applicationcontext,andtheDBMS_RLSpackagetoaddpolicies.Inthefollowingsection,wewilldiscussthebuildingblocksoftheVirtualPrivateDatabaseimplementation.
ApplicationContextAVirtualPrivateDatabaseimplementationwithapplicationcontextsisusefulwhenworkingwithmultiplesecurityattributes.Forexample,inanorganization,thedataviewauthorizationmaybedifferentfordifferentjobroles.Inamanufacturingunit,Asupervisorcanbeauthorizedtoquerytheglobalpartswhileanexecutivecanseeonlythelocalparts.Insuchcases,thejobrolecanbeacontextattributewhosevaluecanbeusedinthepredicateclausereturnedbythepolicyfunction.
Applicationcontextsaresessionvariablesthatholdtheuserandsessioninformationsecurely.Contextattributesarestoredaskey-valuepairsunderagivennamespace,whichisalsoknownasalabel.USERENVisasystem-definednamespaceintheOracleDatabasethatcanprovidesessioninformationsuchasDB_NAME,SESSION_USER,andothers.User-definedapplicationcontextscanbecreatedbyaSYSDBAoruserswiththeCREATEANYCONTEXTprivilegebyusingatrustedapplicationpackage.
Anapplicationcontextcanbeeitherdatabasesession-based,clientsession-based,orglobal.
Adatabasesession-basedapplicationcontextisaccessibleonlywithinadatabaseuser’ssession.Itsattributesandvaluesarestoredinasessioncache,UserGlobalArea(UGA).Thedatabasesession-basedapplicationcontextscaneitherbeinitializedlocallyfromthesession,externallyusingadatabaselink,OCIinterfaceorjobqueueprocess,orgloballyfromacentralizeddirectoryusingtheOracleInternetDirectory.Youcanquerythedatabasesession-basedcontextattributesfromtheSESSION_CONTEXTdictionaryview.
Aclientsession-basedapplicationcontextisinitializedusingOCIfunctions(OCIAppCtxSet)andisstoredinUserGlobalArea(UGA)undertheCLIENTCONTEXTnamespace.Theapplicationcansetthenon-databaseattributeswithinthecontextsandusethemduringpolicycreation.Ensurethatthedatabasesessionandclientsession-basedapplicationcontextsdonotconflictwitheachother.
AglobalapplicationcontextcanbeaccessedbyallthedatabaseusersessionsinasingleinstanceorRACenvironment.ThecontextattributesandtheirvaluesarestoredinSystemGlobalArea(SGA),whichcanbequeriedfromtheGLOBAL_CONTEXTdictionaryview.
ThefollowingSQLqueriesthedatabasenamefromtheUSERENVnamespaceusingtheSYS_CONTEXTfunction:
/*QuerythedatabasenamefromUSERENVnamespace*/
SELECTSYS_CONTEXT('USERENV','DB_NAME')
FROMdual
/
SYS_CONTEXT('USERENV','DB_NAME')
-------------------------------------------------------
orcl
Youcancreatedatabasesession-basedapplicationcontextsusingtheCREATECONTEXTstatement,asperthefollowingsyntax:
CREATECONTEXT[context_name]
USING[trusted_package]
INITIALIZED[EXTERNALLY|GLOBALLY]
ACCESSED[LOCALLY|GLOBALLY]
TrustedpackageisaPL/SQLpackageorstoredprocedurethatcontrolsthevaluesofthecontextattributes.Adatabasesession-basedcontextcanbeinitializedlocally,externallyorglobally.ThecontexttypecanbeACCESSEDGLOBALLYforglobalapplicationcontextsorACCESSEDLOCALLY(default)forsession-basedapplicationcontexts.Thefollowingexampleshowsthecreationofacontextusingatrustedpackage:
/*ConnectasSYSDBA*/
CONNsys/oracleASSYSDBA
Connected.
/*GrantCREATEANYCONTEXT,DROPANYCONTEXTprivilegestoSCOTT*/
GRANTCREATEANYCONTEXT,DROPANYCONTEXTTOSCOTT
/
Grantsucceeded.
/*ConnecttoSCOTTuser*/
CONNscott/tiger
Connected.
YoucancreatethetrustedPL/SQLprogrambeforeoraftercreatingthecontext.ThefollowingPL/SQLprocedureP_APP_CONTEXTusestheOraclesuppliedpackageDBMS_SESSIONtocreateacontextnamespaceandmemberattributes.
/*Createthestoredproceduretosetthecontextattribute*/
CREATEORREPLACEPROCEDUREp_app_context(p_valVARCHAR2)
IS
BEGIN
/*CreateanamespaceDEMO_CONTEXT*/
DBMS_SESSION.SET_CONTEXT(
NAMESPACE=>'DEMO_CONTEXT',
ATTRIBUTE=>'COUNTRY',
VALUE=>P_VAL);
END;
/
ThePL/SQLprocedurecannowbeusedtocreatetheapplicationcontext.
/*Createthecontext*/
CREATECONTEXTdemo_contextUSINGp_app_context
/
Contextcreated.
Now,usethetrustedprogramtosetthevalueoftheCOUNTRYcontextkey.Usethesameprogramtomodifythecontextattributevalue.
/*CallP_APP_CONTEXTtosetcontextvalue*/
EXECp_app_context('LUXEMBOURG')
/
PL/SQLproceduresuccessfullycompleted.
/*QuerytheCOUNTRYcontext*/
SELECTSYS_CONTEXT('DEMO_CONTEXT','COUNTRY')
FROMDUAL
/
SYS_CONTEXT('DEMO_CONTEXT','COUNTRY')
----------------------------------------------------------------
LUXEMBOURG
VirtualPrivateDatabasepolicyfunctionTheVirtualPrivateDatabasepolicyfunctionisaPL/SQLfunctionthatisusedtoconstructthepredicate(orWHERE)clause.Thepolicyfunctionisspecifiedduringpolicycreationthatgetsexecutedatthetimeofpolicyenforcement.Notethatthefunctionexecutionperformancedirectlyimpactsthequeryperformance.
Thefollowingarethefeaturesofthepolicyfunction:
Theschemanameanddatabaseobjectnamearemandatoryparameters(andinthesamesequence)tothepolicyfunction.Uponexecution,theparametervaluesaresuppliedbytheDBMS_RLSpackage.Thefunctionmustreturnavalidpredicateinstringformat.ThefunctionmustnotperformSELECTorDMLonthetabletobeprotectedthroughtheVirtualPrivateDatabase.
PolicytypesYoucanspecifyapolicytypetooptimizetheperformanceofaVirtualPrivateDatabasesecuritypolicy.Thepolicyperformanceislimitedbytheresourcesconsumedduringtheexecutionofthepolicyfunctionandfrequencyofitsexecution.
AVirtualPrivateDatabasepolicycanbeSTATIC,DYNAMIC,SHARED_STATIC,CONTEXT_SENSITIVE,orSHARED_CONTEXT_SENSITIVE.ThefollowingtableshowsthedifferentVPDpolicytypes:
Policytype Comments Whentouse
STATIC
SamepredicateforallthequeriesPredicateclauseiscachedinSGA
Usedwhenallthequeriesonatablehaveamandatorypredicateandperformanceisthepriority.
Policyfunctionisexecutedforeveryquery Usedwhenthepredicateconditionchangesforeach
DYNAMIC(Default) Noperformanceoptimization
queryissuedontheVirtualPrivateDatabaseprotectedobjectortable.
SHARED_STATIC
PolicyshareableacrossschemaobjectsPredicateclauseiscachedinSGA
Usedwhenmultipletablesorviewshavethesamecolumns.
CONTEXT_SENSITIVE
PolicyisapplicableonlytoafixedvalueoftheapplicationcontextIncludethenamespaceandattributeparametersinthepolicydefinition
Usedwhenthepredicatevariesbytheuserorgroup.
SHARED_CONTEXT_SENSITIVE
Sameasthecontext-sensitivepolicyPolicycanbesharedamongmultipleobjects
Usedwhenthepredicatevariesbytheuserandcanbesharedbymultipledatabaseobjects.
TheDBMS_RLSpackageThesecuritypoliciesareenforcedusingtheOracle-suppliedDBMS_RLSpackage.Itcanbeusedtoadd,drop,orrefreshasecuritypolicy,enableordisableapolicy,andhandlethepolicygroups.ItisownedbytheSYSuserandavailableinenterpriseeditiononly.
NoteForcompletedetails,itisrecommendedthatyourefertotheOracleDatabase12cdocumentationathttps://docs.oracle.com/database/121/ARPLS/d_rls.htm.
ThefollowingtableliststhesubprogramscontainedintheDBMS_RLSpackage:
Subprogram Description
ADD_POLICY Addsafine-grainedaccesscontrolpolicytoatable,view,orsynonym
DROP_POLICY Dropsafine-grainedaccesscontrolpolicyfromatable,view,orsynonym
REFRESH_POLICY Causesallthecachedstatementsassociatedwiththepolicytobereparsed
ENABLE_POLICY Enablesordisablesafinegrainedaccesscontrolpolicy
CREATE_POLICY_GROUP Createsapolicygroup
ADD_GROUPED_POLICY Addsapolicyassociatedwithapolicygroup
ADD_POLICY_CONTEXT Addsthecontextfortheactiveapplication
DELETE_POLICY_GROUP Deletesapolicygroup
DROP_GROUPED_POLICY Dropsapolicyassociatedwithapolicygroup
DROP_POLICY_CONTEXT Dropsadrivingcontextfromtheobjectsothatitwillhaveonelessdrivingcontext
ENABLE_GROUPED_POLICY Enablesordisablesarow-levelgroupsecuritypolicy
DISABLE_GROUPED_POLICY Disablesarow-levelgroupsecuritypolicy
REFRESH_GROUPED_POLICY Re-parsestheSQLstatementsassociatedwitharefreshedpolicy
DemonstrationThissectiondemonstratestheimplementationofaVirtualPrivateDatabasetoenforcerow-levelandcolumn-levelsecurity.
Let’ssupposethatSCOTTisamasteruserthatownstheemployeedetails.Allothersubusersareauthorizedtoviewthedetailsoftheemployeesthatbelongtotheirjobroles.Forexample,CLERKisauthorizedtoviewonlytheclerk’sdetailswhileSALESisauthorizedtoviewonlysalesmandata.
Let’spreparethetestenvironmentbycreatingthetestusersandgrantingthemrequiredprivileges:
/*CreateuserCLERK,MGR,SALES.GrantCONNECT,RESOURCEroles*/
CONNsys/oracleassysdba
CREATEUSERclerkIDENTIFIEDBYclerk
/
CREATEUSERmgrIDENTIFIEDBYmgr
/
CREATEUSERsalesIDENTIFIEDBYsales
/
GRANTCONNECT,RESOURCETOclerk
/
GRANTCONNECT,RESOURCETOmgr
/
GRANTCONNECT,RESOURCETOsales
/
GRANTEXECUTEONdbms_rlsTOpublic
/
GRANTCREATEANYCONTEXTTOscott
/
GRANTCREATEPUBLICSYNONYMTOscott
/
Let’screatetheMYJOBcontextusingatrustedprogram:
CONNscott/tiger
/*CreatethecontextMYJOB*/
CREATECONTEXTmyjobUSINGscott.job_context
/
ThefollowingJOB_CONTEXTproceduresetstheMYJOBcontextattributes,basedonthecurrentsessionuser.Thecontextattributevaluesshouldmatchtheexpectedvaluetobeusedinthequerypredicates:
/*CreatethePL/SQLprocedure*/
CREATEORREPLACEPROCEDUREjob_contextIS
BEGIN
/*Setthecontextbasedonthesessionuser*/
IFSYS_CONTEXT('USERENV','SESSION_USER')='CLERK'THEN
DBMS_SESSION.SET_CONTEXT('myjob','role','CLERK');
ELSIFSYS_CONTEXT('USERENV','SESSION_USER')='SALES'THEN
DBMS_SESSION.SET_CONTEXT('myjob','role','SALESMAN');
ELSIFSYS_CONTEXT('USERENV','SESSION_USER')='MGR'THEN
DBMS_SESSION.SET_CONTEXT('myjob','role','MANAGER');
ENDIF;
END;
/
AsthisprocedurewillbeaccessedbySALES,CLERK,andMGR,let’screateapublicsynonymandgranttheexecuteprivilegetotheusers:
/*CreatesynonymforJOB_CONTEXTprocedure*/
CREATEPUBLICSYNONYMjob_contextFORscott.job_context
/
GRANTEXECUTEONscott.job_contextTOclerk,mgr,sales
/
/*GrantselectprivilegeonEMPtabletotheusers*/
GRANTSELECTONempTOclerk,mgr,sales
/
Tosetthecontextatthetimeofthedatabaselogon,let’screatealogontrigger.Thistriggercallsthecontextsettingprocedure:
CONNsys/oracleASSYSDBA
/*Createalogontrigger*/
CREATEORREPLACETRIGGERscott.set_security_context
AFTERLOGONONDATABASE
BEGIN
scott.job_context;
END;
/
Now,it’stimetocreatetheVirtualPrivateDatabasepolicyfunction.Itlaysdownthelogicofrow-levelsecuritybyconstructingthepredicateclause.Inthiscase,thesecuritypolicyvirtuallypartitionsthedataviewbyjobroles.ThepredicateusestheSYS_CONTEXTfunctiontoretrievethejobrolecorrespondingtothesessionuser.
CONNscott/tiger
/*Createpolicyfunction*/
CREATEORREPLACEFUNCTIONfun_vpd
(schemaownerVARCHAR2,objectnameVARCHAR2)
RETURNVARCHAR2IS
BEGIN
/*Returnthepredicateclause*/
RETURN'job=SYS_CONTEXT(''myjob'',''role'')';
END;
/
/*Createpublicsynonymforthepolicyfunction*/
CREATEPUBLICSYNONYMfun_vpdFORscott.fun_vpd
/
GRANTEXECUTEONscott.fun_vpdTOclerk,mgr,sales
/
ThefinalstepisthecreationofpolicyontheobjectusingtheDBMS_RLS.ADD_POLICYprocedure:
connscott/tiger
BEGIN
DBMS_RLS.add_policy(
object_schema=>'SCOTT',
object_name=>'EMP',
policy_name=>'VPD_RLS',
function_schema=>'SCOTT',
policy_function=>'FUN_VPD',
statement_types=>'SELECT');
END;
/
Let’sconnecttotheMGRuserandverifytheVirtualPrivateDatabaseinoperation:
connmgr/mgr
SELECTempno,ename,job,mgr,deptno
FROMscott.emp
/
EMPNOENAMEJOBMGRDEPTNO
----------------------------------------
7566JONESMANAGER783920
7698BLAKEMANAGER783930
7782CLARKMANAGER783910
TheCLERKusercanquerythedetailsofonlythoseemployeesthatareclerks.Similarly,theotheruserscantrytologinthedatabaseandverifythedataview:
connclerk/clerk
SELECTempno,ename,job,mgr,deptno
FROMscott.emp
/
EMPNOENAMEJOBMGRDEPTNO
-----------------------------------------
7369SMITHCLERK790220
7876ADAMSCLERK778820
7900JAMESCLERK769830
7934MILLERCLERK778210
AndthentheSALESuser:
connsales/sales
SELECTempno,ename,job,mgr,deptno
FROMscott.emp
/
EMPNOENAMEJOBMGRDEPTNO
--------------------------------------------
7499ALLENSALESMAN769830
7521WARDSALESMAN769830
7654MARTINSALESMAN769830
7844TURNERSALESMAN769830
Youcanenforceacolumn-levelpolicybyspecifyingthesensitivecolumnsatthetimeofthepolicycreation.ThefollowingPL/SQLblockdropsthelastVirtualPrivateDatabasepolicyandcreatesanewonetoenforcetherow-levelsecurity:
connscott/tiger
BEGIN
/*Droptherow-levelpolicy*/
DBMS_RLS.DROP_POLICY('SCOTT','EMP','VPD_RLS');
/*CreateacolumnlevelVPDpolicy*/
DBMS_RLS.ADD_POLICY(
object_schema=>'SCOTT',
object_name=>'EMP',
policy_name=>'VPD_COLUMN',
policy_function=>'FUN_VPD',
sec_relevant_cols=>'sal,comm');
END;
/
TheprecedingsecuritypolicyspecifiesthatwheneverauserwilltrytoquerytheSALandCOMMcolumnsoftheEMPtable,therow-levelsecuritywillbeenforced.Let’sverifythisstatementbyconnectingtotheMGRuserandqueryingtheemployeerecords:
CONNmgr/mgr
/*Selectnon-sensitivecolumnsfromEMPtable*/
SELECTempno,deptno,job
FROMscott.emp
/
EMPNODEPTNOJOB
------------------------
736920CLERK
749930SALESMAN
752130SALESMAN
756620MANAGER
765430SALESMAN
769830MANAGER
778210MANAGER
778820ANALYST
783910PRESIDENT
784430SALESMAN
787620CLERK
790030CLERK
790220ANALYST
793410CLERK
14rowsselected.
NotethattheprecedingquerydisplaysalltheemployeesbecausetheSELECTquerydidn’tprojecttheSALandCOMMsensitivecolumns.IfthequeryhadcontainedtheSALcolumn,theoutputwouldhavebeenasfollows:
/*SelectsensitivecolumnsfromEMPtable*/
SELECTempno,deptno,sal,job
FROMscott.emp
/
EMPNODEPTNOSALJOB
----------------------------------
7566202975MANAGER
7698302850MANAGER
7782102450MANAGER
Intheprecedingoutput,theemployeerecordswiththesensitivecolumnsarerestrictedinthequeryoutput.However,youcanstilllistalltheemployeesandmasktheSALandCOMMsensitivecolumnswithNULLsbysettingtheSEC_RELEVANT_COLS_OPTattributetoDBMS_RLS.ALL_ROWS:
CONNscott/tiger
BEGIN
/*Dropthepreviouspolicy*/
DBMS_RLS.DROP_POLICY('SCOTT','EMP','VPD_COLUMN');
/*Createanewcolumn-levelpolicy*/
DBMS_RLS.ADD_POLICY(
object_schema=>'SCOTT',
object_name=>'EMP',
policy_name=>'VPD_COLUMN',
policy_function=>'FUN_VPD',
sec_relevant_cols=>'sal,comm',
sec_relevant_cols_opt=>DBMS_RLS.ALL_ROWS);
END;
/
Withtheprecedingsecuritypolicy,theoutputoftheSELECTquerywillbeasfollows:
CONNmgr/mgr
/*SelectsensitivecolumnsfromEMPtable*/
SELECTempno,ename,job,sal,deptno
FROMscott.emp
ORDERBYjob
/
EMPNOENAMEJOBSALDEPTNO
------------------------------------------------------------
7788SCOTTANALYST20
7902FORDANALYST20
7934MILLERCLERK10
7900JAMESCLERK30
7369SMITHCLERK20
7876ADAMSCLERK20
7698BLAKEMANAGER285030
7566JONESMANAGER297520
7782CLARKMANAGER245010
7839KINGPRESIDENT10
7844TURNERSALESMAN30
VirtualPrivateDatabasefeaturesandbestpracticesThefollowingarethefeaturesandbestpracticesthatcanbefollowedwhileworkingwithaVirtualPrivateDatabase:
YoucannotqueryaVirtualPrivateDatabaseprotectedtableasSELECTFORUPDATEbecauseofthequeryrewriteimplementation.However,theFORUPDATEuserquerymayworkprovidedtheVPDimpliedinlineviewforthequeryisnotacomplexone,thatis,anon-analyticquery,withnoDISTINCT,nocursorexpression,noSEToperator.SYSuserisexemptedfromtheVirtualPrivateDatabasesecuritypolicies.However,theSYSDBAactionscanbemonitoredusingDatabaseVault.UserswiththeEXEMPTACCESSPOLICYsystemprivilegeareexemptfromtheVirtualPrivateDatabasesecuritypolicies.Thisprivilegemustbeusedjudiciouslyasitbypassesallthefine-grainedsecuritycontrols.Thepolicyfunctionshouldbeexecutedwithdefiner’srightsinmajorcasestoavoidanyuncertaintyduetoprivileges.AvoidusingouterjoinsandtheANSIjoinoperationsontheVirtualPrivateDatabaseprotectedtables.Ifyouareusingedition-basedredefinitioninyourapplication,youcanassociateaneditioningviewtoapplytheVirtualPrivateDatabasepoliciesacrossalltheeditions.VirtualPrivateDatabaseworkswithflashbackquery.YoucanquerythebusinessdatatoapasttimeorolderSCNusingthemostrecentsecuritypolicies.Duringadirectpathexportoperation,theOracleVirtualPrivateDatabasepolicies(andOracleLabelSecuritypolicies)arenotenforced.AschemalevelexportoperationfailsiftheschemacontainsaVPDprotectedobject.Inascenariowhereauserhasavalidjustificationtobypasssecuritypolicies,hecanbegrantedEXEMPTACCESSPOLICYprivilege(withoutWITHADMINOPTION)toignoreVPDpolicies.
VirtualPrivateDatabasemetadataOraclecapturesthestaticanddynamicdetailsoftheVPDpoliciesindictionaryviews.YoucanquerythefollowingdictionaryviewstofindthemetadataabouttheVirtualPrivateDatabasesecuritypolicies:
Dictionaryview Comments
[ALL|USER|
DBA]_POLICIES
Theviewcapturesthesecuritypolicyonobjectsaccessibletoauser,ownedbyauser,orwithinadatabase.
[ALL|USER|
DBA]_POLICY_ATTRIBUTES
Theviewcapturestheapplicationcontextnamespaces,theirattributes,andtheirassociationwiththeVirtualPrivateDatabasepolicy.
[ALL|USER|
DBA]_POLICY_CONTEXTSTheviewcapturesinformationaboutthedrivingcontextsfortheobjects.
[ALL|USER|
DBA]_POLICY_GROUPSTheviewcapturesinformationaboutthepolicygroupsontheobjects.
[ALL|USER|
DBA]_SEC_RELEVANT_COLS
Theviewcapturesthespecificationsofthecolumn-levelVirtualPrivateDatabasepolicyontheobjects.
V$VPD_POLICY
Thedynamicviewcapturesinformationaboutthesecuritypolicyassociatedwiththecachedcursors.Inamultitenantenvironment,theviewshowsinformationaboutthecurrentpluggabledatabase.It’sextremelyusefulintroubleshootingpolicyexecution.
ThefollowingquerygivesthepredicateappliedtothequeriesexecutedagainsttheVirtualPrivateDatabaseprotectedtableownedbytheSCOTTuser:
connectsys/oracleassysdba
SELECTobject_name,
policy,
s.sql_text,
predicate
FROMv$vpd_policyvp,v$sqls
WHEREvp.sql_id=s.sql_id
ANDobject_owner='SCOTT'
/
OBJECT_NAMEPOLICYSQL_TEXTPREDICATE
---------------------------------------------------------------
EMPVPD_COLUMNselect*fromscott.empjob=
SYS_CONTEXT('myjob','role')
ForfurtherinformationabouttheVPD_COLUMNpolicy,youcanrefertotheUSER_POLICIESdictionaryview:
connectscott/tiger
SELECTpolicy_name,
policy_type,
static_policy,
function,
pf_owner
FROMUSER_POLICIES
/
POLICY_NAMEPOLICY_TYPESTAFUNCTIONPF_OWNER
----------------------------------------------------
VPD_COLUMNDYNAMICNOFUN_VPDSCOTT
Policyutilities—refreshanddropThepolicyutilityactivitiessuchasrefreshingordroppingcanbedonethroughtheDBMS_RLSpackagesubprograms.Refreshingapolicyinheritsthelatestchangesmadetothepolicyanditsdependents.Apolicyrefreshisrequiredwhentheunderlyingreferencedobjectsofthepolicyundergoanychangethatinvalidatesthedependentobjects.Duringthepolicyrefreshprocess,allthecachedstatementsassociatedwiththepolicyareparsedagain.Apolicythatisalreadydisabledcannotberefreshed.
AVirtualPrivateDatabasepolicycanbedroppedusingtheDROP_POLICYsubprogramoftheDBMS_RLSpackage:
EXECDBMS_RLS.DROP_POLICY('SCOTT','EMP','VPD_COLUMN')
/
OracleDatabase12cSecurityenhancementsOracleDatabase12cintroducedanumberoffeaturesandenhancementstofurtherstrengthenthein-depthsecuritycollateral.Inthissection,youwillunderstandsomeofthekeysecurityenhancementsandfeaturesinOracleDatabase12c.Thefollowingisasummaryofthenewsecurityfeatures:
RealApplicationSecurity(RAS):OracleDatabase12cintroducesadataauthorizationsolutiontoprovideend-to-endsecurityinamultitierapplicationarchitecture.Youcannowdeclareandenforcetheapplication-levelsecuritypoliciesinthedatabasekernel.TheRASsecuritymodelunderstandstheapplication-levelsecuritypolicyconstructs,suchasapplicationusers,privileges,androleswithinthedatabase,andenforcesthesecuritypoliciesinthecontextoftheapplication.Aswellasdataaccess,RAScanhelptheapplicationstosecuretheaccesscontroloperationsofanapplicationuser.OracleDataRedaction:TheDataRedactionfeaturemasksthesensitivedataon-the-flybeforeitisdisplayedtotheuser.Thisfeatureprovidesarichlibraryformaskingthesensitiveinformationwhilethedatainthestorageremainsinanactual,thatis,unmaskedformat.Roleandprivilegeanalysis:Privilegeanalysishelpstoenhanceoperationalsecuritybyidentifyingtheleastsetofprivilegestorunanapplication.Duringapplicationdevelopment,youmayhavegrantedsystemprivilegesSELECTANYTABLEtoauserorobjectprivilegestothePUBLICrole.However,beforemovingittoproduction,youmustverifythesecurityaspectoftheapplicationbyretainingtherequiredprivilegesandrevokingtheunnecessaryones.Youcannowanalyzetheroles,usersorcontexts,sessionsordatabasetodetectusedandunusedprivileges.Aprivilegeisconsideredasunusedifitisnotutilizedforcompilationorrun-timeoperations.
AuserwiththeCAPTURE_ADMINrolecankick-offaprivilegeanalysisoperation.NotethataSYSusercannotbeanalyzedunderprivilegeanalysis.
UnifiedAuditing:OracleDatabase12cintroducesaunifiedaudittrailwhichresolvesthepaintomaintaindifferentstoresofauditinformation.ThenewUNIFIED_AUDIT_TRAILdatadictionaryviewreplacesthepreviousauditingviewsandconsolidatestheauditinformationfromallthesources.ThenewAUDIT_VIEWERandAUDIT_ADMINrolesenabletheseparationofdutyandprovideeasymanagementofauditingwithinthedatabase.Thenewauditingframeworksupportsconditionalauditingtopreventtheauditingofirrelevantoperations.NewadministrativeprivilegessuchasSYSBACKUP,SYSDG,andSYSKM:Thesearethenewprivilegesfordedicatedtaskslikebackup,dataguardoperations,andkeymanagementinordertoreducedependencyonSYSDBAandenabletheseparationofduties.TheREADobjectprivilegeandtheREADANYTABLEsystemprivilege:Youcannow
granttheREADobjectprivilegethatallowsausertoquerytables,views,materializedviews,andsynonyms.ThedifferencebetweentheSELECTandREADobjectprivilegesisthatSELECTallowsausertolockthetabledatausingtheLOCKstatementortheFORUPDATEclause,whileREADisonlyforquerypurpose.TheADMINandDELEGATEoptionsforcode-basedaccesscontrol:YoucannowprotectyourPL/SQLprogramsbygrantingrolestotheprogramunitsandnottotheusers.YoucangranttheroleswiththeADMINorDELEGATEoptiontoaprogramunit.WiththeDELEGATEoption,thegranteeisnotallowedtogranttheroletotheotherprograms.
OracleDatabase12cDataRedactionOracleDatabase12cDataRedactionpreventstheexposureofsensitivedatatothenon-authorizedusers.Thebeautyofthisfeatureliesinthefactthatitenablesdynamicmasking,whichmeansthatthedataisneverchangedonthestorageorcachebutgetsredactedatruntimejustbeforeitisdisplayedtotheuser.Thesecuritypoliciesarecreatedinthedatabaseandareconsistentlyactivetohidesensitiveinformationwheneverrequestedbytheapplications.Inaddition,thisfeaturehasnoimpactontheintegrityconstraintsanddatabaseoperationssuchasthebackup,restore,export,import,grid,andclusteroperations.
NoteTheOracleDatabase12cDataRedactionfeaturehasbeenbackportedtoOracleDatabase11.2.0.4.
AtypicalusecaseofDataRedactionwouldbearead-onlyapplicationthatfetchesthedatafromaproductionwarehouse.Similarly,theredactionpoliciescanbecreatedforacallcenterapplication.Therewillbemanysuchcaseswheredataviewisbasedontheuserauthorization.
DataRedactionexemptionsandmiscellaneousfeaturesDataRedactionisapartoftheAdvancedSecurityoption,whichcanbepurchasedwithOracleDatabaseEnterpriseEdition.ThefollowingarethesalientfeaturesofDataRedaction:
TheSYSandSYSTEMusersarealwaysexemptfromtheredactionpolicies.Thevirtualcolumnscannotberedacted.Theeditioningviewscannotberedacted.UserswiththeEXEMPTREDACTIONPOLICYsystemprivilegeareexemptfromtheredactionpolicies.YoucannotperformtheCTAS(CREATETABLEASSELECT)operationonaredactedtable.AredactionpolicycanbecontrolledusingtheDBMS_REDACTpackage.AusermusthavetheEXECUTEprivilegeonthepackage.
DataRedactionpoliciescanbecreatedfromEnterpriseManagerCloudControl12c.
DataRedactionfunctiontypesDataRedactioncanusethefollowingmethodsofredaction:
Fullredaction:Fullredactionreferstothecompletereplacementofacolumnvalue.Anumbertypevaluewillbereplacedwithzerooradummydatecanreplaceadate.Forexample,15/01/2015(andallthedatevalues)canberedactedas01/01/00.Partialredaction:Partialredactionreferstothemaskingofaportionofacolumnvalue.Forexample,thefirstfewdigitsoftelephonenumbersorsocialsecuritynumbersarereplacedwithX.Themaskingformatshownintheprecedingfiguredepictspartialredaction.Regularexpressions:Youcanuseregularexpressionstomaskthedatabasedonapatternandnotonthebasisofafixedlengthofthecharacters.Forexample,emailaddressesorcreditcardnumberscanbemaskedbasedonthepositionofthespecialcharacter.Randomredaction:Youcandirecttheredactionpolicytogeneratearandomvaluewithamatchingdatatypeforthecolumncarryingthesensitivedata.Noredaction:Thisisusedfortestingpurposesandcanbeusedbeforedeployingthesecuritypoliciesduringproduction.
DemonstrationLet’scontinuethecasestudyfromtheVirtualPrivateDatabasedemonstration.NotethatEMPisaVirtualPrivateDatabaseprotectedtable.WithDataRedaction,theobjectivewillbetomaskthevaluesfromtheSALandCOMMcolumnsoftheEMPtablefortheCLERK,MGR,andSALESusers.
ThefollowingPL/SQLblockcreatesaredactionpolicyontheSALcolumnoftheEMPtable.Astheredactionisfortheaccessfromthreeusers,thatis,SALES,MGR,andCLERK,thepredicateexpressionusingtheSYS_CONTEXTfunctionhasbeenincluded.
CONNECTsys/oracleASSYSDBA
/*GrantexecuteprivilegeonDBMS_REDACTtoscott*/
GRANTEXECUTEONsys.dbms_redactTOSCOTT
/
CONNECTscott/tiger
BEGIN
/*AddapolicytoredactSALcolumn*/
DBMS_REDACT.add_policy(
object_schema=>'SCOTT',
object_name=>'EMP',
column_name=>'SAL',
policy_name=>'redact_employee_info',
function_type=>DBMS_REDACT.full,
expression=>q'|sys_context('userenv','current_user')IN
('SALES','MGR','CLERK')|'
);
END;
/
Let’sverifytheimpactoftheredactionpolicy.TheSALcolumnisfullyredactedbyreplacingtheoriginalcolumnvaluesbyadefaultvalue,zero.NotethattheVirtualPrivateDatabasepolicyisstillactiveandenforced:
CONNmgr/mgr
SELECTempno,ename,job,sal,deptno
FROMscott.emp
/
EMPNOENAMEJOBSALDEPTNO
------------------------------------------------
7566JONESMANAGER020
7698BLAKEMANAGER030
7782CLARKMANAGER010
NoteForafullredactionpolicytype,thedefaultvaluesforthecolumnsarepickedupfromtheREDACTION_VALUES_FOR_TYPE_FULLdictionaryview.
YoucanalteraredactionpolicyusingtheALTER_POLICYprocedurefromtheDBMS_REDACTpackage.TheACTIONattributeisusedtorecordthechangesthatyoumakewhilealteringthepolicy.
Let’saltertheredactionpolicyandmasktheHIREDATEcolumnvalue.Thistime,wewillusethepartialredactiontechniquetomaskthedatevalue.
CONNECTscott/tiger
BEGIN
/*AlterpolicytoincludeHIREDATEcolumn*/
DBMS_REDACT.alter_policy(
object_schema=>'SCOTT',
object_name=>'EMP',
policy_name=>'redact_employee_info',
action=>DBMS_REDACT.add_column,
column_name=>'hiredate',
function_type=>DBMS_REDACT.partial,
function_parameters=>'m1d1y1900'
);
END;
/
Now,let’sconnecttotheSALESuserandcheckthemaskedvaluesoftheHIREDATEcolumn:
CONNsales/sales
SELECTempno,ename,job,sal,hiredate
FROMscott.emp
/
EMPNOENAMEJOBSALHIREDATE
------------------------------------------------
7499ALLENSALESMAN001-JAN-00
7521WARDSALESMAN001-JAN-00
7654MARTINSALESMAN001-JAN-00
7844TURNERSALESMAN001-JAN-00
Let’smaskanothercolumntodemonstratetheredactionusingregularexpression.We’llaltertheEMPtabletoaddtheEMAILcolumn:
CONNECTscott/tiger
ALTERTABLEemp
ADD(emailVARCHAR2(30))
/
UPDATEemp
SETemail=LOWER(ename)||'@xyz.com'
/
COMMIT
/
ThefollowingPL/SQLblockmaskstheEMAILcolumnusingaregularexpression:
BEGIN
/*AlterpolicytoincludeEMAILcolumn*/
DBMS_REDACT.alter_policy(
object_schema=>'SCOTT',
object_name=>'EMP',
policy_name=>'redact_employee_info',
action=>DBMS_REDACT.add_column,
column_name=>'email',
function_type=>dbms_redact.regexp,
regexp_pattern=>dbms_redact.RE_PATTERN_EMAIL_ADDRESS,
regexp_replace_string=>dbms_redact.RE_REDACT_EMAIL_NAME
);
END;
/
TheprecedingpolicyincludestheEMAILcolumnandmasksitusingaregularexpression.Notetheregularexpressionpatternandreplacethestringconstants.TheDBMS_REDACTpackageincludesalistofthestandardsecurityconstructsthatcanbereadilyusedwhilecreatingtheredactionpolicy.Let’sconnecttoCLERKuserandchecktheemailcolumn:
CONNclerk/clerk
SELECTempno,ename,job,sal,hiredate,email
FROMscott.emp
/
EMPNOENAMEJOBSALHIREDATEEMAIL
--------------------------------------------------------
TheDataRedactionmetadataYoucanquerythefollowingdictionaryviewstofindthemetadatainformationabouttheredactionpolicies:
REDACTION_POLICIES:ThisviewstorestheredactionpolicydetailsREDACTION_COLUMNS:Thisviewstoresthedetailsofredactedcolumnsinthedatabase
Thefollowingtwoqueriesdisplaytheredactionpolicydetailsthatwerecreatedintheprecedingdemonstration:
CONNECTsys/oracleASSYSDBA
SELECTpolicy_name,expression
fromREDACTION_POLICIES
/
POLICY_NAMEEXPRESSION
----------------------------------------------------------------
redact_employee_infosys_context('userenv','current_user')IN
('SALES','MGR','CLERK')
SELECTobject_name,column_name,function_type,function_parameters
FROMredaction_columns
/
OBJECT_NAMECOLUMN_NAMEFUNCTION_TYPEFUNCTION_PARAMETERS
--------------------------------------------------------------
EMPHIREDATEPARTIALREDACTIONm1d1y1900
EMPSALFULLREDACTION
EMP EMAILREGEXPREDACTION
SummaryInthischapter,wecoveredthefundamentalsofdatabasesecuritysolutionsfromOracle.AfteranoverviewoftheOracleDatabaseSecuritysolution,wedivedintothefine-grainedaccesscontrolandVirtualPrivateDatabase.TheVirtualPrivateDatabaseenforcesrow-levelsecuritythroughthepoliciesandrestrictsthedataaccessforunauthorizedusers.Dependingonauser’sidentityandrole,theapplicationcansetupmultitenancyandensureuserisolationaswell.
OracleDatabase12cmadeconsiderableenhancementstoitssecurityoffering.Thesummaryoftheseenhancementswasincluded,whiletheDataRedactionfeaturewascoveredindetailalongwithdemonstrations.Inthenextchapter,wewilldiveintoanotherkeyareathathascontinuouslygainedmoreweightwithtime:handlingoflargeobjectsintheOracleDatabase.WewillbefocusingthemajorityofourdiscussionaroundSecureFilesanditsoptimizations.
PracticeexerciseIdentifythecorrectstatementsabouttheworkingofFineGrainedAccessControl.
1. Atablecanhaveonlyonesecuritypolicy.2. DifferentpoliciescanbeusedtoprotecttheSELECT,INSERT,UPDATE,and
DELETEstatementsonatable,butnotone.3. ThepolicyfunctionreturnsthepredicateinformationasWHERE<Column>=
<Value>.4. Onceassociated,theFGACpolicycannotberevokedfromthetable.
AsecuritypolicycanbeassociatedtoagroupofobjectsbytheDBA.Statewhetherthisistrueorfalse.
1. True2. False
ChoosethecorrectstatementaboutDBMS_RLS.
1. DBMS_RLSisusedonlyforrow-levelsecuritypolicies.2. ThepackageisownedbySYS.3. Itcancreate/drop/refreshpoliciesandcreate/droppolicygroups.4. UsingDBMS_RLStosetthepolicydegradestheapplicationperformance.
Identifythecorrectstatementsaboutthecontextofanapplication.
1. AuserwhoholdstheCREATECONTEXTprivilegecancreateacontext.2. ItisownedbytheSYSuser.3. AusercancheckthecontextmetadatainUSER_CONTEXTS.4. Thetrustedpackageassociatedwiththecontextmustexistbeforethecontextis
created.
ArrangethesequenceoftheVirtualPrivateDatabaseimplementationusingapplicationcontexts.
i.Creatingpolicyfunction.
ii.Creatingtrustedpackage.
iii.Creatingandsettingapplicationcontexts.
iv.AssociatingapolicyusingDBMS_RLS.
1. iii,ii,i,iv2. ii,iii,iv,i3. iii,iv,i,ii4. iv,i,ii,iii
Allthepoliciesondifferentcolumnsofthesametablearecollectivelyknownaspolicygroups.
1. True2. False
Identifythecorrectstatementsaboutthepolicytypes.
1. Sharedstaticpolicyisanextensiontothestaticpolicieswheremultiplestaticpoliciescanbesharedamongmultipleusers.
2. Sharedstaticpolicyisanextensiontothestaticpolicieswhereasinglestaticpolicycanbesharedamongmultipleobjects.
3. STATICisthedefaultpolicytype.4. DYNAMICisthedefaultpolicytype.
Pickthecorrectstatementabouttheapplicationcontexts.
1. OnlyaDBAcancreateacustomapplicationcontextandaddattributesunderit.2. TheDBAcanmodifyallUSERENVattributes.3. Thepackageusedforthecontextcreationmayormaynotexistintheschema.4. Globalcontextscanbeusedbyalltheusersonaserver.
ApolicyoftheCONTEXT_SENSITIVEtypeexecutesthepolicyfunctiononce,everytimethequeryisreparsed,ifthelocalcontexthasbeenchanged.
1. True2. False
Identifythecauseofthefollowingexception:
SQL>SELECT*FROMemployees;
select*fromemployees
*
ERRORatline1:
ORA-28110:policyfunctionorpackageORADEV.F_JOB_POLICYhaserror
1. ThepolicyfunctionF_JOB_POLICYdoesnotexist.2. ThepolicyfunctionF_JOB_POLICYhasnotbeenspecifiedin
DBMS_RLS.ADD_POLICYtoaddthepolicyontheemployeestable.3. Thepredicatereturnedbythepolicyfunctionisnotappropriateforthisquery.4. TheVirtualPrivateDatabasepolicyontheemployeestableisinvalidandhas
errors.
Chapter7.OracleSecureFilesThefactthatdataisgrowingmultifoldsatatremendousspeedhasledtotheevolutionofanumberofdatamanagementtrendsandBigDataisoneofthem.Alargeamountofinformationfromwebcontent,sensors,documents,images,andlocationserviceshaspushedorganizationstoplaceseriousthoughttodatamanagementstrategiesanddistiloutnuggetsofinformation.Thedatacanbestructured,semi-structured,orunstructured.
Inrelationaldatabaseterminology,unstructureddatasuchasbinaryfilesordocumentsareclassifiedaslargeobjects.Oraclehasbeenallowinguserstostorelargeobjectsinthetablesofarelationaldatabaseforalongtime.WhilethelargeobjectsareprototypedasBLOBorCLOBinatable,thereisaprovisiontostoreXMLdocuments,spatialdataandtextusingdedicateddatatypes.Inthischapter,wewillfocusonlargeobjecthandlingintheOracleDatabase.YouwillunderstandhowlargeobjectsorLOBsarestoredinthedatabase,whattheoptimizationfeaturesare,andhowithasevolvedovertime.TheOracleDatabase11gintroducedanewformatoftheLOBstorageknownasSecureFiles.SecureFilesofferoptimizedstorageandenableabetterperformanceofthelargeobjectsinanOracledatabase.
Thechapterisoutlinedasfollows:
IntroductiontoLargeObjectsClassificationofLargeObjectsWorkingwithLOBdatatypes
CreatingLOBdatatypesManagingLOBdatatypesMigratingLONGtoLOB
OracleSecureFiles
AnoverviewWorkingwithSecurefilesMigratingBasicFilestoSecureFiles
OracleDatabase12cSecureFilesenhancements
IntroductiontoLargeObjectsAsthenamesuggests,largeobjectsorLOBsrefertolargedata.Acolumnofalargeobjecttypeinatablecanstoresemi-structuredorunstructureddata.Semi-structureddatacanbeacharacter-baseddocumentthatcanbeprocessedinanearrelationalformat.Unstructureddataisabinaryfilethatisdifficulttointerpretlogically.Forexample,anXMLfileisasemi-structureddocumentwhileanimageoragraphicsfileisanunstructuredformatofthedata.
OracleDatabasesupportsthestorageoflargeobjectsalongthefollowingaspects:
Storage:Justlikeanyotherdata,theOracleDatabaseallowsthestorageoflargeobjectsincolumnswithinatable.ThecolumnsofLOBdatatypescanefficientlystoreasemiorunstructureddataobject,compressitandevenencryptitinthedatabase.TheLOBdatatypestoredintheOracleDatabaseabidesbytheACID(Atomicity,Consistency,Isolation,andDurability)properties.Oracleprovidesawiderangeofadministrativecontrolstomanageandmaintainlargeobjectsinthedatabase.Access:OracleSecureFiles(discussedlaterinthischapter)providesyouwithhighlyoptimizedaccessoflargeobjectsfromtheOracleDatabase.SecureFiles,introducedinOracleDatabase11gandthedefaultLOBstorageoptioninOracleDatabase12c,acceleratesLOBperformancethroughvectoroptimizationtechniques.Forsemi-structureddatatypessuchasOracleTextorOracleSpatial,Oracleenablesindexingtechniquestoimprovequeryperformance.Security:TheLOBdatatypeintheOracleDatabasestaysprotectedandsecure.Fine-graineddataaccesssecuritypoliciesapplytolargeobjectsaswell.
TheuseoftheLONGandLONGRAWdatatypeswassucceededbytheLOBdatatypesinOracle8i.AlthoughLONGandLONGRAWarestillsupported,OraclerecommendstheusageoftheLOBdatatypesinplaceofLONGandLONGRAWduetothefollowingreasons:
AtablecanhaveonlyoneLONGorLONGRAWcolumnALONGorLONGRAWcolumncanstoredataonlyupto2GBTheLONGdatacanonlybeaccessedsequentially
ItisrecommendedforlegacyapplicationsusingLONGorLONGRAW,tomigratetoLOBssoastoleveragethebenefitsofstorageoptimizationandenhancedperformance.
ClassificationofLargeObjectdatatypesALOBdatatypecanbeclassifiedonthebasisofitsstorageproperties.ThefollowingfigurebranchesoutthedifferentLOBtypesinOracle:
InternalLOBAninternalLOBcanbestoredinandaccessedfromthedatabase.AcolumnofBLOB,CLOB,orNCLOBcanbeincludedinatabletostorelargeobjects,likeallothercolumns.NotethattheinternalLOBdatatypescanbeusedinPL/SQLaswell.
PersistentandTemporaryLOB
ALOBdatatypeispersistentifitisphysicallystoredinthedatabasetables.Aswithallothercolumnvalues,itcanbeapartofadatabasetransaction.
AtemporaryLOBisusedtoinstantiateaLOBinaPL/SQLprogram.ItisusedtoperformtheLOBoperations,whicharecarriedoutinatemporarytablespace.IfthetemporaryLOBvalueisinsertedintoadatabasetable,theLOBinstancebecomespersistent.
ExternalLOBIftheLOBdatadoesnotresideinsidetheOracleDatabase,itisanExternalLOB.AcolumnofanexternalLOBdatatype,BFILE,storesonlytheLOBlocatorandnotthedata.Thedataresidesoutsidethedatabasestorageasanoperatingsystemfileontheserverhost.TheintegrityanddurabilityofexternalLOBsmustbelayeredattheoperatingsystemlevel.
NoteBFILEisaread-onlydatatypeanddoesnotparticipateindatabasetransactions.
LOBrestrictionsALOBisaspecialfeaturethatallowsadatabasemanagementsystemtostoreunstructureddatasuchasfilesanddocuments.However,therearecertainrestrictionsontheusageofaLOBanditsrelatedoperations,listedasfollows:
ALOBcolumncannotbeaprimarykeyofatableALOBcolumncannotbeusedintheORDERBYclauseofSELECTqueryALOBcolumncannotappearintheGROUPBYclauseofaSELECTqueryALOBcolumncannotbeusedtojointwotablesYoucannotusetheDISTINCTclausewithaLOBcolumninaSELECTqueryALOBcolumncannotbeselectedinaUNIONqueryAB-TreeindexorabitmapindexcannotbecreatedonaLOBcolumn
LOBdatatypesinOracleOracleprovidesfourdatatypesdedicatedfordeclaringlargeobjects,namely:BLOB,CLOB,NCLOB,andBFILE.
BLOBandCLOBTherearethreetypesofinternalLOBdatatypes,namely:
BLOB:TheBinaryLargeObjectdatatypeisusedtostorelargebinaryfilesthatcannotbelogicallybrokendowntodatabitssuchasPDFs,images,audiosorvideos,andsoon.CLOB:TheCharacterLargeObjectdatatypestoresthesingle-bytecharacterdatainthedatabasecharactersetformat.Itsupportsfixed-widthcharacterformats.NCLOB:TheCLOBdatatypethatcanstorenationalcharactersetdataandsupportvaryingwidthformatcharactersets.
NoteStartingfromOracle10g,OraclecancasttheCLOBdatatotheVARCHAR2dataimplicitly.
BFILEABFILEisanSQLdatatypefortheexternalLOBdatatype.Itistheread-onlydatatypethatstoresalocatorforabinaryfilewhosephysicallocationisoutsidetheOracleDatabase.DeletingaBFILEcolumnvalue(orsettingittoNULL)willdropthereferencepointertotheexternalfilebutwillnotdeletethefile.
TipThesecurityandintegrityoftheexternallylocatedfilemustbemanagedandadvisedattheoperatingsystemlevel.Oraclerecommendstheusageofdatabasedirectoriesinordertosecuretheuseractionstothefilelocation.Asession-levelinitializationparameterSESSION_MAX_OPEN_FILESdeterminesthemaximumnumberofBFILEsthatcanbeopenedinasession.Thedefaultparametervalueis10butthiscanbemodifiedusingtheALTERSESSIONcommand.Ifyouwanttoclosealltheopenfiles,youcandosobycallingDBMS_LOB.FILECLOSEALL.
SomemorerelatedstuffWhileworkingwiththeLOBdatatypes,youmustbefamiliarwithafewmoretermssuchastheLOBinstance,LOBinitialization,andtheDBMS_LOBpackage.AthoroughunderstandingisessentialtoperformtheLOBoperations.
TheLOBlocatorStructurally,aLOBinstanceismadeupofaLOBlocatorandvalue.TheLOBlocatorstoresthepointertotheLOBvaluewhiletheLOBvaluestorestheactualphysicaldata.
BeitaninternalorexternalLOB,thecolumninthetableholdsjustthelocator.InthecaseofBLOB,CLOB,andNCLOB,theLOBlocatorisusedtoretrievethevaluefromtheLOBinstance.ForBFILE,thelocatorisusedtoretrievetheexternallylocatedoperatingsystemfile.
LOBinstanceinitializationThestateofaLOBcolumncanbeNULL,empty,orpopulated.ALOBinstancewithoutalocatorisaNULLLOBandcannotbepassedasanargumenttoaprogram.ToallowaLOBtobepassedasaparametertoaprogram,itmustbeinitialized.YoucaninitializeaLOBinstanceofapersistentLOBcolumnusingtheOracle-suppliedconstructorfunctions,EMPTY_BLOB()andEMPTY_CLOB()forBLOBandCLOBrespectively.ThefunctionsinitializetheLOBsbutdonotpopulatethemwithanydata.Thesefunctionscanbeusedinthefollowingscenarios:
TheLOBcolumndefaultcanbesettooneoftheconstructorfunctionsinaCREATETABLEstatement:
CREATETABLEt_LOB_init
(idNUMBER,
b_LOBBLOBDEFAULTEMPTY_BLOB(),
c_LOBCLOBDEFAULTEMPTY_CLOB()
)
/
Similarly,thecolumndefaultcanbesetwhileaddingacolumnusingtheALTERTABLEcommand.
AnemptyLOBinstancecanbeinsertedintotheLOBcolumninanINSERTstatement.Forexample,thefollowingINSERTstatementusestheEMPTY_BLOB()functionortheemptylocatorinsteadofaprofileimage:
/*Inserttestdataintheabovetable*/
INSERTINTOt_LOB_init(ID,B_LOB,C_LOB)
VALUES
(129,EMPTY_BLOB(),EMPTY_CLOB())
/
TheLOBvariablesinaPL/SQLblockcanbeinitializedeitherinthedeclarativesectionorprogrambody:
/*StartthePL/SQLblock*/
DECLARE
/*DeclarelocalLOBvariables*/
l_my_cLOBCLOB:=EMPTY_CLOB();
l_my_bLOBBLOB:=EMPTY_BLOB();
BEGIN
...
--executablesection
...
END;
/
PL/SQLproceduresuccessfullycompleted.
YoucaninitializeaBFILEcolumnusingtheBFILENAMEfunction.TheBFILENAMEfunctionacceptsthedatabasedirectoryandfileasinputsandreturnsaBFILElocator.ABFILElocatorisareferencetothefilelocatedexternallyintheoperatingsystem.ThesyntaxoftheBFILENAMEfunctionisasfollows:
FUNCTIONBFILENAME(directoryINVARCHAR2,filenameINVARCHAR2)
RETURNBFILE;
TheBFILENAMEfunctionisalsousedwhilepopulatingaLOBinstancefromanexternalfileinaPL/SQLblock.
TheDBMS_LOBpackageOracleprovidesabuilt-inpackage,DBMS_LOB,thatallowsuserstoperformtransactionaloperationsontheinternalLOBsandreadoperationsforBFILEs.ThepackageisownedbySYS.AuserwiththeEXECUTEprivilegeontheDBMS_LOBpackagecaninvokeitssubprograms.
NoteForthefollowingsubsections,refertotheOracleDatabaseOnlineDocumentation12cRelease1(12.1)/DatabaseAdministrationathttps://docs.oracle.com/database/121/ARPLS/d_LOB.htm.
TheDBMS_LOBconstants
TheDBMS_LOBpackageconstantshavebeenconsolidatedinthefollowingtable:
Constant Description Value
TheDBMS_LOBconstants
FILE_READONLY OpenBFILEinread-only 0
LOB_READONLY Read-onlyLOB 0
LOB_READWRITE ReadwriteLOB 1
LOBMAXSIZE MaximumsizeofLOB 18446744073709551615
SESSION CreatetemporaryLOBforthedurationofasession 10
CALL CreatetemporaryLOBforthedurationofatransaction 12
TheDBMS_LOBoptiontypes
OPT_COMPRESS SecureFilecompressionoption 1
OPT_ENCRYPT SecureFileencryptionoption 2
OPT_DEDUPLICATE SecureFilededuplicateoption 4
TheDBMS_LOBoptionvalues
COMPRESS_OFF SecureFilecompressionOFF 0
COMPRESS_ON SecureFilecompressionON 1
ENCRYPT_OFF SecureFileencryptionOFF 0
ENCRYPT_ON SecureFileencryptionON 2
DEDUPLICATE_OFF SecureFilededuplicationOFF 0
DEDUPLICATE_ON SecureFilededuplicationON 4
TheDBFSstatevaluetypes
DBFS_LINK_NEVER Non-archivedLOB 0
DBFS_LINK_NO LOBarchivedbutreadbythedatabase 2
DBFS_LINK_YES LOBarchived 1
TheDBFSCacheFlags
DBFS_LINK_CACHE ArchiveandcachetheLOBdata 1
DBFS_LINK_NOCACHE ArchivetheLOBdatawithoutcachingitinthedatabase 0
TheDBMS_LOBdatatypes
TheDBMS_LOBpackageworkswiththefollowingdatatypes:
Datatype Description
BLOB SourceordestinationbinaryLOB
RAW SourceordestinationRAWbuffer(usedwithBLOB)
CLOB SourceordestinationcharacterLOB(includingNCLOB)
VARCHAR2 Sourceordestinationcharacterbuffer(usedwithCLOBandNCLOB)
INTEGER SpecifiesthesizeofabufferofaLOB
BFILE Large,binaryobjectstoredoutsidethedatabase
TheDBMS_LOBsubprograms
TheDBMS_LOBsubprogramsarelistedinthefollowingtable:
Subprogram Type Description
APPEND Procedure AppendsthecontentsoftheLOBsourcetotheLOBdestination
CLOSE Procedure ClosesapreviouslyopenedinternalorexternalLOB
COMPARE Function ComparestwoentireLOBsorpartsoftwoLOBs
CONVERTTOBLOB ProcedureReadsthecharacterdatafromasourceCLOBorNCLOBinstance,convertsthecharacterdatatothespecifiedcharacter,writestheconverteddatatoadestinationBLOBinstanceinbinaryformat,andreturnsthenewoffsets
CONVERTTOCLOB ProcedureTakesasourceBLOBinstance,convertsthebinarydatainthesourceinstancetothecharacterdatausingthespecifiedcharacter,writesthecharacterdatatoadestinationCLOBorNCLOBinstance,andreturnsthenewoffsets
COPY Procedure Copiesall,orapart,oftheLOBsourcetotheLOBdestination
CREATETEMPORARY Procedure CreatesatemporaryBLOBorCLOBanditscorrespondingindexintheuser’sdefaulttemporarytablespace
ERASE Procedure Erasestheentire,orapart,ofaLOB
FILECLOSE Procedure Closesthefile
FILECLOSEALL Procedure Closesallpreviouslyopenedfiles
FILEEXISTS Function Checksifthefileexistsontheserver
FILEGETNAME Procedure Getsthedirectoryobjectnameandfilename
FILEISOPEN Function ChecksifthefilewasopenedusingtheinputBFILElocators
FILEOPEN Procedure OpensaBFILE
FRAGMENT_DELETE Procedure DeletesthedataatthegivenoffsetforthegivenlengthfromtheLOB
FRAGMENT_INSERT Procedure Insertsthegivendata(limitedto32KB)intotheLOBatthegivenoffset
FRAGMENT_MOVE Procedure Movesachunkofbytes(BLOB)orcharacters(CLOB/NCLOB)fromthegivenoffsettothenewoffsetspecified
FRAGMENT_REPLACE Procedure Replacesthedataatthegivenoffsetwiththegivendata(nottoexceed32KB)
FREETEMPORARY Procedure FreesthetemporaryBLOBorCLOBinthedefaulttemporarytablespace
GETCHUNKSIZE Function ReturnstheamountofspaceusedinLOBCHUNKtostoretheLOBvalue
GETLENGTH Function GetsthelengthoftheLOBvalue
GETOPTIONS Function Obtainssettingscorrespondingtotheoption_typesfieldforaparticularLOB
GET_STORAGE_LIMIT Function ReturnsthestoragelimitforLOBsinyourdatabaseconfiguration
INSTR Function ReturnsthematchingpositionofthenthoccurrenceofthepatternintheLOB
ISOPEN Function CheckstoseeiftheLOBwasalreadyopenedusingtheinputlocator
ISTEMPORARY Function ChecksifthelocatorispointingtoatemporaryLOB
LOADBLOBFROMFILE Procedure LoadstheBFILEdataintoaninternalBLOB
LOADCLOBFROMFILE Procedure LoadstheBFILEdataintoaninternalCLOB
LOADFROMFILE Procedure LoadstheBFILEdataintoaninternalLOB
OPEN Procedure OpensaLOB(internal,external,ortemporary)intheindicatedmode
READ Procedure ReadsthedatafromtheLOBstartingatthespecifiedoffset
SETOPTIONS Procedure EnablesCSCEfeaturesonaper-LOBbasis,overridingthedefaultLOBcolumnsettings
SUBSTR Function ReturnspartoftheLOBvaluestartingatthespecifiedoffset
TRIM Procedure TrimstheLOBvaluetothespecifiedshortlength
WRITE Procedure WritesthedatatoaLOBfromagivenoffset
WRITEAPPEND Procedure WritesabufferattheendofaLOB
LOBusagenotesAsadatabaseadministrator,youwillfindthefollowingnotesusefulwhileworkingwithLOBsinadatabaseapplication:
ObjecttypescanhavetheLOBtypeattributes.YoucanchangethetablespaceofaLOBsegmentbyusingtheALTERTABLE…MODIFYcommand.LOBsarestoredinlinealongwiththetablerowiftheLOBsizeislessthanorequalto4000bytes.YoucanspecifyENABLE|DISABLESTORAGEINROWintheLOBstorageclauseforinlineandout-of-linestorage.However,theLOBlocatorsarealwaysstoredintheLOBcolumnofthetable.NoLOBstoragespecificationsareapplicabletotheBFILEcolumns.
OracleSecureFilesOracleSecureFileswereintroducedinOracleDatabase11gRelease2toenableoptimizedstorageoflargeobjectsandenhancedperformance.SecureFilesarere-engineeredLOBstoragearchitecturethatisdesignedtoleveragethejointcapabilitiesofanOracleDatabaseandafilesystem.OracleSecureFilesgreatlybenefittedfromthefilesystem-likefeaturessuchasdeduplication,compression,andencryption.Inaddition,theSecureFilesdataworkswithtrusteddatabasefeaturessuchasflashback,fine-grainedauditing,RealApplicationClusters,AutomaticStorageManagement,andInformationLifecycleManagement.TheoptimizationfeaturesinSecureFilesarededuplication,compression,andencryption.
WiththeintroductionofOracleSecurefiles,theolderLOB,thatis,allLOBsuntilOracleDatabase11gRelease1,willbeknownasBasicFiles.
DeduplicationandcompressionLetusfirstunderstandwhatoptimizestheSecureFilesstorageonthedisk.OracleSecureFilesgivesthebestperformanceduringthewriteoperationsduetothebulkallocationofcontiguousblocksonthedisk.TheSecureFilesegmentsmustresideonanAutomaticSegmentSpaceManagement(ASSM)managedtablespace.
Inaddition,advancedfeaturessuchasdeduplicationandcompressioncontributelargelytotheLOBstorageoptimizationbyreducingtheoverallsizeofdatagettingwrittentothestorage.TheOracleDatabasemaintainsaninternalindexofprefixhashandfullhashforalltheobjects.Duringthewriteoperations,theprefixhashisgeneratedfortheobject,whichisthenmatchedagainsttheprefixhashesavailableintheinternalindex.Iftheprefixhashisnotmatched,theobjectiswrittentothedisk,otherwisetheobjecthashcomparisonisperformed.Amismatchduringfullhashcomparisonwillagainresultinanobjectwrite.Iftheobjecthashesarematched,thenapointer(memoryvector)tothemasterhashiswrittentotheLOBcolumnforthecurrentwriteoperation.Thus,forduplicateobjects,theOracleDatabasestoresasinglemastercopy.YoucanuseDEDUPLICATEorKEEP_DUPLICATEStoenableordisablethededuplicatefeature.
Withregularchecksonthesizeandaccess,theOracleDatabasecancompresstheSecureFiles,whichmaximizestheirspaceutilization.YoucanspecifythecompressionlevelasCOMPRESSLOW,COMPRESSMEDIUM(default)orCOMPRESSHIGHdependingontheSecureFileaccessrateandavailableCPUcycles.Tocompletelydisablethecompression,specifyNOCOMPRESSintheSecureFileLOBstoragespecification.NotethattheLOBcompressionisdifferentfromthetablecompression.
ThededuplicationandcompressionfeaturestransparentlyaccountfortheenhancedperformanceofSecureFiles.Thededuplicationandcompressionfeaturescanbespecifiedatthetableaswellasthepartitionlevel.
EncryptionASecureFileLOBcolumncanbesafelyandtransparentlyencryptedordecryptedusingtheTransparentDataEncryption(TDE)featureofOracle.YoucanusetheENCRYPTorDECRYPTclausetoenableordisabletheencryptionfeature.
IfyouenableallthreeadvancedfeaturesforaSecureFile,theOracleDatabasewillfirstdeduplicate,thencompress,andfinallyencryptit.
OracleSecureFilecompressionanddeduplicationarepartoftheOracleAdvancedCompressionoptionOracleSecureFileencryptionispartoftheOracleAdvancedSecurityoption
FileSystemLoggingYoucanalsoenableafilesystem-likeloggingforOracleSecureFilestoreduceredogenerationwhileloadingtheLOBdataintoatable.Typically,OracleDatabaselogsthedatachangesaswellasmetadatachangesintheredologs.Ontheotherhand,atypicalfilesystemsimplytracksthemetadatachanges.TheOracleSecureFilelogginglevelcanbesettoFILESYSTEM_LIKE_LOGGINGinordertoenabletheloggingofonlytheLOBmetadata.InthecaseoflargesizeSecureFiles,thefilesystem-likeloggingcutsshorttheredogenerationbyahugemarginandimprovesthedataloadingperformance.ThedefaultloggingmodeforSecureFilesisNOCACHELOGGING.
WriteGatherCacheWriteGatherCache(WGC)isachunkofmemoryallocatedwithinthebuffercacheforstaginglargeLOBwriteoperations.Themaximumsizeofthecachecanbe4MegaBytes(MB).WhenmultipleconcurrentserverprocessesattempttowritetheLOBdatatothestoragelayer,theWGCfacilitatesthebufferingoflargewriteI/Os,whichhelpsintheallocationoflargeadjacentspaceallocation.ItisrecommendedtoavoidfrequentCOMMIToperationsastheywillflushthiscache.TheSecureFilededuplicationcheckisperformedwhilethedataisinWriteGatherCache.TheusageofWriteGatherCachegreatlyimprovesthewriteperformanceoftheSecureFiles.
FreespacemanagementThefreespacemanagementkeepstrackoftheallocationanddeallocationoftheSecureFileLOBsintheLOBsegments.AbackgroundfreespacemonitorkeepsacheckonthecurrentspaceusageoftheSecureFileLOBsintheLOBsegments.Itisthebackgroundfreespacemonitorthatdeterminestheallocationofextents.
Whilewritinginasegment,thefixedCHUNKparametervaluecanleadtothefragmentationofthelargeobjectdata.TheOracleSecureFilesusealargeranddynamicchunksizeinordertosupportthelargeallocationofcontiguousblocksondiskandavoidfragmentation.ThisfeaturegreatlyimprovesthewriteperformanceofSecureFiles.
OracleSecureFilesrequirenoindexessuchasb-tree.Inconcurrentenvironments,indexmaintenanceonthelargeobjectscanbeacostlyoperation.SecureFilesuseprivatemetadatablocksthatarecontiguouslylocatedintheLOBsegment.
UnlikeolderLOBs,SecureFilesdonotsufferfromhighwatermarkcontentionissuesbecausethefreedspaceisdeallocatedandreclaimedsimultaneously.
OracleSecureFilesallowaLOBtobeprefetchedfromtheOracleDatabasetoimprovereadperformance.TheprefetchintelligencecomesfromtheSecureFilesaccesspatternsthatincreasethroughputbyasignificantmargin.
BasicFilesandSecureFilesStartingfromOracleDatabase11g,aLOBdatacanbestoredeitherasaBasicFileorSecureFile.OraclerecommendsthatyouusetheSecureFileapproachforstoringlargeobjectsinthedatabasebecauseitoptimizesthestoragemechanismandboostsboththereadandwriteperformance.IfyourapplicationusesanASSMmanagedtablespace,youmustcreateaLOBasaSecureFile.
UntilOracle11g,thedefaultstoragetypewasBasicFile.However,withOracleDatabase12c,SecureFileisthedefaultstoragemechanism.Theapplicationsworkingwithanolderversionofthelargeobjects,thatis,BasicFilesareadvisedtomigratetoSecureFilesusingtheonlineredefinitionapproach.
Thedb_securefileparameterOracleDatabase11gintroducedanewinitializationparameterdb_securefiletocontrolthebehaviorofLOBstorageinthedatabase.UntilOracle11g,thedefaultvalueoftheparameterwasPERMITTED.StartingfromOracleDatabase12c,thedefaultvalueofthedb_securefileparameterisPREFERRED.TheparametercanbesetusingtheALTERSYSTEMorALTERSESSIONstatement.Theparametervaluesarebrieflydescribedasfollows:
PREFERRED:ThisisthedefaultparametervalueinOracleDatabase12corCOMPATIBLEsetto12.0.0.0andhigher.PERMITTED:ItallowsthecreationofLOBsasSecureFiles,iftheLOBstorageisspecifiedasSECUREFILE.ALWAYS:AlltheLOBsegmentsontheASSMmanagedtablespacesarecreatedasSecureFiles.NotethatLOBsonanon-ASSMtablespacewillstillbeBasicFiles.FORCE:AlltheLOBcolumnsonanASSMtablespacewillbeforciblycreatedasSecureFiles.Inaddition,noLOBcanbecreatedonanon-ASSMtablespace.NEVER:ItrestrictsthecreationofSecureFiles.IGNORE:ItignoresthecreationofSecureFiles.AlltheLOBcolumnsarecreatedasBasicFiles.
WorkingwithLOBsNowthatweknowthebenefitsofOracleSecureFiles,let’sillustratehowtoworkwiththeLOBdataintheOracleDatabase.Inourcasestudy,youwillseethecomparisonbetweenBasicFilesandSecureFiles.
Let’sfirstverifythesettingofthedb_securefileinitializationparameter:
connsys/oracleasSYSDBA
showparameterdb_securefile
NAMETYPEVALUE
----------------------------------
db_securefilstringPREFERRED
WewillusethedefaultsettingoftheparameterbecauseitallowsthecreationofaSecureFileontheASSMtablespaceandthebehaviorcanbeoverriddenbyexplicitlyspecifyingBasicFile.
Fortestingpurposes,let’screatetwotablespaceswithdifferentsegmentspacemanagement.TheTBS_BASICtablespaceisamanuallymanagedtablespacewhileTBS_SECUREisanASSMtablespace:
connsys/oracleasSYSDBA
/*Createamanuallymanagedtablespace*/
CREATETABLESPACEtbs_basic
DATAFILE'/u01/app/oracle/oradata/orcl/tbs_basic.dbf'
SIZE200M
SEGMENTSPACEMANAGEMENTMANUAL
/
Tablespacecreated.
/*CreateatablespacewithASSM*/
CREATETABLESPACEtbs_secure
DATAFILE'/u01/app/oracle/oradata/orcl/tbs_secure.dbf'
SIZE200M
SEGMENTSPACEMANAGEMENTAUTO
/
Tablespacecreated.
/*Verifythesegmentspacemanagementoftablespaces*/
SELECTtablespace_name,segment_space_management
FROMdba_tablespaces
WHEREtablespace_namelike'TBS%'
/
TABLESPACE_NAMESEGMEN
---------------------------------
TBS_BASICMANUAL
TBS_SECUREAUTO
ThefollowingCREATETABLEscriptscreatetwotables:EMP_BASICandEMP_SECURE.BoththetablesincludeaBLOBcolumn:MISC_DOCS.IntheEMP_BASICtable,theMISC_DOCScolumnisstoredasaBasicFilewhileintheEMP_SECUREtable,thecolumnisstoredasaSecureFile.NotetheBASICFILEandSECUREFILEkeywordspecificationtodifferentiatethetwostorageapproaches.TheLOBsegmentswillbecreatedontheprecedingtablespacesaswell:
connscott/tiger
/*CreateatableEMP_BASIC*/
CREATETABLEemp_basic
(empno,ename,deptno,job,sal,misc_docs)
LOB(misc_docs)
STOREASBASICFILE
(tablespaceTBS_BASIC)
AS
SELECTempno,ename,deptno,job,sal,empty_bLOB()
FROMemp
/
/*CreateatableEMP_SECURE*/
CREATETABLEemp_secure
(empno,ename,deptno,job,sal,misc_docs)
LOB(misc_docs)
STOREASSECUREFILE
(tablespaceTBS_SECURE)
AS
SELECTempno,ename,deptno,job,sal,empty_bLOB()
FROMemp
/
LOBmetadataTheUSER_LOBSdictionaryviewincludesaSECUREFILEcolumntoidentifyacolumnasSecureFileorBasicFileinatable.ForeachLOBtypecolumninatable,OraclecreatesaLOBsegmentseparatelyfromthetablesegment.Implicitly,OraclealsocreatesaninternalindexstructurefortheLOBcolumnonthesametablespacespecifiedforLOB.NotethattheLOBindexstructuredoesnotneedtoberebuiltormaintained.
ThefollowingSQLstatementqueriestheUSER_LOBSdictionaryviewandliststheLOBsegment,tablespace,in-rowattribute,andSecureFilecharacteristicoftheLOBcolumns:
connscott/tiger
/*QueryUSER_LOBSforLOBmetadata*/
WITHCAS
(
SELECTtable_name,
column_name,
segment_name,
tablespace_name,
in_row,
securefile
FROMuser_LOBs
WHEREtable_namein('EMP_BASIC','EMP_SECURE')
)
SELECT*FROMc
UNPIVOT
(column_valueFORcolumn_nameIN
(table_name,column_name,segment_name,tablespace_name,in_row,securefile))
/
COLUMN_NAMECOLUMN_VALUE
--------------------------------------------------
TABLE_NAMEEMP_BASIC
COLUMN_NAMEMISC_DOCS
SEGMENT_NAMESYS_LOB0000093890C00007$$
TABLESPACE_NAMETBS_BASIC
IN_ROWYES
SECUREFILENO
TABLE_NAMEEMP_SECURE
COLUMN_NAMEMISC_DOCS
SEGMENT_NAMESYS_LOB0000093893C00007$$
TABLESPACE_NAMETBS_SECURE
IN_ROWYES
SECUREFILEYES
ThefollowingqueryshowsthesegmentspaceallocationandinitialextentsandblocksallocatedforBasicFileLOBandSecureFileLOB:
/*QueryUSER_SEGMENTStoqueryinitialbytesforLOB*/
WITHCAS
(
SELECTtable_name,
column_name,
l.segment_name,
s.segment_type,
s.segment_subtype,
to_char(s.bytes/1024)asbytes
FROMuser_LOBsl,user_segmentss
WHEREl.segment_name=s.segment_name
ANDl.table_namein('EMP_BASIC','EMP_SECURE')
)
SELECT*FROMC
UNPIVOT
(column_valueFORcolumn_nameIN
(table_name,column_name,segment_name,segment_type,segment_subtype,bytes))
/
COLUMN_NAMECOLUMN_VALUE
-----------------------------------------------------------
TABLE_NAMEEMP_BASIC
COLUMN_NAMEMISC_DOCS
SEGMENT_NAMESYS_LOB0000093890C00007$$
SEGMENT_TYPELOBSEGMENT
SEGMENT_SUBTYPEMSSM
BYTES64
TABLE_NAMEEMP_SECURE
COLUMN_NAMEMISC_DOCS
SEGMENT_NAMESYS_LOB0000093893C00007$$
SEGMENT_TYPELOBSEGMENT
SEGMENT_SUBTYPESECUREFILE
BYTES128
TheprecedingqueryoutputshowsthataSecureFileneedsaminimumof16blocks(thatis,128/8)inthefirstextent.Atthesametime,BasicFilerequiresaminimumof3blocksintheinitialextent.However,thequeryresultshowstheallocationof8extentsfortheEMP_BASIC.MIS_DOCScolumns.
TemporaryLOBmetadatacanbequeriedfromtheV$TEMPORARY_LOBSdictionaryview.
EnablingtheadvancedfeaturesofaSecureFileLet’scheckwhethertheadvancedfeatures,thatis,compression,deduplication,andencryptionforaSecureFileLOBareenabledornot:
/*QueryUSER_LOBStoviewadvancedfeaturesofSecureFile*/
SELECTcolumn_name,
encrypt,
compression,
deduplication
FROMuser_LOBs
WHEREtable_name='EMP_SECURE'
/
COLUMN_NAMENCRCOMPREDEDUPLICATION
-----------------------------------
MISC_DOCSNONONO
Theoutputfromtheprecedingqueryshowsthatcompression,deduplication,andencryptionisnotyetswitchedonfortheMISC_DOCScolumnintheEMP_SECUREtable.YoucanusetheALTERTABLEcommandtoenablecompressionanddeduplicationfortheSecureFileLOBcolumn:
/*ModifytheMISC_DOCStoenablecompressionanddeduplication*/
ALTERTABLEemp_secure
MODIFYLOB(misc_docs)
(
COMPRESSHIGH
DEDUPLICATE
)
/
Tablealtered.
Let’sverifythechangesfromtheUSER_LOBStable:
/*QueryUSER_LOBStoviewadvancedfeaturesofSecureFile*/
SELECTcolumn_name,
encrypt,
compression,
deduplication
FROMuser_LOBs
WHEREtable_name='EMP_SECURE'
/
COLUMN_NAMENCRCOMPREDEDUPLICATION
-----------------------------------
MISC_DOCSNOHIGHLOB
YoucanalsoenabletheLOBencryptionfortheMISC_DOCStableusingtheALTERTABLEcommand.ASecureFilesupportsthefollowingencryptionalgorithms:
3DES168:Thisisthetripledataencryptionstandardwitha168-bitkeysizeAES128:Thisistheadvanceddataencryptionstandardwitha128-bitkeysizeAES192:Thisisthedefaultencryptionalgorithm.Itistheadvanceddataencryption
standardwitha192-bitkeysizeAES256:Thisistheadvanceddataencryptionstandardwitha256-bitkeysize
Thefollowingprogrammodifiesacolumntoenableencryption:
/*ModifyMISC_DOCScolumntoenableencryption*/
ALTERTABLEemp_secure
MODIFY
(
misc_docsENCRYPTUSING'AES192'
)
/
ALTERTABLEemp_secure
*
ERRORatline1:
ORA-28365:walletisnotopen
Youmightreceivetheprecedingexceptioniftheencryptionwalletisnotopen.Wewillnowauthenticatethewalletbysettingapassword:
connsys/oracleasSYSDBA
ALTERsystem
SETENCRYPTIONKEY
IDENTIFIEDBY"orcl"
/
Systemaltered.
Usingtheprecedingpassword,youcanauthenticateandopenthewallet:
ALTERsystem
SETENCRYPTIONWALLETOPEN
IDENTIFIEDBY"orcl"
/
Systemaltered.
Oncethewalletisopened,itwillcreateafile,ewallet.p12,inthedefaultwalletdirectory:
[oracle@oradev12cwallet]$ll
total4
-rw-r--r--.1oracleoinstall2848May1606:54ewallet.p12
YoucanalsocheckthewalletstatusfromtheV$ENCRYPTION_WALLETdictionaryview:
/*QueryV$ENCRYPTION_WALLETtocheckthewalletstatus*/
SELECTwrl_type,
wrl_parameter,
status
FROMv$encryption_wallet
/
WRL_TYPEWRL_PARAMETERSTATUS
--------------------------------------------------------------
FILE/u01/app/oracle/admin/orcl/walletOPEN
Let’sreruntheALTERTABLEcommandtoenableencryptionfortheMISC_DOCScolumn:
connscott/tiger
/*ModifytheMISC_DOCStoenableencryption*/
ALTERTABLEemp_secure
MODIFY
(
misc_docsENCRYPTUSING'AES192'
)
/
Tablealtered.
YoucanverifytheadvancedsettingfeatureundertheUSER_LOBSdictionaryview:
/*QueryUSER_LOBStoviewadvancedfeaturesofSecureFile*/
SELECTcolumn_name,
encrypt,
compression,
deduplication
FROMuser_LOBs
WHEREtable_name='EMP_SECURE'
/
COLUMN_NAMENCRCOMPREDEDUPLICATION
-----------------------------------
MISC_DOCSYESHIGHLOB
PopulatingtheLOBdataThefollowingPL/SQLprocedurewritesanoperatingsystemfiletoaLOBcolumnagainstatablerecord.Itiscustomizedforourtestcasetoacceptthedirectoryname,filename,tablename,andemployeeID,forwhichthefilehastobeuploaded:
/*StartthePL/SQLblock*/
CREATEORREPLACEPROCEDUREupload_emp_docs
(p_dirVARCHAR2,
p_fileVARCHAR2,
p_tableVARCHAR2,
p_empnoNUMBER)
IS
/*DeclaringLOBlocatorfortheBLOB*/
L_SOURCE_BLOBBFILE;
/*DeclaringoffsetvaluefortheLOBcolumn*/
L_AMT_BLOBINTEGER:=4000;
/*DeclaringtemporaryLOBcolumnsfortheLOBcolumn*/
L_BLOBBLOB:=EMPTY_BLOB();
L_STMTCLOB:=EMPTY_CLOB();
BEGIN
/*CreateaBFILElocatorfortheexternalfile*/
L_SOURCE_BLOB:=BFILENAME(p_dir,p_file);
/*CreateatemporaryLOB*/
DBMS_LOB.CREATETEMPORARY(l_bLOB,true);
/*OpeningtheLOBlocatorinreadonlymode*/
DBMS_LOB.OPEN(L_SOURCE_BLOB,DBMS_LOB.LOB_READONLY);
/*CalculatingthelengthofLOBlocator*/
L_AMT_BLOB:=DBMS_LOB.GETLENGTH(L_SOURCE_BLOB);
/*LoadthetemporaryLOBswiththeLOBlocator*/
DBMS_LOB.LOADFROMFILE(L_BLOB,L_SOURCE_BLOB,L_AMT_BLOB);
/*ClosetheLOBlocators*/
DBMS_LOB.CLOSE(L_SOURCE_BLOB);
/*UpdatethetablewiththetemporaryLOBvariable*/
L_STMT:='UPDATE'||p_table||'SETmisc_docs=:p2WHEREempno=:p3';
EXECUTEIMMEDIATEl_stmtusingl_bLOB,p_empno;
IFSQL%ROWCOUNT=0THEN
DBMS_OUTPUT.PUT_LINE('Wronginput-Employeedoesnotexsts');
ELSE
DBMS_OUTPUT.PUT_LINE('Documentuploadedsuccessfullyforemployee
'||p_empno);
ENDIF;
END;
/
Procedurecreated.
Let’stesttheprocedurebyuploadingaPDFfileforalltheemployees.Beforeweruntheprocedure,youmustcreateadirectorypointingtothefilelocationandgrantthereadwriteprivilegeonthedirectorytotheSCOTTuser.Notethatthedatabasedirectorymustpointtoavalidlocationontheserveroperatingsystem;thereasonbeingthatthedirectorylocationisvalidatedatthetimeofthedirectoryexecutiononly:
CONNsys/oracleASSYSDBA
CREATEORREPLACEDIRECTORYsecure_dirAS'/u01/app/oracle/LOBs/'
/
Directorycreated.
GRANTREAD,WRITEONDIRECTORYsecure_dirTOSCOTT
/
Grantsucceeded.
ThefollowingPL/SQLblockcallstheUPLOAD_EMP_DOCSproceduretouploadthePDFfilesintheEMP_BASICandEMP_SECUREtableforalltheemployees:
SETSERVEROUTOFF
BEGIN
FORIIN(SELECTrownum,empnoFROMemp)
LOOP
/*CalltheproceduretoloadinEMP_BASICtable*/
upload_emp_docs('SECURE_DIR',
'ebook'||i.rownum||',pdf',
'EMP_BASIC',
i.empno);
/*CalltheproceduretoloadinEMP_SECUREtable*/
upload_emp_docs('SECURE_DIR',
'ebook'||i.rownum||',pdf',
'EMP_SECURE',
i.empno);
ENDLOOP;
END;
/
PL/SQLproceduresuccessfullycompleted.
YoucancheckthesizeofthefileuploadedagainstanemployeeusingtheDBMS_LOB.GETLENGTHfunction:
/*VerifythesizeoftheBLOBinarow*/
SELECTempno,DBMS_LOB.GETLENGTH(misc_docs)
FROMemp_secure
WHEREempno=7839
/
EMPNODBMS_LOB.GETLENGTH(MISC_DOCS)
---------------------------------------
78395769744
YoucancheckthenumberofextentsandblocksallocatedforBasicFileandSecureFileusingthefollowingquery:
/*QueryUSER_SEGMENTStocomparethetotalblocksconsumed*/
SELECTtable_name,
l.segment_name,
bytes/1024KB,
blocks,
extents
FROMuser_LOBsl,user_segmentss
WHEREl.segment_name=s.segment_name
ANDl.table_namein('EMP_BASIC','EMP_SECURE')
/
TABLE_NAMESEGMENT_NAMEKBBLOCKSEXTENTS
------------------------------------------------------------
EMP_BASICSYS_LOB0000093890C00007$$819201024081
EMP_SECURESYS_LOB0000093893C00007$$73609209
TemporaryLOBoperationsAtemporaryLOBenablestheLOBoperationssuchascreationandmodificationoftheLOBcolumnvalues.AtemporaryLOBconsumesspaceinatemporarytablespacebutitmustbefreedafterusage.TheDBMS_LOBpackageprovidestheAPIstohandletemporaryLOBactions.
ManagingtemporaryLOBsTheDBMS_LOBpackageofferssubprogramsfortemporaryLOBs.TheDBMS_LOBsubprogram,ISTEMPORARY,determineswhetheragivenLOBistemporaryornot.Syntactically,theoverloadedsubprogramisasfollows:
DBMS_LOB.ISTEMPORARY(LOB_locINBLOB)
RETURNINTEGER;
DBMS_LOB.ISTEMPORARY(LOB_locINCLOBCHARACTERSETANY_CS)
RETURNINTEGER;
Inthesyntax,LOB_LOCistheLOBlocator.ALOBlocatorcanbeaCLOBorBLOBtypevariable.
TocreateatemporaryLOB,youusetheDBMS_LOB.CREATETEMPORARYsubprogram.ItisanoverloadedAPItoallowtheLOBlocatorfromafixedorvariablecharacterset:
DBMS_LOB.CREATETEMPORARY
(
LOB_locINOUTNOCOPYBLOB,
cacheINBOOLEAN,
durationINPLS_INTEGER:=DBMS_LOB.SESSION
);
DBMS_LOB.CREATETEMPORARY
(
LOB_locINOUTNOCOPYCLOBCHARACTERSETANY_CS,
cacheINBOOLEAN,
durationINPLS_INTEGER:=10
);
Intheprecedingsubprogramsignatures:
LOB_loc:ThisistheLOBlocator.cache:ThisisthebooleanparametertospecifywhethertheLOBshouldbecachedinthebuffercacheornot.duration:ItspecifiesthelifeofthetemporaryLOB.ItcanbeoneofSESSION,TRANSACTION,orCALL.ThedefaultdurationofatemporaryLOBisSESSION.
DBMS_LOB.FREETEMPORARYfreesthememoryallocatedforthetemporaryLOB.Thesyntaxfortheoverloadedsubprogramisasfollows:
DBMS_LOB.FREETEMPORARY(LOB_locINOUTNOCOPYBLOB);
DBMS_LOB.FREETEMPORARY(LOB_locINOUTNOCOPYCLOBCHARACTERSETANY_CS);
WorkingwithatemporaryLOBLet’swriteaPL/SQLprogramtoillustratetheusageofthetemporaryLOBsubprograms.Weshallobservethecreation,validation,andreleaseofthetemporaryLOBintheprogram:
/*EnabletheSERVEROUTtodisplaytheblockoutput*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
L_TEMP_LOBCLOB;
AMTNUMBER;
OFFSETNUMBER:=5;
L_WRITEVARCHAR2(100):='Oracle8iintroducedLOBtypes';
L_APPENDVARCHAR2(100):='Oracle11gintroducedSecureFiles';
BEGIN
/*CreatethetemporaryLOB*/
DBMS_LOB.CREATETEMPORARY
(
LOB_loc=>L_TEMP_LOB,
cache=>true,
dur=>dbms_LOB.session
);
/*VerifythecreationoftemporaryLOB*/
IF(DBMS_LOB.ISTEMPORARY(L_TEMP_LOB)=1)THEN
DBMS_OUTPUT.PUT_LINE('GivenLOBisatemporaryLOB');
ELSE
DBMS_OUTPUT.PUT_LINE('GivenLOBisapersistentLOB');
ENDIF;
/*OpenthetemporaryLOBisreadwritemode*/
DBMS_LOB.OPEN
(
LOB_loc=>L_TEMP_LOB,
open_mode=>DBMS_LOB.LOB_READWRITE
);
/*WritethesampledatainthetemporaryLOB*/
DBMS_LOB.WRITE
(
LOB_loc=>L_TEMP_LOB,
amount=>LENGTH(L_WRITE),
offset=>OFFSET,
buffer=>L_WRITE);
DBMS_OUTPUT.PUT_LINE
(
'TemporaryLOBlengthafterWrite'||DBMS_LOB.GETLENGTH(L_TEMP_LOB)
);
/*AppendthesampleinthetemporaryLOB*/
DBMS_LOB.WRITEAPPEND
(
LOB_loc=>L_TEMP_LOB,
amount=>LENGTH(L_APPEND),
buffer=>L_APPEND
);
DBMS_OUTPUT.PUT_LINE
(
'TemporaryLOBlengthafterAppend'||DBMS_LOB.GETLENGTH(L_TEMP_LOB)
);
/*DisplaythecompletecontentofthetemporaryLOB*/
DBMS_OUTPUT.PUT_LINE
(
CHR(10)||'TemporaryLOBContent:'
);
DBMS_OUTPUT.PUT_LINE
(
DBMS_LOB.SUBSTR
(
L_TEMP_LOB,DBMS_LOB.GETLENGTH
(L_TEMP_LOB),1
)
);
DBMS_LOB.CLOSE(LOB_loc=>L_TEMP_LOB);
DBMS_LOB.FREETEMPORARY(LOB_loc=>L_TEMP_LOB);
END;
/
GivenLOBisatemporaryLOB
TemporaryLOBlengthafterWrite34
TemporaryLOBlengthafterAppend67
TemporaryLOBContent:
Oracle8iintroducedLOBtypesOracle11gintroducedSecureFiles
PL/SQLproceduresuccessfullycompleted.
MigratingLONGtoLOBsThedatabaseapplicationsusingLONGdatatypesshouldmigratetoLOBduetothefollowingreasons:
ALONGcolumncanstoreamaximumof(2GB-1)whileanLOBcanstoreamaximumdataof(4GB-1)Atablecanhaveone,andonlyone,LONGdatatypecolumnwhilethereisnorestrictiononthenumberofLOBcolumnsinatableDatareplicationisnotallowedwiththeLONGandLONGRAWcolumns
TipMigratingLONGtotheLOBcolumnsmaygeneratealotofredo.Therefore,itisadvisedtoswitchofftheloggingforthetablecontainingtheLONGcolumn.
YoucanconvertLONGtoCLOBandLONGRAWtoBLOBusingeitherofthefollowinglistedapproaches:
UsetheALTERTABLEcommandForatablewiththeLONGtypecolumn,youcanusetheALTERTABLEcommandtomodifythecolumntypetoLOBwithnewstoragespecificationsandmigratethedatatoanewspace.NotethatalltheLONGdataismigratedasLOBinthetable.Allthecolumn-levelcharacteristicsoftheLONGcolumnareretainedandcarriedforwardtotheLOBcolumn.Asabestpractice,youshoulddropthedomainindexesontheLONGcolumns,ifanyexist.
Forexample,thefollowingcommandconvertstheTEXTcolumnfromLONGtoLOB:
ALTERTABLEneed_to_migrateMODIFY(textCLOB)
/
UsingtheTO_LOBfunctionYoucanusetheTO_LOButilityfunctiontoconverttheLONGdataintoLOBwhileperformingtheCREATETABLEASSELECTorINSERTINTO..SELECTactions.ThismethodisbeneficialwhenyouwanttoperformtheconversionofasubsetoftheLONGvaluesbyapplyingpredicateclausestotheSELECTquery.ItcannotbeusedinaPL/SQLblock.
TheTO_LOBfunctionconvertsLONGtoCLOBorNCLOBandLONGRAWtoBLOBdata.Refertothefollowingexample:
CREATETABLEsales_new
AS
SELECTsales_id,sales_name,TO_LOB(sales_doc)
FROMsales_old
/
TheTO_LOBfunctioninaCTASoperationdoesn’tworkforanIndexOrganizedTable.However,theINSERTASSELECToperationonanindex-organizedtablestillworks.
OnlineTableRedefinitionOnlinetableredefinitionusestheTO_LOButilityfunctiontoperformtheLONGtoLOBconversion.Youhavetocreateawork-in-progresstableofthesamestructureastheoriginaltable.Notethatthistime,youwillusetheLOBcolumnsinplaceoftheLONGcolumns.Later,youcancallDBMS_REDEFINITION.START_REDEF_TABLEwiththerequiredparameterstokickofftheconversion.
MigratingBasicFilestoSecureFilesItisrecommendedtomigratetheBasicFileLOBstoSecureFileLOBsusingtheOnlineTableRedefinitionmethod.TheadvantageofusingtheOnlineTableRedefinitionmethodisthatnoneoftheobjectshavetobeofflineduringtheprocess.Inaddition,theperformanceoftheredefinitionprocesscanbeenhancedbyenablingparallelism.Thefollowingexampledemonstratestheonlineredefinitionprocess.
ATAB_BASICFILEtablecontainstheDOCcolumnthatisaBasicFileCLOBcolumn:
SELECT*
FROMtab_basicfile
/
IDDOC
-----------------------
1Oracle9i
2Oracle10g
3Oracle11g
4Oracle12c
ThefollowingquerycheckstheLOBbehaviorfromtheUSER_LOBSdictionaryview:
SELECTcolumn_name,
securefile
FROMuser_LOBs
WHEREtable_name='TAB_BASICFILE'
/
COLUMN_NAMESEC
----------------
DOCNO
Forredefinition,wewillcreateawork-in-progresstablewiththesamestructureastheTAB_BASICFILEtable.Youcandropthistableafterthetableredefinitionactivityisover.Notethatthistableshouldnothaveanyindexes.Duringtheredefinitionprocess,thetargettablewillcarrythesamedataastheoriginaltable.Therefore,thehostservermusthavesufficientfreespaceavailabletoperformtheredefinitionoperation:
/*CreatingtargettableTAB_SECUREFILEforredefinition*/
CREATETABLETAB_SECUREFILE
(idNUMBER,
docCLOB)
LOB(doc)STOREASSECUREFILE
/
/*VerifytheSecureFilefeature*/
SELECTcolumn_name,
securefile
FROMuser_LOBs
WHEREtable_name='TAB_SECUREFILE'
/
COLUMN_NAMESEC
----------------
DOCYES
Youcankick-startthetableredefinitionoperationbycallingtheDBMS_REDEFINITION.START_REDEF_TABLEsubprogram:
connsys/oracleasSYSDBA
/*StartthePL/SQLblock*/
DECLARE
L_ERRORPLS_INTEGER:=0;
BEGIN
/*Specifysourceandtargettablesforredefinition*/
DBMS_REDEFINITION.START_REDEF_TABLE
(uname=>'SCOTT',--Schemanameofthetables
orig_table=>'TAB_BASICFILE',--Tabletoberedefined
int_table=>'TAB_SECUREFILE',--Interimtable
col_mapping=>'idid,docdoc'--Columnmappingfrom
sourcetointerimtable
);
/*Specifysourceandtargettablesforcopyingthedependents*/
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS
(uname=>'SCOTT',--Schemanameofthetables
orig_table=>'TAB_BASICFILE',--Originaltable
int_table=>'TAB_SECUREFILE',--Interimtable
copy_indexes=>1,--Copyindexes(1)ornot(0)
copy_triggers=>true,--Copytriggers(T)ornot(F)
copy_constraints=>true,--Copyconstraints(T)ornot(F)
copy_privileges=>true,--Copyprivileges(T)ornot(F)
ignore_errors=>false,--Ignoreerrorswhilecopyinga
dependentobject
num_errors=>L_ERROR,--Numberoferrorsoccurredwhile
copyingdependentobjects
copy_statistics=>FALSE,--Copystatistics(1)ornot(0)
copy_mvlog=>FALSE--Copymaterializedviewlog(1)or
not(0)
);
DBMS_OUTPUT.PUT_LINE('Errors:='||TO_CHAR(L_ERROR));
/*Finishtheredefinitionprocess*/
DBMS_REDEFINITION.FINISH_REDEF_TABLE
(uname=>'SCOTT',--Schemanameofthetables
orig_table=>'TAB_BASICFILE',--Tabletoberedefined
int_table=>'TAB_SECUREFILE'--Interimtable
);
END;
/
PL/SQLproceduresuccessfullycompleted.
YoucanuseDBMS_REDEFINITION.ABORT_REDEF_TABLEtoabortthetableredefinitionprocessifyouencountertheORA-23539:table"SCOTT"."TAB_BASICFILE"currently
beingredefinedexception.
Let’sverifytheSECUREFILEpropertyfortheTAB_BASICFILEtable:
SELECTcolumn_name,
securefile
FROMUSER_LOBS
WHERETABLE_NAME='TAB_BASICFILE'
/
COLUMN_NAMESEC
-----------------------
DOCYES
TAB_BASICFILEexchangesitstablepropertieswithTAB_SECUREFILE:
SELECTcolumn_name,securefile
FROMUSER_LOBS
WHERETABLE_NAME='TAB_SECUREFILE'
/
COLUMN_NAMESEC
-----------------------
DOCNO
OracleDatabase12cenhancementstoSecureFilesOracleDatabase12caddsthefollowingfeaturestotheSecureFileLOBs:
SecureFilesLOBwillbethedefaultstorage:YoumighthaveseenthispointearlierinthechaptersothisisjustreiteratingthefactthatSecureFileswillbethedefaultstorageoptioninOracleDatabase12c.Thevalueofthedb_securefileinitializationparameterisPREFERRED,whichmeansthatallLOBsontheASSMenabledtablespacewillbecreatedasSecureFiles(unlessBasicFileisexplicitlyspecifiedorthetablespaceisnonASSM).ParallelDMLsupportforLOBs:IfalltheLOBcolumnsinapartitionedornon-partitionedtableareSecureFiles,thenDMLoperationscanbeexecutedinparallel.DataPumpusesSecureFileasthedefaultLOBstorage:YoucannowmigrateaBasicFiletoSecureFileusingtheDataPumputility.Duringanexportdatapumpoperation,youcansettheTRANSFORMhandleasLOB_STORAGEtodecidehowtheLOBsegmentswillbecreatedinthetargetdatabase.TheLOB_STORAGEhandlecanbeSECUREFILE,BASICFILE,DEFAULT,orNO_CHANGE(default):TheNO_CHANGEoptiondoesnotmanipulatetheLOBstorage.TheDEFAULToptionfollowsthedefaultLOBstorageonthetargetdatabase.TheSECUREFILE|BASICFILEoptionsenablethecreationoftheLOBsegmentsasSecureFilesorBasicFiles.
SummaryInthischapter,youlearnedhowtohandlelargeobjectsinOracle.Younowunderstandthedynamicsofstoringlargeobjectsinadatabase.AdetaileddiscussionontheoptimizationfeaturesofOracleSecureFileswouldhavehelpedyoutodifferentiatethetwostorageapproaches.ThecomparativeillustrationofaBasicFileandSecureFilewillhelpindeducingtheappropriateconclusions.
Movingforward,thenextchapterwilldealwithanotherimportantaspectofdatabaseprogramming,thatis,tuningthePL/SQLcode.Tuning—anindispensablepartofprogramming—isaskillforwritingoptimizedcode,whichcomesfromknowledgeandmatureswithexperience.
PracticeexerciseInternalLOBscanbeusedasattributesofauser-defineddatatype:
1. True.2. False.
InternalLOBscannotbepassedasparameterstoPL/SQLsubprograms:
1. True.2. False.
InternalLOBscanbestoredinatablespacethatisdifferentfromthetablespacethatstoresthetablecontainingtheLOBcolumn:
1. True.2. False.
YouissuethefollowingcommandtocreateatablecalledLOB_STORE:
CREATETABLELOB_store
(LOB_idNUMBER(3),
photoBLOBDEFAULTEMPTY_CLOB(),
cvCLOBDEFAULTNULL,
ext_fileBFILEDEFAULTNULL)
/
Identifytheissueinthisscript:
1. Thetableiscreatedsuccessfully.2. ItgeneratesanerrorbecauseaBLOBcolumncannotbeinitializedwith
EMPTY_CLOB().3. ItgeneratesanerrorbecauseDEFAULTcannotbesettoNULLforaCLOBcolumn
duringtablecreation.4. ItgeneratesanerrorbecauseDEFAULTcannotbesettoNULLforaBFILEcolumn
duringtablecreation.
IdentifythecorrectstatementsrelatingtotheinitializationofLOBs:
1. AninternalLOBcannotbeinitializedintheCREATETABLEstatement.2. ABFILEcolumncanbeinitializedwiththeEMPTY_BFILE()constructor.3. TheEMPTY_CLOB()andEMPTY_BLOB()functionscanbeusedtoinitializeboth
theNULLandNOTNULLinternalLOBsoftheCLOBandBLOBtypes.4. InitializationisamandatorystepforLOBtypecolumns.
WhichtwostatementsaretrueabouttheFILEOPENsubprogramintheDBMS_LOBpackage?
1. FILEOPENcanbeusedtoopenonlyinternalLOBs.2. FILEOPENcanbeusedtoopenonlyexternalLOBs.3. FILEOPENcannotbeusedtoopentemporaryLOBs.4. FILEOPENcanbeusedtoopeninternalandexternalLOBs.
TemporaryLOBscanbesharedamongtheuserswhoarecurrentlyconnectedtotheserver:
1. True.2. False.
IdentifythecorrectstatementsaboutBFILEs:
1. ABFILEcolumninatablemustbeinitializedwithadummylocator.2. BFILEscannotbeusedasattributesinanobjecttype.3. TheBFILEdatatypeisaread-onlydatatype.4. TheexternalfilestillpersistsiftheBFILElocatorisdeletedormodified.
PicktheincorrectstatementsaboutTemporaryLOBs:
1. Itresidesintheuser’stemporarytablespace.2. ItcanbeusedduringtheLONGtoLOBdatatypemigration.3. ItcanbepersistentforSESSION,TRANSACTION,orCALL.4. TemporaryLOBofaBFILEtypecanbecreated.
ASAMPLE_DATAtablehasthefollowingstructure:
NameNull?Type
------------------
SD_IDNUMBER
SD_SOURCEBFILE
YouupdatearowinthetableusingtheUPDATEstatement,asfollows:
UPDATEsample_data
SETsd_source=BFILENAME('SD_FILE','sample.pdf')
WHEREsd_id=448;
However,youreceivetheerror—ORA-22286:insufficientprivileges—onthefileordirectorytoperformFILEOPEN.
Whatcouldbetheprobablecauseofthiserror?
1. ThedirectorySD_FILEdoesnotexist.2. Thefilesample.pdfdoesnotexist.3. TheuserdoesnothavetheREADprivilegeonthedirectory.4. Thefilesample.pdfisaread-onlyfile.
WhichofthefollowingstatementsaboutSecureFilesaretrue?
1. SecureFilesrequireanASSM-enabledtablespace.2. ABFILEtypecolumninatablecanbedeclaredasSecureFiles.3. ASecureFileisnotaffectedbyaLOBindexcontention.4. SecureFilesuseanewcachecomponentofthebuffercachetoholdtheLOBdata.
IdentifytheincorrectstatementaboutthecompressionfeatureinSecureFiles:
1. CompressionimpactsperformanceduringaLOBwriteoperation.2. SecureFilescompressionispartoftheadvancedcompressionfeatureinOracle.3. PossibledegreesofcompressioncanbeMEDIUMandHIGH.4. OraclecompressesalltheLOBdataathighpriorityifthefeaturehasbeen
enabledforaSecureFile.
ThecompressionfeaturecanbeenabledonlyforencryptedSecureFiles:
1. True.2. False.
AcompressedtablecontainingaSecureFilecolumnwillautomaticallyenablecompressionforSecureFiles:
1. True.2. False.
IdentifythetruestatementsaboutthededuplicationfeatureofSecureFiles:
1. KEEP_DUPLICATESisthedefaultoption.2. DEDUPLICATEretainsonecopyoftheduplicateLOBdata.3. ThededuplicationfeatureimpactswriteperformanceasOraclecomparesthe
securehashcodewiththeavailablehashcodesbeforewritingtothedisk.4. ThededuplicationofSecureFilesischeckedonthebasisofthefilenames.
PickthecorrectstatementfortheencryptionfeatureinSecureFiles:
1. TheSecureFileencryptionkeysarestoredinthetable.2. TheSecureFileencryptionkeysarestoredinthedatabase.3. TheSecureFileencryptionkeysarestoredoutsidethedatabase.4. EncryptionalgorithmscannotbemodifiedforanencryptedSecureFilecolumn.
WhichofthefollowingstatementsaretrueforBasicFiletoSecureFilemigrationinOracle?
1. TheBasicFiletoSecureFilemigrationcanbedonethroughadatapumpoperation.
2. Tableredefinitionispreferredasitdoesthemigrationwithalltheresourcesconnectedonline.
3. TheDBMS_REDEFINITIONpackagecanmigrateonlyoneLOBcolumnatatime.4. Unnecessaryspaceconsumptionmakestheredefinitionprocesslesspreferable
overthepartitionmethod.
Chapter8.TuningthePL/SQLCodeDatabasetuningreferstoanexercisethataimstoimprovetheperformanceofadatabase.Theartofoptimizingthedatabaseperformancelargelydependsonhowwelloneunderstandsthedatabasearchitecture,applicationdesignandserverenvironment.Theareasthatcanbepotentiallytunedaretheapplicationdesign,network,SQLqueries,andPL/SQLcode.Thisexercisestartswiththedetectionandidentificationofaproblem,followedbyanalysisandtuningrecommendations.Inthischapter,wewillseetuningpracticesrelatedtotheOraclePL/SQLcode.
ProgramswritteninOraclePL/SQLcanbetunedtooptimizedata-centricandCPU-intensiveoperations.InaPL/SQLprogramunit,statementslikeloops,dynamicSQLstatements,routinecalls,andthecompilationmodecanbetunedforbetterperformance.Thischapterwilldiscussthedifferentcodecompilationtechniquesandtheirbenefits.Thechapteroutlineisasfollows:
ThePL/SQLCompiler
Subprograminline
NativecompilationofthePL/SQLCodeTuningthePL/SQLCode
BuildsecureapplicationsusingbindvariablesCallparametersbyreferenceAvoidanimplicitdatatypeconversionUnderstandtheNOTNULLconstraintSelectanappropriatenumericdatatypeBulkprocessinginPL/SQL
ThePL/SQLCompilerThePL/SQLcompilerconvertsapieceofPL/SQLcodethatiswritteninuser-readablelanguagesemanticstosystemcode.Atahigherlevel,thecodecompilationisathree-stepprocessthatincludescodeparsing,parameterbinding,andtranslationintomachinecode(M-code).ThecompilerraisesasyntaxorcompilationerrorifaPL/SQLconstructorstatementisincorrectlyused.OncethePL/SQLprogramcodeiserror-freeandargumentbindingisdone,thesystemcodeisgeneratedandstoredinthedatabase.
UntilOracle10gRelease1,theM-codewasgeneratedwithoutanycodeoptimization.StartingfromOracleDatabase10gRelease2,M-codeusesthePL/SQLoptimizertoapplycodeformattingforbetterperformance.ThePL/SQLoptimizerlevelisgovernedbyacompilationparameterknownasPLSQL_OPTIMIZE_LEVEL.Theparametervaluecanbesetatthesystemorsessionlevelasanumberbetween1to3.Bydefault,theparametervalueis2.
ThePL/SQLoptimizerusesmultipletechniquestooptimizethePL/SQLcode,forexample,theremovalofdeadcodefromtheprogramunit,orinliningthecallstosubprograms.Letusfirstseehowsubprograminliningworks.
SubprograminlininginPL/SQLAPL/SQLprogramunitwithalocally-declaredandinvokedsubprogramcanbeoptimizedusingtheinliningmethod.Whileoptimizingtheprogramcode,thePL/SQLoptimizerreplacesthesubprograminvocationcallsbythesubprogrambodyitself.ForthePL/SQLcompilertoinlinealocalsubprogram,thefollowingcriteriamustbemet:
SetPLSQL_OPTIMIZE_LEVELto2andusePRAGMAINLINE:ThecompilerinlinesonlythosesubprogramsthatarespecifiedwithPRAGMAINLINE.SetPLSQL_OPTIMIZE_LEVELto3:Thecompilerinlinesallthesubprogramcalls.However,youcanspecifyPRAGMAINLINEtopreventtheinliningofaparticularsubprogram.Todisabletheinliningofaprogramunit,specifyPRGMAINLINE([subprogramunit],'NO').
PRAGMAINLINEdirectsthecompilertoinlinethesubprogramcallsthatarejustsucceedingit.Forexample,inthefollowingPL/SQLblock,thesubprogramcallisinlinedinLine5butnotinLine7:
PROCEDUREP_SUM_NUM(P_ANUMBER,P_BNUMBER)/*Line1*/
.../*Line2*/
BEGIN/*Line3*/
PRAGMAINLINE('P_SUM_NUM','YES')/*Line4*/
result_1:=P_SUM_NUM(10,20);/*Line5*/
..../*Line6*/
result_2:=P_SUM_NUM(100,200);/*Line7*/
END;/*Line8*/
//*Line9*/
Atmostofthescenarios,subprograminliningimprovestheperformanceofaPL/SQLprogram.Ifthesubprogramisalargeunit,thecostofinliningwouldbemorethanthemodularexecution.
NotePRAGMAINLINE([subprogram],'NO')willalwaysoverridePRAGMAINLINE([subprogram],'YES')inthesamedeclaration.
ItisrecommendedthatyouinlinethoseutilitysubprogramsthatarefrequentlyinvokedinaPL/SQLblock.Theintra-unitinliningistraceablethroughsession-levelwarnings.Thesession-levelwarningscanbeturnedonbysettingthePLSQL_WARNINGSparametertoENABLE:ALL.
PRAGMAINLINEPRAGMAisacompilerdirectivethathintsthecompiler.AnyerrorintheusageofPRAGMAresultsinacompilationerror.NotethataPRAGMA,whichacceptsanargument,cannotacceptaformalargumentbutalwaysneedsanactualargument.
PRAGMAINLINEwasintroducedinOracleDatabase11gtosupportsubprograminliningforbetterPL/SQLperformance.WhenthecompilationparameterPLSQL_OPTIMIZE_LEVELis2,youhavetospecifythesubprogramtobeinlinedusingPRAGMAINLINE.When
PLSQL_OPTIMIZE_LEVELis3,thePL/SQLoptimizertriestoinlinemostofthesubprogramcalls,withoutrequiringanyPRAGMAspecification.Atthisstage,ifyouperceiveaninlinedsubprogramtobeirrelevantorundesirable,youcandisabletheinliningofthatparticularsubprogramthroughPRAGMAINLINE.
NotePRAGMAINLINEimpactsonlywhenPLSQL_OPTIMIZE_LEVELiseither2or3.WhenPLSQL_OPTIMIZE_LEVELis1,ithasnoeffect.
PLSQL_OPTIMIZE_LEVELOracleDatabase10gintroducedthePLSQL_OPTIMIZE_LEVELinitializationparametertoenableordisablePL/SQLoptimization.Ifenabled,theoptimizerdeploysseveraloptimizationtechniquesinaccordancewiththelevel.ThecompilationsettingsofaPL/SQLprogramcanbequeriedfromtheUSER_PLSQL_OBJECT_SETTINGSdictionaryview.
UntilOracleDatabase10g,theparametervaluecouldbeeither0,1,or2.StartingfromOracleDatabase11g,thenewoptimizationlevelcanbeenabledbysettingtheparametervalueto3.Notethatthedefaultvalueoftheparameteris2.TheparametervaluecanbemodifiedusingtheALTERSYSTEMorALTERSESSIONstatements.OnlythePL/SQLprogramsthatarecompiledaftertheparametermodificationareimpacted.YoucanalsospecifythePLSQL_OPTIMIZE_LEVELvalueatthetimeofexplicitcompilationofaprogramunit.Forexample,aP_OPT_LVLprocedurecanberecompiledusingthefollowingstatement:
ALTERPROCEDUREp_opt_lvlCOMPILEPLSQL_OPTIMIZE_LEVEL=1
/
ThefollowingPL/SQLproceduredemonstratesthesubprograminliningusingPRAGMAINLINE.Theprocedureaddstheseries(1*2)+(2*2)+(3*2)+…+(N*2)uptoNterms:
/*Createaprocedure*/
CREATEORREPLACEPROCEDUREP_SUM_SERIES(p_countNUMBER)
IS
l_seriesNUMBER:=0;
l_timeNUMBER;
/*Declarealocalsubprogramwhichreturnsthedoubleofanumber*/
FUNCTIONF_CROSS(p_numNUMBER,p_multiplierNUMBER)RETURNNUMBERIS
l_resultNUMBER;
BEGIN
l_result:=p_num*p_multiplier;
RETURN(l_result);
ENDF_CROSS;
BEGIN
/*Capturethestarttime*/
l_time:=DBMS_UTILITY.GET_TIME();
/*Begintheloopforseriescalculation*/
FORJIN1..p_count
LOOP
/*Setinliningforthelocalsubprogram*/
PRAGMAINLINE(F_CROSS,'YES');
l_series:=l_series+F_CROSS(J,2);
ENDLOOP;
/*Timeconsumedtocalculatetheresult*/
DBMS_OUTPUT.PUT_LINE('Executiontime:'||TO_CHAR(DBMS_UTILITY.GET_TIME()
-L_TIME));
END;
/
Case1:WhenPLSQL_OPTIMIZE_LEVEL=0
Atlevel0,thePL/SQLoptimizerdoesn’tkickin,sonocodeoptimizationisenabled.Thecompilermaintainsthecodeevaluationorder,andperformsobjectchecks.
EnablePLSQL_WARNINGStocapturetheinlineoperations:
ALTERSESSIONSETplsql_warnings='enable:all'
/
Sessionaltered.
Let’srecompiletheP_SUM_SERIESprocedurewiththePLSQL_OPTIMIZE_LEVEL=0setting:
ALTERPROCEDUREP_SUM_SERIESCOMPILEPLSQL_OPTIMIZE_LEVEL=0
/
SP2-0804:Procedurecreatedwithcompilationwarnings
showerrors
ErrorsforPROCEDUREP_SUM_SERIES:
LINE/COLERROR
----------------------------------------------------------------
1/1PLW-05018:unitP_SUM_SERIESomittedoptionalAUTHIDclause;
defaultvalueDEFINERused
Let’sexecutetheprocedurewitharelativelylargeinputvalueforacomputation-intensiveoperation:
BEGIN
p_sum_series(10000000);
END;
/
Executiontime:776
PL/SQLproceduresuccessfullycompleted.
Case2:WhenPLSQL_OPTIMIZE_LEVEL=1
Atlevel1,thePL/SQLoptimizerappliesconventionaloptimizationtechniquestoa
PL/SQLprogramunit.Iteliminatesthedeadcode,andskipstheredundantandunnecessarycodeintheprogramwhilegeneratingthep-codeinstructions.
Whatisdeadcode?IfaPL/SQLstatementremainsunchangedwithinaniterativeorconditionalconstruct,anddoesn’tcontributetotheprogramlogic,itisknownasdeadcode.Whiletranslatingtheprogramintothesystemcodeinstructions,thePL/SQLoptimizeridentifiesthepiecesofdeadcodeandpreventstheirconversion.
Let’srecompiletheP_SUM_SERIESprocedureusingtheALTERPROCEDUREstatementforPLSQL_OPTIMIZE_LEVEL=1andcheckthewarnings:
ALTERPROCEDUREP_SUM_SERIESCOMPILEPLSQL_OPTIMIZE_LEVEL=1
/
SP2-0804:Procedurecreatedwithcompilationwarnings
showerrors
ErrorsforPROCEDUREP_SUM_SERIES:
LINE/COLERROR
----------------------------------------------------------
1/1PLW-05018:unitP_SUM_SERIESomittedoptionalAUTHIDclause;
defaultvalueDEFINERused
YoucanalsoquerythecompilationwarningsfromtheUSER_ERRORSdictionaryview.
AlthoughPRAGMAwasspecified,theF_CROSSinvocationwasnotinlined.Therefore,thesubprograminliningdoesn’tseemtoworkwhenPLSQL_OPTIMIZE_LEVELissetto1:
BEGIN
P_SUM_SERIES(10000000);
END;
/
Executiontime:710
PL/SQLproceduresuccessfullycompleted.
Case3:WhenPLSQL_OPTIMIZE_LEVEL=2
Atlevel2,thePL/SQLoptimizerperformstheintelligentcodeoptimizationthroughtechniqueslikeexplicitsubprograminliningandcodereorganization.
RecompiletheP_SUM_SERIESprocedurewithPLSQL_OPTIMIZE_LEVEL=2usingtheALTERPROCEDUREstatement:
ALTERPROCEDUREp_sum_seriesCOMPILEPLSQL_OPTIMIZE_LEVEL=2
/
SP2-0805:Procedurealteredwithcompilationwarnings
Let’sretrievethecompilationwarnings.Oracleincludesanewsetofcompilationwarningstodemonstratetheinliningflowintheprogram.ThePL/SQLoptimizerisinstructedbyPRAGMAtoinlinethesubprograminline28.Atline8,thefunctionwasremovedanditsbodywasmergedintothemainprogram.Line28showstheinliningrequestandaction:
SQL>showerrors
ErrorsforPROCEDUREP_SUM_SERIES:
LINE/COLERROR
---------------------------------------------------------
1/1PLW-05018:unitP_SUM_SERIESomittedoptionalAUTHIDclause;
defaultvalueDEFINERused
8/3PLW-06006:uncalledprocedure"F_CROSS"isremoved.
28/7PLW-06004:inliningofcallofprocedure'F_CROSS'requested
28/7PLW-06005:inliningofcallofprocedure'F_CROSS'wasdone
Let’scheckhowalevel2-optimizedandcompiledprogramperforms:
BEGIN
P_SUM_SERIES(10000000);
END;
/
Executiontime:456
PL/SQLproceduresuccessfullycompleted.
Welldone!Itrunsin456ms,whichisalmosthalfofitsbaseline,thatis,2timesbetterperformance.
Case4:WhenPLSQL_OPTIMIZE_LEVEL=3
Level3optimizationfocusesonthepredictiveandautomaticinliningandcoderefactoring.Modifythecompilationparameterinthesessionusingthefollowingstatement:
ALTERSESSIONSETplsql_optimize_level=3
/
Sessionaltered.
Toseetheimplicitinliningofthesubprogram,let’srecreatetheP_SUM_SERIESprocedurewithoutthePRAGMAspecification:
/*Createaprocedure*/
CREATEORREPLACEPROCEDUREP_SUM_SERIES(p_countNUMBER)
IS
l_seriesNUMBER:=0;
l_timeNUMBER;
/*Declarealocalsubprogramtoreturnthedoubleofanumber*/
FUNCTIONF_CROSS(p_numNUMBER)RETURNNUMBERIS
BEGIN
RETURN(p_num*2);
ENDF_CROSS;
BEGIN
/*Capturethestarttime*/
l_time:=DBMS_UTILITY.GET_TIME();
/*Begintheloopforseriescalculation*/
FORJIN1..p_count
LOOP
/*Setinliningforthelocalsubprogram*/
l_series:=l_series+F_CROSS(J);
ENDLOOP;
/*Timeconsumedtocalculatetheresult*/
DBMS_OUTPUT.PUT_LINE('Executiontime:'||TO_CHAR(DBMS_UTILITY.GET_TIME()
-L_TIME));
END;
/
SP2-0805:Procedurealteredwithcompilationwarnings
Let’scheckthecompilationwarnings:
showerrors
ErrorsforPROCEDUREP_SUM_SERIES:
LINE/COLERROR
----------------------------------------------------------
1/1PLW-05018:unitP_SUM_SERIESomittedoptionalAUTHIDclause;
defaultvalueDEFINERused
8/3PLW-06006:uncalledprocedure"F_CROSS"isremoved.
25/7PLW-06005:inliningofcallofprocedure'F_CROSS'wasdone
Notethewarningsatline8andline24.NoPRAGMAspecified,butthePL/SQLoptimizerinlinesthesubprogram.Let’sseehowtheprocedureexecutionisimpactedbylevel3optimization:
BEGIN
P_SUM_SERIES(10000000);
END;
/
Executiontime:420
PL/SQLproceduresuccessfullycompleted.
Theexecutiontimeisalmostequaltothelevel2optimization,becausethetechniquetooptimizethecodewassimilarinboththecases.
Theconsolidationoftheexecutionnumbersisshowninthefollowingtable:
PLSQL_OPTIMIZE_LEVEL InliningRequested InliningDone Executiontime Performancefactor
PLSQL_OPTIMIZE_LEVEL=0 Yes No 776 1
PLSQL_OPTIMIZE_LEVEL=1 Yes No 710 1.1x
PLSQL_OPTIMIZE_LEVEL=2 Yes Yes 456 1.7x
PLSQL_OPTIMIZE_LEVEL=3 No Yes 420 1.8x
Note
ItisrecommendedthatyouhavePLSQL_OPTIMIZE_LEVELas2forthedatabasedevelopmentandproductionenvironments.ItideallyoptimizesthePL/SQLcodeandenablesthedatabasedeveloperstocontrolthesubprograminlining.
NativeandinterpretedcompilationtechniquesUntilOracle9i,allPL/SQLprogramunitswerecompiledininterpretedmode.StartingwithOracle9i,PL/SQLprogramscanbecompiledeitherininterpretedmodeornativemode.Let’squicklyunderstandwhatareinterpretedandnativecompilationmodes.
ThePL/SQLcompilergeneratesmachinecodefortheprogramunits.MachinecodeisasetofinstructionsstoredinthedatabasedictionariesthatrunsagainstthePL/SQLvirtualmachine(PVM).Atthetimeoftheprograminvocation,theM-codeisscannedbyoneofthesubroutinesinthePVM.Thescanningprocessinvolvestheidentificationoftheoperationcodeandoperandsandroutingthecalltotheappropriatesubroutine.Thescanningofthemachinecodeinstructionsconsumessystemsresources,whichmayimpacttheruntimeperformanceofthecode.Thisishowinterpretedcompilationworks.Inthecaseofnativecompilation,ashareabledynamiclinkedlibrary(DLL)isgeneratedinsteadofamachinecode.Atruntime,theDLLisdirectlyinvokedanditinvokesthesubroutinealongwiththerequiredsetofarguments.WithDLL,youdon’thavetogothroughthescanningprocedureatruntime,whichcontributestobettercodeperformance.
UntilOracleDatabase9iand10g,thechallengewithnativecompilationwastogenerateaplatform-specificshareableandnonportablelibrary.ItwasmadepossiblebytheCcompilerandlinkercommandslocatedin$ORACLE_HOME/plsql/spnc_commands,whichwouldcompileandlinktheCtranslationofthemachinecodetoaplatform-specificlibrary.InOracleDatabase9i,thelibrarieswerestoredonafilesystem,whileinOracleDatabase10g,thelibrarieswerestoredinacatalog(databasedictionary).Acopyofthesharedlibrarieswasstoredonafilesystemforbackupandoperating-systemoperations.ThefilesystemlocationusedtobespecifiedinPLSQL_NATIVE_LIBRARY_DIRandPLSQL_NATIVE_LIBRARY_SUBDIR_COUNT.Thesharedlibrarieswereautomaticallyextracted,restored,anddeletedfromthefilesystem.Ifanyofthefilesystemlibrarieswerelostordroppedaccidently,theywerere-extractedandrestoredinthefilesystemafterthedatabasewasrestarted.
NoteThesharedlibrariesgeneratedduringnativecompilationarestoredintheNCOMP_DLL$dictionary.
NativecompilationissupportedwiththeRealApplicationCluster(RAC)databaseoption.
ThisapproachworkedwelluntiltheproductionDBAsshowedreluctanceinhavingtheCcompileronproductionenvironmentsandprocuringanadditionalCcompilerlicense.
OracleDatabase11gRealNativeCompilationOracleDatabase11gintroducedtherealnativecompilationtechniquetoaddressthebelow:
RemovetheCcompilerandlinkerdependenciestogenerateplatformspecificlibrariesImprovecodecompilationperformanceNocompromisewiththeruntimeperformance
StartingfromOracleDatabase11g,theOracleDatabasecangenerateplatform-specificmachinecodefromPL/SQLcodeandstoreitinthedatabasecatalogoraninternaldictionarywithouttheinterventionofathirdpartyCcompiler.Thenativecodeisthenloadeddirectlyfromthecatalogwithoutstagingitonafilesystem.OracleDatabase11grealnativecompilationimprovesthecompilationperformancebyadegreeofmagnitude.
Thefollowinglistsummarizesthesalientfeaturesofrealnativecompilationprocess:
ThereisnodependencyonathirdpartyCCompiler.ThenativecodeisstoredintheSYSTEMtablespace.ThereisnoDBAtasktosetthefilesysteminitializationparameter.Thecompilationmethodiscontrolledbyaninitializationparameter:PLSQL_CODE_TYPE[native/interpreted].NativecompilationissupportedforalltypesofPL/SQLprogramunits.InINTERPRETEDmode,thePL/SQLcodeiscompiledtotheequivalentmachinecode.ThemachinecodeinstructionsarescannedduringtheruntimeandroutedtotheappropriatesubroutineonthePL/SQLVirtualMachine.InNATIVEmode,thePL/SQLcodeiscompiledtomachinecode,whichisdirectlytranslatedtotheplatform-specific.Atruntime,themachinecodeisexecutednativelybythePL/SQLVirtualMachine.Therealnativecompilationmodecanbesetatsystemlevel,sessionlevel,andobjectlevel.Anativelycompiledprogramunitcancallaninterpretedprogramandviceversa.
SelectingtheappropriatecompilationmodeDuringthedatabasedevelopmentphase,thePL/SQLprogramunitstendtogetrecompiledfrequently.Atthisstage,youwouldwanttohavethefastercompilationofprograms.Therefore,youcanchoosetocompiletheprogramunitsininterpretedmode.
Oncethedatabaseisdeployedforproduction,andhasfewerchancesoffrequentrecompilation,youcanchoosenativecompilation.PL/SQLnativecompilationenhancestheruntimeperformanceoftheprogramunits.Computation-intensiveprogramsareexpectedtobenefitmostfromthenativecompilationmethod.TheperformancegainswillbelessiftheprogramisfrequentlyswitchingthecontextbetweentheSQLandPL/SQLengines.
Oracleallowshavingamixofprogramunitswithdifferentcompilationmodes.However,keepinmindthatifanativelycompiledunitinvokesaninterpretedunit,theprogramexecutionperformancewillbeimpacted.
SettingthecompilationmodeThecompilationmethodissetusingthePLSQL_CODE_TYPEparameter.TheadmissiblevaluesfortheparameterareINTERPRETEDandNATIVE.ThedefaultvalueoftheparameterisINTERPRETED.TheparametercanbesetusingtheALTERSYSTEMorALTERSESSIONstatement.
AttheSYSTEMlevel:
ALTERSYSTEMSETPLSQL_CODE_TYPE=[NATIVE|INTERPRETED]
AttheSESSIONlevel:
ALTERSESSIONSETPLSQL_CODE_TYPE=[NATIVE|INTERPRETED]
Alternatively,youcanalsocompileaparticularPL/SQLprogramunitinthenativeorinterpretedmethodbyrecompilinganobjectusingtheALTER<objecttype>statement.Forexample,thefollowingscriptwillrecompileaprocedurewithanewvalueforPLSQL_CODE_TYPE,butreusingtheexistingcompilationparameters:
ALTERPROCEDURE<procedurename>COMPILEPLSQL_CODE_TYPE=NATIVEREUSE
SETTINGS
/
ThePL/SQLprogramunitsretaintheircompilationmodesettingunlesstheyarerecompiledinadifferentcompilationmode.
QueryingthecompilationsettingsThecompilationmodeofanobjectcanbequeriedfromthedatadictionaryview:[USER|DBA|ALL]_PLSQL_OBJECT_SETTINGS.Thisdictionaryviewcontainsthecompilationsettingsforstandaloneprogramunits,packagespecification,packagebody,andpackagedsubprograms:
/*DescribethestructureofUSER_PLSQL_OBJECT_SETTINGS*/
SQL>DESCUSER_PLSQL_OBJECT_SETTINGS
NameNull?Type
--------------------------------------------------------
NAMENOTNULLVARCHAR2(30)
TYPEVARCHAR2(12)
PLSQL_OPTIMIZE_LEVELNUMBER
PLSQL_CODE_TYPEVARCHAR2(4000)
PLSQL_DEBUGVARCHAR2(4000)
PLSQL_WARNINGSVARCHAR2(4000)
NLS_LENGTH_SEMANTICSVARCHAR2(4000)
PLSQL_CCFLAGSVARCHAR2(4000)
PLSCOPE_SETTINGSVARCHAR2(4000)
ORIGIN_CON_IDNUMBER
CompilingaprogramunitfornativeorinterpretedcompilationInthissection,let’scheckhowaPL/SQLprogramunitcanbecompiledindifferentcompilationmodesattheobjectlevel.
1. Showthecompilationmodeofthesession:
/*Connectassysdba*/
connectsys/oracleassysdba
/*DisplaycurrentsettingofparameterPLSQL_CODE_TYPE*/
SELECTname,
value
FROMv$parameter
WHEREname='plsql_code_type'
/
NAMEVALUE
----------------------------------------
plsql_code_typeINTERPRETED
2. Createastandalonefunction,whichcurrentlygetscompiledintheINTERPRETEDmode:
/*Createafunction*/
CREATEORREPLACEFUNCTIONf_get_caps(p_nameVARCHAR2)
RETURNVARCHAR2
IS
BEGIN
RETURNUPPER(p_name);
END;
/
Functioncreated.
3. VerifythecompilationmodeoftheF_GET_CAPSfunction:
/*QuerythecompilationsettingsforthefunctionF_GET_CAPS*/
SELECTname,
type,
plsql_code_type,
plsql_optimize_levelOPTIMIZE
FROMUSER_PLSQL_OBJECT_SETTINGS
WHEREname='F_GET_CAPS'
/
NAMETYPEPLSQL_CODE_TYPEOPTIMIZE
-------------------------------------------------
F_GET_CAPSFUNCTIONINTERPRETED2
4. Recompilethefunctionusingnativemode:
/*Explicitlycompilethefunction*/
ALTERFUNCTIONf_get_capsCOMPILEPLSQL_CODE_TYPE=NATIVE
/
Functionaltered.
5. ConfirmthechangeinthecompilationmodeoftheF_GET_CAPSfunction:
/*QuerythecompilationsettingsforthefunctionF_GET_CAPS*/
SELECTname,
type,
plsql_code_type,
plsql_optimize_levelOPTIMIZE
FROMUSER_PLSQL_OBJECT_SETTINGS
WHEREname='F_GET_CAPS'
/
NAMETYPEPLSQL_CODE_TYPEOPTIMIZE
----------------------------------------------
F_GET_CAPSFUNCTIONNATIVE2
6. YoucanalsoverifythegenerationofasharedlibraryfortheF_GET_CAPSfunctionbyqueryingtheNCOMP_DLL$dictionaryview.ThelibraryisstoredasaBLOBintheNCOMP_DLL$view:
connectsys/systemassysdba
SELECTobject_name,
dllname
FROMncomp_dll$,dba_objects
WHEREobj#=object_id
ANDowner='SCOTT'
/
OBJECT_NAMEDLLNAME
--------------------------------------------------------
F_GET_CAPS465F4745545F434150535F5F53434F54545F5F465F5F3934303837
Thelibraryisautomaticallydeletedfromthedictionaryiftheobjectisrecompiledwithadifferentcompilationmode.
RecompilingadatabaseforaPL/SQLnativeorinterpretedcompilationYoucancompileallthePL/SQLprogramunitsinadatabasefrominterpretedtonativecompilationmodeandviceversa.OracleenablesthebulkcompilationofthePL/SQLprogramunitsthroughinbuiltscripts:dbmsupnv.sqlanddbmsupgin.sql.Thedbmsupgnv.sqlscriptcompilesalltheprogramunitsusingnativecompilationmodewhiledbmsupgin.sqlcompilesalltheprogramunitsininterpretedmode.Thefollowingpointsshouldbeconsideredduringtheplanningstage:
Choosetherightcompilationmode—theselectionoftheappropriatecompilationmodeisthekeytoensurebettercodeperformance.SYSDBAorauserwithDBAprivilegescanruntherecompilationprocedure.IftheuserisprotectedthroughtheOracleDatabaseVaultoption,theusermustbegrantedtheDV_PATCH_ADMINrole.Objecttypespecificationscannotbecompiledinnativecompilationmode.SkipthePL/SQLpackagespecificationswithoutanexecutablesectionfromnativecompilation.YoucannotexcludeanyPL/SQLprogramunitwhilecompilinganentiredatabaseforinterpretedcompilation.
Thefollowingstepsshowhowtocompileadatabasefornativeorinterpretedcompilationmode:
1. Shutdownthedatabase—youmustshutdowntheOracleDatabaseandtheTNSlistener.Ensurethatallconnectionstothedatabasefromtheapplicationtierareterminated.
2. SetPLSQL_CODE_TYPEasNATIVEorINTERPRETEDintheparameterfile.Ifyouareusingaserverparameterfile(spfile),youcanmodifytheparametervaluebeforeadatabaseisshutdown,orafterthedatabaseisstarted.Thedbmsupgnv.sqlscriptalsosetsPLSQL_CODE_TYPEbeforecompilingthePL/SQLprogramunits:
/*Alterthesystemtosetthenewcompilationmode*/
SQL>ALTERSYSTEMSETPLSQL_CODE_TYPE=NATIVESCOPE=SPFILE
/
Systemaltered.
3. VerifyandsetPLSQL_OPTIMIZE_LEVELas2(orhigher).4. Startthedatabaseintheupgrademode:
SQL>connectsys/oracleassysdba
Connectedtoanidleinstance.
/*Startupinupgrademode*/
SQL>startupupgrade
ORACLEinstancestarted….
...
Databasemounted.
Databaseopened.
IfyouareworkinginanOracleDatabase12cMultitenantarchitecture,youhavetoopenthepluggabledatabaseintheUPGRADEandRESTRICTEDmode:
ALTERPLUGGABLEDATABASE<pdbname>OPENUPGRADERESTRICTED
/
5. ConnectedastheSYSuser,executethedbmsupgnv.sqlscript:
/*Executetherecompilationscript*/
SQL>@ORACLE_HOME/rdbms/admin/dbmsupgnv.sql…
...
#######################################################################
#######################################################################
dbmsupgnv.sqlcompletedsuccessfully.AllPL/SQLprocedures,
functions,typebodies,triggers,andtypebodiesobjectsinthe
databasehavebeeninvalidatedandtheirsettingssettonative.
Shutdownandrestartthedatabaseinnormalmodeand
runutlrp.sqltorecompileinvalidobjects.
#######################################################################
#######################################################################
Thedbmsupgnv.sqlanddbmsupgin.sqlscriptscreateaPL/SQLpackagesys.dbmsncdbwithtwosubprograms:SETUP_FOR_NATIVE_COMPILEandSETUP_FOR_INTERPRETED_COMPILE.Thedbmsupgnv.sqlinvolvesSETUP_FOR_NATIVE_COMPILEwithausersuppliedinput.TheinputshouldbeTRUEtocompileallfunctions,procedures,packagebodies,triggers,andtypebodies.IftheinputisFALSE,packageandobjecttypespecificationsarealsoincludedintheprocess.IfthePL/SQLpackagespecificationscontainanexecutablesection,youshouldprovidetheinputasFALSE.
ThescriptmodifiesthecompilationofallthePL/SQLprogramstonativebutinvalidatesthematthesametime.
6. ShutdownandrestartthedatabaseintheNORMALmode:
/*Shutdownandstartupthedatabase*/
SQL>shutdownimmediate
Databaseclosed.
Databasedismounted.
ORACLEinstanceshutdown.
SQL>startup
ORACLEinstancestarted….
...
Databasemounted.
Databaseopened.
7. Executetheutlrp.sqlscripttorecompiletheinvalidatedobjects.Althoughtheobjectsthathavebeeninvalidatedgetautomaticallyrecompiledwhenevertheyaresubsequentlyinvoked,itisrecommendedthatyoucompileandrevalidatetheobjects
toreducerecompilationlatencies.
TipItisrecommendedthatyourunutlrp.sqlinarestrictedsession.Anyconnectionrequestfromtheapplicationservicesoradatabasesessionmayleadtodeadlocks.
SQL>ALTERSYSTEMENABLERESTRICTEDSESSION
/
Systemaltered.
SQL>@ORACLE_HOME\rdbms\admin\utlrp.sql
Thescriptrecompilesalltheprogramunitsthathaveadefaultcompilationmode.Youcanrerunthescriptanynumberoftimestorecompiletheinvalidatedobjects.TherecompilationoperationcanbeoptimizedthroughparallelizationwhereinthedegreeofparallelismisselectedbasedonCPU_COUNTandPARALLEL_THREADS_PER_CPU.
Fortroubleshootinganddiagnosis,youcanusethefollowingqueries:
Querytheinvalidobjects:
SELECTo.OWNER,
o.OBJECT_NAME,
o.OBJECT_TYPE
FROMDBA_OBJECTSo,DBA_PLSQL_OBJECT_SETTINGSs
WHEREo.OBJECT_NAME=s.NAME
ANDo.STATUS='INVALID'
/
QuerythecountofthePL/SQLprogramsineachcompilationmode:
SELECTTYPE,
PLSQL_CODE_TYPE,
COUNT(*)
FROMDBA_PLSQL_OBJECT_SETTINGS
WHEREPLSQL_CODE_TYPEISNOTNULL
GROUPBYTYPE,PLSQL_CODE_TYPE
ORDERBYTYPE,PLSQL_CODE_TYPE
/
NoteThePL/SQLobjectswithNULLplsql_code_typeareOracle’sinternalobjects.
QuerythenumberofthePL/SQLobjectsthatarecompiledsofarusingutlrp.sql:
SELECTCOUNT(*)FROMUTL_RECOMP_COMPILED
/
8. Disabletherestrictedsession:
SQL>ALTERSYSTEMDISABLERESTRICTEDSESSION
/
Systemaltered.
Ifyouwanttorollbackthecompilationmodetointerpreted,youcanfollowthesamesteps,andreplacedbmsupgnv.sqlwiththedbmsupgin.sqlscript.
TuningPL/SQLcodeWehavejustdiscussedtwokeyfeaturesintheperformancemanagementspace.ThePL/SQLcodeoptimizationandcompilationcansignificantlyimproveruntimeperformance.Apartfromthecodeoptimizationtechniques,thereareseveralefficientcodingpracticesthatmayimpactoverallPL/SQLperformance.PL/SQLperformancemanagementisoftenregardedaslesstedious,whencomparedtothedatabasetuningexercisebecausetheareaofoperationisaprogramunitanddoesn’trequiretheinstancetoberestarted.Inthissection,wewilldiscusssomeoftheselectivebutkeyfeaturestoimprovePL/SQLcodingpracticesforbetterperformance.
BuildsecureapplicationsusingbindvariablesItishighlyencouragedtousebindvariablesinSQLstatementswhilebuildingrobustdatabaseapplications.BindvariablesreducetheparsingoverheadbyenablinganSQLstatementtobeexecutedusingitsalreadyparsedimagestoredinthesharedSQLareaofthedatabasememory.
EverySQLstatementexecutedbytheSQLengineisparsed,optimized,andexecuted.OnlyaftertheSQLstatementisexecutedistheresultfetchedanddisplayedtotheuser.TheSQLexecutionstepsarebrieflydescribed,asfollows:
GenerateahashvaluefortheSQLstatement.Lookforamatchinghashvalueofcachedcursorsinthesharedpool.Ifthematchisnotfound,Oraclecontinueswiththestatementparsingandoptimizationstages.Thisishardparsing.ItisaCPU-intensiveoperationandinvolvescontentionforlatchesinthesharedSQLarea.Ifthematchisfound,reusethecursorandreduceparsingtoaprivilegecheck.Thisisasoftparse.Thereafter,withoutneedingfurtheroptimization,theexplainplanisretrievedfromthelibrarycache,andtheSQLqueryisexecuted.
NoteOracleDatabase12cintroducedadaptivequeryoptimization,whichallowstheoptimizertore-optimizetheexistingexplainplansuponsubsequentexecutionsofanSQLquery.
Theresultsetisfetched.
Inanenterpriseapplication,manySELECTstatementsortransactionalstatements(INSERT,UPDATE,orDELETE)aresimilarinstructurebuttheyrunwithdifferentpredicatevalues.ThehashesfortwoofthesameSQLstatementswithdifferentvalueswillneverbethesame,thusresultinginahardparse.Ahardparse,beinganon-scalableexpensiveoperation,degradestheapplicationperformance.Theonlywaytogetridoftheproblemistoencouragesoftparsingbymaximizingtheuseofcachedcursorsandassociatedexplainplans.
Theuseofbindvariablespromotessoftparsing.Abindvariableisasubstitutionvariablethatactsasaplaceholderfortheliteralvalues.BindvariablesenableanSQLstatementtoappearthesameevenaftermultiplerunswithdifferentinputvalues.ThisreduceshardparsingandtheexistingplansinthelibrarycachecanbeusedtooptimizethecurrentSQLstatements.
TipAvoidusinghard-codedliteralsinSQLqueriesandPL/SQLprograms.
Forexample,thefollowingSELECTquerywillhavethesamehashvalueforthedifferentvaluesofemployeeids:
/*SelectEMPtablewithabindvariable*/
SELECTename,
deptno,
sal
FROMemp
WHEREempno=:empid
/
OraclePL/SQLsupportstheuseofbindvariables.Allreferencestoablockvariableorprogramargumentaretreatedasabindvariable.InthecaseofadynamicSQL,eitherusingDBMS_SQLorEXECUTEIMMEDIATE,youmustusebindvariables.BindvariableshelpdynamicSQLintwoways.Firstitimprovesthecodeperformance.Secondly,itreducestheriskofSQLinjectionbycoveringthevulnerableareas.Let’sconductasmallillustrationtoseethebenefitsofbindvariablesinPL/SQL.
ThefollowingPL/SQLblockfindsthecountofdistinctobjecttypeaccessiblebytheSCOTTuser.ItexecutestheSELECTqueryusingEXECUTEIMMEDIATE.Inordertogettheaccurateresults,wewillflushthesharedpool:
connectsys/oracleassysdba
ALTERSYSTEMFLUSHSHARED_POOL
/
connectscott/tiger
SETSERVEROUTON
/*StartthePL/SQLblock*/
DECLARE
/*Localblockvariables*/
l_countNUMBER;
l_stmtVARCHAR2(4000);
clock_inNUMBER;
clock_outNUMBER;
TYPEv_obj_typeisTABLEOFvarchar2(100);
l_obj_typev_obj_type:=v_obj_type('TYPE','PACKAGE','PROCEDURE',
'TABLE','SEQUENCE','OPERATOR','SYNONYM');
BEGIN
/*Capturethestarttime*/
clock_in:=DBMS_UTILITY.GET_TIME();
/*FORlooptoiteratethecollections*/
FORIINl_obj_type.first..l_obj_type.last
LOOP
l_stmt:='SELECTcount(*)
FROMall_objects
WHEREobject_type='||''''||l_obj_type(i)||'''';
EXECUTEIMMEDIATEl_stmtINTOl_count;
ENDLOOP;
/*Capturetheendtime*/
clock_out:=DBMS_UTILITY.GET_TIME();
DBMS_OUTPUT.PUT_LINE('Executiontimewithoutbind
variables:'||TO_CHAR(clock_out-clock_in));
END;
/
Executiontimewithoutbindvariables:948
PL/SQLproceduresuccessfullycompleted.
Now,we’llrewritetheabovePL/SQLblockusingbindvariables:
connectsys/oracleassysdba
ALTERSYSTEMFLUSHSHARED_POOL
/
connectscott/tiger
SETSERVEROUTON
/*StartthePL/SQLblock*/
DECLARE
/*Localblockvariables*/
l_countNUMBER;
l_stmtVARCHAR2(4000);
clock_inNUMBER;
clock_outNUMBER;
TYPEv_obj_typeisTABLEOFvarchar2(100);
l_obj_typev_obj_type:=v_obj_type('TYPE','PACKAGE','PROCEDURE',
'TABLE','SEQUENCE','OPERATOR','SYNONYM');
BEGIN
/*Capturethestarttime*/
clock_in:=DBMS_UTILITY.GET_TIME();
/*FORlooptoiteratethecollection*/
FORIINl_obj_type.first..l_obj_type.last
LOOP
/*BuildtheSELECTstatementbyusingbindvariable*/
l_stmt:='SELECTcount(*)
FROMall_objects
WHEREobject_type=:p1';
/*UsedynamicSQLtoexecutetheSELECTstatement*/
EXECUTEIMMEDIATEl_stmtINTOl_countUSINGl_obj_type(i);
ENDLOOP;
clock_out:=DBMS_UTILITY.GET_TIME();
DBMS_OUTPUT.PUT_LINE('Executiontimewithbind
variables:'||TO_CHAR(clock_out-clock_in));
END;
/
Executiontimewithbindvariables:121
PL/SQLproceduresuccessfullycompleted.
Theblockwiththebindvariablesgetsexecutedatleast8timesfasterthantheonewhichusesliteralsintheSQLqueryinsidethePL/SQLblock.ThereasonfortheperformancegainisthesoftparsingoftheSELECTstatement.
Inthecaseoflegacyapplicationsoraccessprotectedapplications,youmightfacedifficultiesinmodifyingthecodetoincludethebindvariables.Oraclemakesthisdauntingtaskeasierbycontrollingthecursorsharingbehaviorthroughaswitch.YoucansetCURSOR_SHARINGparametertoEXACTorFORCEtosharethecursorsacrossthesessionsinadatabaseinstance.IftheparameterissettoEXACT,onlytheSQLstatementsthathaveexactlythesamestructureandparameterswillbeshared.IftheparameterissettoFORCE,thenOracleattemptstosubstitutealltheliteralsinaquerywithsystem-generatedbindvariables.Bydefault,theparametervalueissettoEXACT.Cursorsharinggreatlyimprovestheperformance.Atthesametime,forcedcursorsharinginvolvesextraeffortinsearchingforthesamecursorinthesharedpool.
NoteTheSIMILARvalueofCURSOR_SHARINGhasbeendeprecatedinOracleDatabase12c.
CallparametersbyreferenceAPL/SQLprograminvocationcanpassaparametereitherbyitsvalueorbyreference.ArgumentsintheINmodearepassedbyreference(thedefault)whiletheargumentsintheOUTandINOUTmodesarepassedbyvalue.Inthecaseofpassbyvaluemethod,theparametervaluebeforetheinvocationhastobestoredinatemporaryvariable.Thistemporaryvariableisamemoryvariableandisusedtoassignthevaluebacktotheparameter,ifthesubprogramcallendsinanunhandledexception.IfthePL/SQLprogramacceptscompositedatatypesandcomplexvariablesintheOUTandINOUTmodes,copyingandmaintainingthetemporaryvariablecancauseaperformanceoverhead,therebyslowingdowntheprogramexecution.
OraclerecommendsthatyouspecifytheNOCOPYhintforthepassbyvalueparameters.AparameterwiththepassmodeasOUTNOCOPYorINOUTNOCOPYispassedbyreference,thusavoidingtheoverheadofmaintainingatemporaryvariable.Forsimpledatavalues,whicharegenerallysmall,thegainwillbenegligible.
AvoidinganimplicitdatatypeconversionOracleconvertsthedatatypestoacompatibletypeduringtheoperationslikeassignment,predicateswithvaluecomparison,orpassingparameterstosubprograms.Thisisanimplicitactivitythatfollowsadatatypeprecedencetoconvertthedatatypes.However,itmaycauseanoverheadwhenexecutingacriticalprogram.Thefollowingarethebestpracticesthatcanreducetheimplicitdatatypeconversionintheprograms:
UnderstandthatSQLdatatypesandPL/SQLdatatypeshavedifferentinternalrepresentations.YoushouldexplicitlyconverttheSQLtypevariablestoPL/SQLtypesandthenusethoseinanexpression.Forexample,PLS_INTEGERisaPL/SQLdatatypethatusesmachinearithmetictospeedupcomputeintensiveoperations.IfNUMBERtypevariablesareusedinanexpression,Oracleuseslibraryarithmetic,andtherefore,therearenoperformancegains.Avariablegettingassignedtoatablecolumnshouldbeofthesamedatatypetoavoidanimplicitdatatypeconversion.Asabestpractice,declarethevariableswiththe%TYPEattribute.Similarly,arecordcanbedeclaredwiththe%ROWTYPEattribute.Suchvariabledeclarationsalwaysremainsynchronizedwiththedatabasecolumns,improvetheprogram’sscalability,andreducehumanerrors.Considerthefollowingdeclarations:
empnameemp.ename%type
typeemp_recisrecordofemp%rowtype;
CURSORcIS
SELECTprod_id,prod_code,prod_name
FROMproducts;
prod_recc%rowtype;
UsetheSQLconversionfunctiontoconverttheto-beassignedvariabletothetargetvariable’sdatatype.SomeoftheconversionfunctionsareTO_CHAR,TO_NUMBER,TO_DATE,TO_TIMESTAMP,CAST,andASCIISTR.PassavariableofcorrectdatatypewhileinvokingthePL/SQLprogramunitswithparameters.YoucanalsoincludeoverloadedsubprogramsinaPL/SQLpackagethatacceptstheparametersofthedifferentdatatypes.Youcaninvokethepackagedsubprogramthatbestmatchestheavailablesetofvariables.Forexample,thefollowingpackagehastwooverloadedfunctions.Youcaninvokeeitherofthetwodependingonthetypeofvariablesavailable:
CREATEORREPLACEPACKAGEpkg_sumAS
FUNCTIONp_sum_series(p_termPLS_INTEGER,p_factorPLS_INTEGER)
RETURNPLS_INTEGER;
FUNCTIONp_sum_series(p_termNUMBER,p_factorNUMBER)
RETURNNUMBER;
END;
/
UnderstandingtheNOTNULLconstraintAblockvariablecanbedeclaredNOTNULLatthetimeofthedeclaration.OracleperformsthenullabilitytesteverytimeavalueisassignedtotheNOTNULLvariable.InlargePL/SQLprogramunits,thenullabilitycheckcanbeanoverheadandimpactthePL/SQLblock’sruntimeperformance.Instead,itisadvisedtohaveanexplicitnullabilitycheckforthevariableintheexecutablesectionoftheblock.
ThefollowingPL/SQLprogramcomparestheperformanceofaNOTNULLvariableandnullablelocalvariable:
/*EnabletheSERVEROUTPUTtodisplayblockresults*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
l_nn_numNUMBERNOTNULL:=0;
l_numNUMBER:=0;
clock_inNUMBER;
clock_outNUMBER;
BEGIN
/*Capturethestarttime*/
clock_in:=DBMS_UTILITY.GET_TIME();
/*Starttheloop*/
FORIIN1..1000000
LOOP
l_nn_num:=l_nn_num+i;
ENDLOOP;
clock_out:=DBMS_UTILITY.GET_TIME();
/*Computethetimedifferenceanddisplay*/
DBMS_OUTPUT.PUT_LINE('TimeforNOTNULL:'||TO_CHAR(clock_out-clock_in));
/*Capturethestarttime*/
clock_in:=DBMS_UTILITY.GET_TIME();
/*Starttheloop*/
FORIIN1..1000000
LOOP
l_num:=l_num+i;
ENDLOOP;
clock_out:=DBMS_UTILITY.GET_TIME();
/*Computethetimedifferenceanddisplay*/
DBMS_OUTPUT.PUT_LINE('TimeforNULL:'||TO_CHAR(clock_out-clock_in));
END;
/
TimeforNOTNULL:111
TimeforNULL:76
PL/SQLproceduresuccessfullycompleted.
IntheprecedingPL/SQLblock,thenullablevariableoutperformstheNOTNULLvariablebyoneandahalftimes.Thereasonforthisperformancegainisthereductioninthenumberofnullabilitychecks.
SelectionofanappropriatenumericdatatypeThePLS_INTEGERdatatypeisapartoftheNUMBERdatatypefamily.Mostofthenumberorintegerdatatypesaregenericonesandthereasonbehindthisistosupportcodeportability.However,PLS_INTEGERisspecificallydesignedforperformance.ItwasintroducedinOracleDatabaseRelease7tospeedupthecomputation-intensiveoperationsthroughnativemachinearithmeticinsteadoflibraryarithmetic.
ThefollowingPL/SQLblockcomparestheperformanceofthePLS_INTEGERandNUMBERvariables:
/*EnabletheSERVEROUTPUTtodisplayblockresults*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
l_pls_intPLS_INTEGER:=1;
l_numNUMBER:=1;
l_factorPLS_INTEGER:=2;
clock_inNUMBER;
clock_outNUMBER;
BEGIN
/*Capturethestarttime*/
clock_in:=DBMS_UTILITY.GET_TIME();
/*Beginthelooptoperformamathematicalcalculation*/
FORIIN1..10000000
LOOP
/*Themathematicaloperationincrementsavariablebyone*/
l_num:=l_num+l_factor;
ENDLOOP;
clock_out:=DBMS_UTILITY.GET_TIME();
/*Displaytheexecutiontimeconsumed*/
DBMS_OUTPUT.PUT_LINE('TimebyNUMBER:'||TO_CHAR(clock_out-clock_in));
/*Capturethestarttime*/
clock_in:=DBMS_UTILITY.GET_TIME();
/*Beginthelooptoperformamathematicalcalculation*/
FORJIN1..10000000
LOOP
/*Themathematicaloperationincrementsavariablebyone*/
l_pls_int:=l_pls_int+l_factor;
ENDLOOP;
clock_out:=DBMS_UTILITY.GET_TIME();
/*Displaythetimeconsumed*/
DBMS_OUTPUT.PUT_LINE('TimebyPLS_INTEGER:'||TO_CHAR(clock_out-
clock_in));
END;
/
TimebyNUMBER:231
TimebyPLS_INTEGER:69
PL/SQLproceduresuccessfullycompleted.
TheperformanceofthePLS_INTEGERvariableisatleastthreetimesbetterthanaNUMBERvariable.AnarithmeticexpressionhavingamixofthePLS_INTEGERandNUMBERtypevariableswilluselibraryarithmeticandnoperformancegainswillbeobtained.
PLS_INTEGERisa32-bitdatatypethatcanstorevaluesintherangeof-2147483648to2147483647.Itacceptsintegervaluesonly.IfafloatingvalueisassignedtoPLS_INTEGER,itisroundedtothenearestinteger.IfthePLS_INTEGERprecisionrangeisviolated,OracleraisesanORA-01426:numericoverflowexception.Toresolvesuchscenarios,Oracle11gintroducedanewsubtypeofPLS_INTEGER,whichisknownasSIMPLE_INTEGER.TheSIMPLE_INTEGERdatatypehasthesamerangeasthatofPLS_INTEGER,butinthecaseofnumericoverflows,itisautomaticallysetto-2147483648insteadofraisinganexception.AstheoverflowcheckissuppressedforSIMPLE_INTEGER,itisfasterthanPLS_INTEGER.
NoteSIMPLE_INTEGERisaNOTNULLdatatype;therefore,alllocalvariablesmustbeinitializedordefaultedtoadefinitivevalue.
ThefollowingPL/SQLanonymousblockdeclaresaSIMPLE_INTEGERvariableanddefaultsitto2147483646,thatis,thelastvalueintheprecisionrange.Intheprogrambody,thevariableisincrementedby1.Let’scheckwhathappens:
/*EnabletheSERVEROUTPUTtodisplayblockresults*/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
l_simpleSIMPLE_INTEGER:=2147483646;
BEGIN
/*Incrementthevariableby1*/
l_simple:=l_simple+1;
DBMS_OUTPUT.PUT_LINE('After1stincrement:'||l_simple);
/*Re-Incrementthevariableby1*/
l_simple:=l_simple+1;
DBMS_OUTPUT.PUT_LINE('After2ndincrement:'||l_simple);
EXCEPTION
WHENOTHERSTHEN
DBMS_OUTPUT.PUT_LINE('NumericOverflowexceptionoccurred');
END;
/
After1stincrement:2147483647
After2ndincrement:-2147483648
PL/SQLproceduresuccessfullycompleted.
BulkprocessinginPL/SQLBulkdataprocessingisoneofthekeyfeaturesinperformancemanagement.BulkSQLisafeaturethatreducescontextswitchesbetweentheSQLandPL/SQLprocessingengines.OneofthebiggestbenefitsofPL/SQLdevelopmentisitsseamlessintegrationwiththeSQLlanguage.TheSQLstatementscandirectlyappearinthePL/SQLprogrambody.InaPL/SQLunitwiththeSQLstatementsandPL/SQLconstructs,thePL/SQLengineandSQLenginecommunicatethroughacontextswitch.ThePL/SQLengineswitchestheprogramcontexttotheSQLenginetoexecutetheSQLstatementsandgettheresult.Thefrequentback-and-forthcontextswitchingbetweentheprocessingenginescausesasevereoverheadandslowsdowntheprogramexecution.Therow-by-rowprocessingofrecordsisquiteslowcomparedtobulkprocessing.
OracleimplementsbulkoperationsthroughtheBULKCOLLECTclauseandtheFORALLstatement.TheBULKCOLLECTclauseretrievesmultiplerecordsinasinglefetchwhiletheFORALLstatementcanprocessmultipleDMLstatementsingroupsratherthanrowbyrow.Inmanyimplementations,theperformancegainsbytheuseofbulkprocessingfeatureshavebeenphenomenal.
BULKCOLLECTYoucanuseBULKCOLLECTin:
TheSELECT…INTOstatementTheRETURNINGINTOclausewiththeUPDATEorDELETEstatementTheFETCHINTOclausewithanexplicitcursor
Thebulkcollectfeaturedependslargelyoncollectionsandcanbeusedwithallthethreeformsofcollections,thatis,associativearrays,nestedtables,andvarrays.Multiplerecordscanbefetchedintoacollectioninasinglefetch.Thisreducesthenumberofthecontextswitchesbetweenthetwoprocessingengines.Duringthefetchoperation,thecollectionvariablesgetdenselypopulated.Inthecaseofnorowsbeingfetched,thecollectionsareleftemptyresultinginanemptycollection.
NoteBulkoperationsareaCPU-intensiveoperation.Theycannotbeparallelized.
UntilOracleDatabase9i,BULKCOLLECTcouldbeusedonlywithstaticSQLstatements,butstartingwithOracleDatabase10g,itcanbeusedindynamicSQLstatementstoo.
TheCREATETABLEscriptcreatesthetesttablewiththesampledatafromtheALL_OBJECTSdictionaryviewtobeusedinthisillustration.TheALL_OBJECTSdictionaryviewcontainsdetailsoftheschemaobjects.Duringourillustration,wewillworkwiththeobjectid,objecttype,andobjectnamecolumnsofthetable:
CREATETABLElocal_objectsAS
SELECT*FROMall_objects
/
/*Querytherecordcount*/
SELECTCOUNT(*)
FROMlocal_objects
/
COUNT(*)
----------
73673
ThefollowingPL/SQLblockopensacursor,fetchesrowbyrow,andcountsthenumberofproceduresthatcanbeaccessedbytheSCOTTuser:
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*LocalPL/SQLvariables*/
obj_idlocal_objects.object_id%TYPE;
obj_typelocal_objects.object_type%TYPE;
obj_namelocal_objects.object_name%TYPE;
counterNUMBER;
clock_inNUMBER;
clock_outNUMBER;
/*Cursortofetchtheobjectdetails*/
CURSORcIS
SELECTobject_id,object_type,object_name
FROMlocal_objects;
BEGIN
/*Capturethestarttime*/
clock_in:=DBMS_UTILITY.GET_TIME();
OPENc;
LOOP
FETCHcINTOobj_id,obj_type,obj_name;
EXITWHENc%NOTFOUND;
/*Countthenumberofproceduresinthetesttable*/
IFobj_type='PROCEDURE'THEN
counter:=counter+1;
ENDIF;
ENDLOOP;
CLOSEc;
/*Capturetheendtime*/
clock_out:=DBMS_UTILITY.GET_TIME();
DBMS_OUTPUT.PUT_LINE('Timetakeninrowfetch:'||to_char(clock_out-
clock_in));
END;
/
Timetakeninrowfetch:369
PL/SQLproceduresuccessfullycompleted.
Therow-by-rowfetchtook369hsectogetexecuted.Therewere73673contextswitchesmadebetweenthePL/SQLandSQLengines.Now,let’sapplythebulkfetchtechniquestotheprecedingblock,andchecktheperformancegains:
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Declarethelocalrecordandtablecollection*/
TYPEobj_recISRECORD
(obj_idlocal_objects.object_id%TYPE,
obj_typelocal_objects.object_TYPE%TYPE,
obj_namelocal_objects.object_name%TYPE);
TYPEobj_tabISTABLEOFobj_rec;
t_all_objsobj_tab;
counterNUMBER;
clock_inNUMBER;
clock_outNUMBER;
BEGIN
/*Capturethestarttime*/
clock_in:=DBMS_UTILITY.GET_TIME();
/*Selectquerytobulkfetchmulti-recordsetinnestedtable
collection*/
SELECTobject_id,object_TYPE,object_name
BULKCOLLECTINTOt_all_objs
FROMlocal_objects;
/*Loopthroughthecollectiontocountnumberofprocedures*/
FORIINt_all_objs.FIRST..t_all_objs.LAST
LOOP
IF(t_all_objs(i).obj_type='PROCEDURE')THEN
counter:=counter+1;
ENDIF;
ENDLOOP;
/*Capturetheendtime*/
clock_out:=DBMS_UTILITY.GET_TIME();
DBMS_OUTPUT.PUT_LINE('Timetakeninbulkfetch:'||to_char(clock_out-
clock_in));
END;
/
Timetakeninbulkfetch:35
PL/SQLproceduresuccessfullycompleted.
Well,thebulkSQLisaround10timesfasterthantheusualfetchoperation.ThereasonisthattherewasonlyonecontextswitchmadebetweentheSQLandPL/SQLengines.Notethatthenestedtablecollectionvariableisnotrequiredtobeinitializedforbulkoperations.
NoteTheBULKCOLLECToperationdoesnotraisetheNO_DATA_FOUNDexception.
BulkprocessingisaCPU-intensiveoperation,andfetchingintoacollectionconsumesyoursessionmemory.Ifthebulkcollectfetchesalargenumberofrowsandthesessionmemoryisnotlargeenough,youmightexperienceahungsessionoranabnormaltermination.Toresolvesuchcases,OracleprovidestheLIMITclausetocontrolthenumberofrecordsretrievedinasinglefetchoperation.ThefollowingPL/SQLblockusestheLIMITclausetocontrolthenumberofrecordsfetchedduringtheFETCHoperation:
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Localblockvariables-objecttyperecordandnestedtable*/
TYPEobj_recISRECORD
(obj_idlocal_objects.object_id%TYPE,
obj_typelocal_objects.object_TYPE%TYPE,
obj_namelocal_objects.object_name%TYPE);
TYPEobj_tabistableofobj_rec;
t_all_objsobj_tab;
counterNUMBER;
p_rec_limitNUMBER:=100;
clock_inNUMBER;
clock_outNUMBER;
/*CursortofetchobjectdetailsfromLOCAL_OBJECTS*/
CURSORCIS
SELECTobject_id,object_TYPE,object_name
FROMlocal_objects;
BEGIN
/*Capturethestarttime*/
clock_in:=DBMS_UTILITY.GET_TIME();
/*Openthecursor*/
OPENc;
LOOP
/*Bulkfetchtherecordsbyspecifyingthelimit*/
FETCHcBULKCOLLECTINTOt_all_objsLIMITp_rec_limit;
EXITWHENc%NOTFOUND;
/*FORlooptocounttheprocedures*/
FORIINt_all_objs.FIRST..t_all_objs.LAST
LOOP
IF(t_all_objs(i).obj_type='PROCEDURE')THEN
counter:=counter+1;
ENDIF;
ENDLOOP;
t_all_objs.DELETE;
ENDLOOP;
CLOSEc;
clock_out:=DBMS_UTILITY.GET_TIME();
DBMS_OUTPUT.PUT_LINE('Timetakenincontrolledfetch:'||to_char
(clock_out-clock_in));
END;
/
Timetakenincontrolledfetch:94
PL/SQLproceduresuccessfullycompleted.
Acontrolledbulkoperation,limitedto100recordsperbulkfetch,took94hsectogetexecuted,whichisstill4timesbetterthantherow-by-rowfetchoperation.Thistimetheprogrammakes737contextswitchesbetweenthePL/SQLandSQLengines.
FORALLMorethaniterative,FORALLisadeclarativestatement.TheDMLstatementsspecifiedinFORALLaregeneratedonce,buttheysendinbulktotheSQLengineforprocessing,thusmakingonlyasinglecontextswitch.TherecanbeonlyoneDMLstatementinFORALLthatcanbeINSERT,UPDATE,orDELETE,ortheFORALLstatementcanbeused,asperthefollowingsyntax:
FORALLindexIN
[
lower_bound…upper_bound|
INDICESOFindexing_collection|
VALUESOFindexing_collection
]
[SAVEEXCEPTIONS]
[DMLstatement]
IftheDMLstatementscontainbindvariables,thebulkSQLbindsallthestatementsinasinglestep.Thisisknownasbulkbinding.
Let’ssetuptheenvironmentforourperformancetest.TheperformancetestwillcomparetheexecutiontimeofaFORloopversusaFORALLstatement:
/*CreatetableT1withbasicobjectcolumns*/
CREATETABLET1
AS
SELECTobject_id,object_type,object_name
FROMall_objects
WHERE1=2
/
/*CreatetableT2withbasicobjectcolumns*/
CREATETABLET2
AS
SELECTobject_id,object_type,object_name
FROMall_objects
WHERE1=2
/
ThefollowingPL/SQLblockbulkcollectsthedatafromtheLOCAL_OBJECTStable,createsaninterimcollection(associativearray)foronlythesynonyminformation,andinsertsitintotwodifferenttables.Forverification,wewillquerytherecordsinsertedinboththetables:
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Localblockvariables-objecttyperecordandnestedtablecollection*/
TYPEobj_recISRECORD
(obj_idlocal_objects.object_id%TYPE,
obj_typelocal_objects.object_TYPE%TYPE,
obj_namelocal_objects.object_name%TYPE);
TYPEobj_tabISTABLEOFobj_rec;
TYPEsyn_tabISTABLEOFobj_recindexbypls_integer;
t_all_objsobj_tab;
t_all_synsyn_tab;
counterNUMBER:=1;
clock_inNUMBER;
clock_outNUMBER;
BEGIN
/*BULKCOLLECTthedatafromLOCAL_OBJECTSinnestedtablecollection*/
SELECTobject_id,object_TYPE,object_name
BULKCOLLECTINTOt_all_objs
FROMlocal_objects;
FORIINt_all_objs.FIRST..t_all_objs.LAST
LOOP
/*Captureallsynonymsinanothercollection*/
IF(t_all_objs(i).obj_type='SYNONYM')THEN
t_all_syn(t_all_syn.count+1):=t_all_objs(i);
ENDIF;
ENDLOOP;
clock_in:=DBMS_UTILITY.GET_TIME();
/*FORlooptoinsertthedataintableT1*/
FORIINt_all_syn.first..t_all_syn.last
LOOP
INSERTINTOt1VALUESt_all_syn(i);
ENDLOOP;
clock_out:=DBMS_UTILITY.GET_TIME();
DBMS_OUTPUT.PUT_LINE('TimetakenbyFORloop:'||to_char(clock_out-
clock_in));
clock_in:=DBMS_UTILITY.GET_TIME();
/*FORALLstatementtoinsertthedataintableT2*/
FORALLIINt_all_syn.first..t_all_syn.last
INSERTINTOt2VALUESt_all_syn(i);
clock_out:=DBMS_UTILITY.GET_TIME();
DBMS_OUTPUT.PUT_LINE('TimetakenbyFORALL:'||to_char(clock_out-
clock_in));
END;
/
TimetakenbyFORloop:1637
TimetakenbyFORALL:29
PL/SQLproceduresuccessfullycompleted.
/*QuerytherecordcountinT2*/
SQL>SELECTCOUNT(*)FROMt2
/
COUNT(*)
----------
37031
/*QuerytherecordcountinT1*/
SQL>SELECTCOUNT(*)FROMt1
/
COUNT(*)
----------
37031
Thisisphenomenal!TheFORALLstatementinsertedmorethan37000recordsinlessthanasecond,whereastheFORLOOPstatementtook16sectoinsertthesamenumberofrecords.Thereasonisagainthecontextswitchbetweentheprocessingengines;oneswitchagainst37000contextswitches.
Inthecaseofasparsecollection,useINDICESOForVALUESOFintheFORALLstatement.Itwilluseonlythoseindexesofthecollectionthatholdavalue.ThefollowingPL/SQLblockusestheFORALLstatementtoinsertasparsecollectionintotheT2table.Tosparsetheinterimcollection,thesynonymsstartingwithSYS%aredeletedfromit:
/*TruncatetableT2forthecurrenttest*/
TRUNCATETABLEt2
/
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Localblockvariables-objecttyperecordandnestedtablecollection*/
TYPEobj_recISRECORD
(obj_idlocal_objects.object_id%TYPE,
obj_typelocal_objects.object_TYPE%TYPE,
obj_namelocal_objects.object_name%TYPE);
TYPEobj_tabISTABLEOFobj_rec;
TYPEsyn_tabISTABLEOFobj_recindexbypls_integer;
t_all_objsobj_tab;
t_all_synsyn_tab;
counterNUMBER:=1;
clock_inNUMBER;
clock_outNUMBER;
BEGIN
/*BULKCOLLECTthedatafromLOCAL_OBJECTSinnestedtablecollection*/
SELECTobject_id,object_TYPE,object_name
BULKCOLLECTINTOt_all_objs
FROMlocal_objects;
/*FORlooptocollectallsynonymsinnestedtablecollection*/
FORIINt_all_objs.FIRST..t_all_objs.LAST
LOOP
IF(t_all_objs(i).obj_type='SYNONYM')THEN
t_all_syn(t_all_syn.count+1):=t_all_objs(i);
ENDIF;
ENDLOOP;
/*DeleteallthesynonymswhosenamesstartswithSYS%*/
FORIin1..t_all_syn.count
LOOP
IFt_all_syn(i).obj_namelike'SYS%'THEN
t_all_syn.delete(i);
ENDif;
ENDLOOP;
clock_in:=DBMS_UTILITY.GET_TIME();
/*InsertthesparsecollectionusingINDICESofclause*/
FORALLIININDICESOFt_all_syn
INSERTINTOt2VALUESt_all_syn(i);
clock_out:=DBMS_UTILITY.GET_TIME();
DBMS_OUTPUT.PUT_LINE('TimetakenbyFORALL:'||to_char(clock_out-
clock_in));
END;
/
TimetakenbyFORALL:30
PL/SQLproceduresuccessfullycompleted.
/*QuerytherecordcountintableT2*/
SQL>selectcount(*)fromt2;
COUNT(*)
----------
37025
ThereweresixsynonymsstartingwithSYS%thatwerenotinsertedinthisrun.Ifyouhadn’tusedtheINDICESOFclause,theblockwouldhaveterminatedwiththeORA-22160:
elementatindex[3]doesnotexistexception.
FORALLandexceptionhandling
FORALLisspecificallydesignedforbulktransactions.Anyfaultytransactioninthebulkoperationmaycausetheentirebulkoperationtoabortwithanexception,therebyrollingbackallthechangesmadebytheearliertransactionsofthesameDMLstatement.OraclegracefullydealswithsuchscenariosbysavingtheerroneousrecordandexceptioninformationseparatelyandbycontinuingtheDMLexecution.TherearetwowaystohandleanexceptionintheFORALLstatement:
1. AborttheFORALLexecutionbutcommitthechangesmadebytheearliertransactions:TraditionalexceptionhandlingbutwithaCOMMITintheexceptionhandler.Forexample,thefollowingexceptionhandlewillcommitthetransactionsthathavebeenexecutedalready:
EXCEPTION
WHENOTHERSTHEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
COMMIT;
RAISE;
2. ContinuetheFORALLexecutionandsavethefailedtransactions:UseSAVEEXCEPTIONSwiththeFORALLstatement.Thefeatureisknownasbulkexceptionhandling.WithSAVEEXCEPTION,OraclestoresthefaultyDMLdetailsinthebulkexceptionloggerknownasSQL%BULK_EXCEPTIONS.AftertheFORALLexecutionisover,databaseadministratorscanlookintotheexceptionlogandtroubleshootthedefectiverecords.ThedefectiverecordsareskippedandloggedundertheSQL%BULK_EXCEPTIONSpseudocolumn.Forexample,ifFORALLgenerated5000updatestatements,outofwhich13werefailedtransactions,4987recordswillstillbeupdated.The13defectivetransactionswillbeloggedintheSQL%BULK_EXCEPTIONSarraystructurewiththecursorindex.
The%BULK_EXCEPTIONSattributemaintainstwofields—ERROR_INDEXandERROR_CODE.ERROR_INDEXstoresthedefectrecordindexwheretheexceptionwasraised,whileERROR_CODErecordstheexceptionmessage.%BULK_EXCEPTIONS.COUNTstoresthecountofexceptionsraisedduringtheexecutionoftheFORALLstatement.NotethatthestandarderrorcodecapturedbytheERROR_CODEattributeisnotprefixedwiththenegative(-)sign.Therefore,inordertofetchitsequivalenterrormessage,passtheerrorcodemultipliedby-1totheSQLERRMfunction.
Inthelastillustration,weexplicitlyremovedthevaluesstartingwithSYS%.Forthecurrentdemonstration,wewilladdacheckconstraintontheOBJECT_NAMEcolumnoftheT2table.Thefollowingscriptaddsthecheckconstraint:
/*TruncatetableT2forcurrenttest*/
TRUNCATETABLEt2
/
/*AddcheckconstraintonOBJECT_NAME*/
ALTERTABLEt2
ADDCONSTRAINTt2_obj_nameCHECK(object_nameNOTLIKE'SYS%')
/
Now,wewillrunthefollowingPL/SQLblocktoinsertthedensecollectionintotheT2table.AsSAVEEXCEPTIONShasbeenspecifiedalongwiththeFORALLstatement,ifthereareanyexceptionswhileloading,theywillbesavedinthebulkexceptionlog:
SETSERVEROUTPUTON
/*StartthePL/SQLblock*/
DECLARE
/*Localblockvariables-objecttyperecordandnestedtablecollection*/
TYPEobj_recISRECORD
(obj_idlocal_objects.object_id%TYPE,
obj_typelocal_objects.object_TYPE%TYPE,
obj_namelocal_objects.object_name%TYPE);
TYPEobj_tabISTABLEOFobj_rec;
TYPEsyn_tabISTABLEOFobj_recindexbypls_integer;
t_all_objsobj_tab;
t_all_synsyn_tab;
counterNUMBER:=1;
clock_inNUMBER;
clock_outNUMBER;
/*Declareuserdefinedexceptionforerrornumber-24381*/
bulk_errorsEXCEPTION;
PRAGMAEXCEPTION_INIT(bulk_errors,-24381);
BEGIN
/*Bulkcollectobjectdetailsinnestedtablecollectionvariable*/
SELECTobject_id,object_TYPE,object_name
BULKCOLLECTINTOt_all_objs
FROMlocal_objects;
/*Filterallsynonymsandcaptureinanothercollection*/
FORIINt_all_objs.FIRST..t_all_objs.LAST
LOOP
IF(t_all_objs(i).obj_type='SYNONYM')THEN
t_all_syn(t_all_syn.count+1):=t_all_objs(i);
ENDIF;
ENDLOOP;
/*FORALLstatementtoinserttherecordsintableT2*/
FORALLIIN1..t_all_syn.count
/*Savefaultyrecordsinbulkcollectioncursorattributes*/
SAVEEXCEPTIONS
insertintot2valuest_all_syn(i);
EXCEPTION
/*Exceptionhandlertoquerythefailedtransactions*/
WHENBULK_ERRORSTHEN
FORJIN1..SQL%BULK_EXCEPTIONS.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE('----------------------------------------');
DBMS_OUTPUT.PUT_LINE('Errorin
INSERT:'||SQL%BULK_EXCEPTIONS(J).ERROR_INDEX);
DBMS_OUTPUT.PUT_LINE('ErrorMessageis:'||sqlerrm('-
'||SQL%BULK_EXCEPTIONS(J).ERROR_CODE));
ENDLOOP;
END;
/
----------------------------------------
ErrorinINSERT:3
ErrorMessageis:ORA-02290:checkconstraint(.)violated
----------------------------------------
ErrorinINSERT:2089
ErrorMessageis:ORA-02290:checkconstraint(.)violated
----------------------------------------
ErrorinINSERT:2091
ErrorMessageis:ORA-02290:checkconstraint(.)violated
----------------------------------------
ErrorinINSERT:2093
ErrorMessageis:ORA-02290:checkconstraint(.)violated
----------------------------------------
ErrorinINSERT:2094
ErrorMessageis:ORA-02290:checkconstraint(.)violated
----------------------------------------
ErrorinINSERT:3545
ErrorMessageis:ORA-02290:checkconstraint(.)violated
PL/SQLproceduresuccessfullycompleted.
SQL>selectcount(*)fromt2;
COUNT(*)
----------
37025
ThetransactionsthatfailedtogetexecutedduetothecheckconstraintviolationweresavedintheBULK_EXCEPTIONScursorattribute.Besidesthesesixrecords,alltheotherdatawasinserted,andthiscanbeconfirmedbyaSELECTqueryonthetable.
SummaryInthischapter,wehavediscussedthefeaturesthatcantuneyourPL/SQLcodetorunfaster.WehavealsoseenhowcodecompilationandoptimizationcanspeeduptheperformanceofthePL/SQLprograms.Inthelaterhalf,wediscussedthePL/SQLtuningfeaturesindetailwiththehelpofdemonstrations.
Inthenextchapter,wewillfocusononeofthemajornewfeaturesintroducedinOracleDatabase11g.Thefeatureisknownasresultcachingthatisprimarilybuilttoacceleratetheperformanceofqueriesthatarerepeatedlyexecuted.Wewilldiscussthedifferentflavorsofresultcachinginthenextchapter.
PracticeexerciseIdentifythenatureoftheprogramthatisbestsuitedfortheinterpretedmodeofcompilation.
1. TheprogramunitcontainsmultipleSQLstatements.2. Theprogramunithasjustbeendevelopedandisinthedebugstage.3. Theprogramunitusescollectionsandbulkbindstatements.4. Theprogramunitisintheproductionphase.
ChoosethecorrectstatementsabouttherealnativecompilationmodeinOracle11g.
1. ThecompilationmethodusestheCcompilertoconverttheprogramintoanequivalentCcode.
2. ThecompilationmethodmountsthesharedlibrariesthroughthePLSQL_NATIVE_LIBRARY_DIRandPLSQL_NATIVE_LIBRARY_SUBDIR_COUNTparameters.
3. ThecompilationdoesnotusetheCcompilerbutconvertstheprogramunitdirectlytotheMcode.
4. TherealnativecompilationissupportedforRACenvironmentsandparticipatesinthebackuprecoveryprocesses.
DeterminethebehaviorofthePLSQL_OPTIMIZE_LEVELoptimizerwhenithasbeensetto3.
1. Theoptimizerwouldinlinetheprogramsthatarenecessary.2. Theoptimizerwouldinlinealltheprogramsirrespectiveofthegains.3. TheoptimizerwouldinlineonlythosesubprogramswhichhavePRAGMAINLINE.4. Thesettinghasnoeffectontheinliningofthesubprograms.
ChoosethecorrectstatementsaboutthecompilationsettinginOracle.
1. FromOracle11g,thedefaultvalueofPLSQL_CODE_TYPEisNATIVE.2. Anobjectcanberecompiledinacompilationmodethatisdifferentfromthe
currentdatabasesetting.3. Duringthedatabaseupgrade,PLSQL_CODE_TYPEmustbemodifiedinthepfile
instance.4. Inrealnativecompilation,thelibrariesgeneratedarestoredinasecuredfile
system.
IdentifythetuningtipsinthefollowingPL/SQLblock:
DECLARE
CURSORCIS
SELECTENAME,SAL,COMM
FROMEMPLOYEES;
L_COMMNUMBER;
BEGIN
FORIINC
LOOP
L_COMM:=I.SAL+((I.COMM/100)*(I.SAL*12));
DBMS_OUTPUT.PUT_LINE(I.ENAME||'earns'||L_COMM||'as
commission');
ENDLOOP;
END;
/
1. UseBULKCOLLECTtoselecttheemployeedata.2. DeclareL_COMMasNOTNULL.3. UsePLS_INTEGERforL_COMM.4. Notuningisrequired.
WhichofthesestatementsaretrueaboutinlininginPL/SQLsubprograms?
1. Theoptimizercaninlineonlythestandalonestoredfunctions.2. Theoptimizercaninlineonlythelocallydeclaredsubprograms.3. Inliningisalwaysusefulintheperformanceirrespectiveofthesizeofthe
subprogram.4. Theoptimizercannotidentifyanysubprogramforinliningwhentheoptimizer
levelissetat0.
Examinethefollowingcodeanddeterminetheoutput:
DECLARE
FUNCTIONF_ADD(P_NUMNUMBER)
RETURNNUMBER
IS
BEGIN
RETURNP_NUM+10;
END;
BEGIN
FORIIN122..382
LOOP
PRAGMAINLINE(F_ADD,'YES');
L_SUM:=L_SUM+F_ADD(I);
ENDLOOP;
END;
/
1. PLSQL_OPTIMIZE_LEVELissetto2.2. TheF_ADDlocalfunctionwouldnotbecalledinlineunless
PLSQL_OPTIMIZE_LEVELissetto3.3. TheF_ADDlocalfunctionmaybecalledinlinebecausePLSQL_OPTIMIZE_LEVEL
issetto2.4. TheF_ADDlocalfunctionwouldbecalledinlinebecausePRAGMAINLINEmarksit
forinline.5. Inliningcannotbedoneforlocallydeclaredsubprograms.
ThelibrariesgeneratedfromrealnativecompilationarestoredintheSYSAUXtablespace.
1. True2. False
SuggestthetuningconsiderationsinthefollowingPL/SQLblock:
DECLARE
L_SUMNATURALN:=0;
L_IDVARCHAR2(10);
BEGIN
L_ID:=256;
L_SUM:=L_ID*1.5;
END;
1. ThedatatypeofL_SUMcanbechangedtoNATURALandnullabilitycanbeverifiedintheexecutablesection.
2. L_SUMmustnotbeinitializedwithzero.3. The1.5multiplemustbeassignedtoavariable.4. L_IDmustbeofanappropriatedatatypesuchasNUMBERorPLS_INTEGER.
IdentifythecorrectstatementsaboutPRAGMAINLINE.
1. ItisthefifthpragmainOraclebesidesAUTONOMOUS_TRANSACTION,EXCEPTION_INIT,RESTRICT_REFERENCE,andSERIALLY_REUSABLE.
2. Itdoesnotworkforoverloadedfunctions.3. ItdoesnotworkforPLSQL_OPTIMIZE_LEVEL=1.4. PRAGMAINLINE(<Functionname>,'YES')ismeaninglessat
PLSQL_OPTIMIZE_LEVEL=3,becausetheoptimizerinlinesallthesubprograms.
Chapter9.ResultCacheInthelastchapter,welearnedquiteafewtechniquestotunePL/SQLcode.Bynow,youmusthavegottheideathattuningisnothinglessthananartthatcomesbypracticeandgrowswithexperience.Thebetteryouunderstandthedataandtheapplication,thehighertheprobabilityoftuningtherightareas.MostDBAsaroundtheworldarefamiliarwiththecommonlyusedtuningpracticessuchasqueryrewriting,columnindexing,instanceoptimization,materializedviews,andPL/SQLcodeoptimization.
AsOracleDatabaseprofessionals,wemightalreadybeawareofmultiplecachesresidentinthedatabaseinstancearchitecture(tonameafew:thebuffercache,librarycache,dictionarycache,orrecyclecache).Primarily,cachesaremeanttoholddatasothatthedataaccessoperationsareservedfaster.
OracleDatabase11gRelease2introducedanewcachecomponentwithinthesharedpool,knownastheServerResultCache,foraspecificjob.TheResultCacheenablescachingofresultsfromanSQLqueryorevenaPL/SQLfunctionintheServerResultCache.ThischapterwilldiscusstheResultCachefeatureindetail.Wewillunderstandhowtoconfiguretheresultcacheinadatabaseandwhatmakesitabrilliantfeature.Theoutlineofthechapterisasfollows:
OracleDatabase11gResultCache:
WhatisServerResultCache?ConfiguringtheServerResultCacheResultCacheversusBufferCacheResultCacheversusDatabaseIn-MemoryResultCacheversustheIn-MemoryDatabaseCache
SQLResultCachePL/SQLfunctionResultCacheOCIclientResultCacheTheDBMS_RESULT_CACHEpackageResultcacheinRealApplicationClusters
OracleDatabase11gResultCacheOracleDatabase11gofferedplentyofperformancemanagementfeatures;oneofthosewasserversideresultcaching.ResultcachingimplementsacachingmechanisminanOracleDatabase.Usingthisfeature,youcancachetheresultsofanSQLqueryoraPL/SQLfunctionwithinadesignatedareaintheSGA(SystemGlobalArea),knownasServerResultCache.
NoteTheresultcachingfeatureisavailableinOracleDatabaseEnterpriseEditiononly.
Conventionally,whenaqueryisexecutedforthefirsttime,Oraclelooksfortherequireddatablocksinthebuffercachefirst.Ifthedatablocksarealreadyinthebuffercache(becausepreviousSELECTquerieshadretrievedthem),thecurrentSQLquerygetsexecutedusingthatdata.Ifnot,OracleperformsphysicalI/Ostofetchthetabledatafromthediskintothebuffercacheandthenmovesaheadforthequeryprocessing.ThenexttimethesameSELECTquerywiththeidenticalpredicatesandinputsisre-executed,inthesameusersession—OracleperformslogicalI/Ostoreadthedatafromthebuffercacheandexecutethequery,butstillgoesthroughtheentirequeryprocessingcycle.
ResultCacheisintendedtotunethescenarioswhereaqueryisexecutedmorethanonceforthesamepredicatesandliterals.OraclestorestheresultofaqueryintheServerResultCacheduringitsfirstexecution.OnthesubsequentexecutionofanidenticalSELECTquery(withthesamepredicatesandliterals),theresultisfetcheddirectfromtheservercachedirectlywithoutre-executingthequery,therebyachievingimpressiveperformancegains.Wheredothesegainscomefrom?Well,thesegainsarecollectivelycontributedbythereductioninlogicalandphysicalI/Os,sorts,and,hence,theCPUconsumption.
Resultcachingcanbeenabledatthreelevels:
SQLqueryResultCache:ResultsfromSQLqueriescanbecachedinthedatabaseserver.PL/SQLfunctionResultCache:ResultsfromPL/SQLfunctionscanbecachedinthedatabaseserver.OCIResultCache:ResultsfromSQLqueriescanbecachedintheclientprocesscache.Withinthescopeofthechapter,wewillrestrictourdiscussiontotheSQLandPL/SQLResultCacheonly.
TheResultCachefeaturecanbringhugebenefitstowarehouseandanalyticworkloads.Databaseapplications,wherethedatadoesnotchangeoftenbutisfrequentlyselected,aretherightcandidatestoimplementresultcaching.Anotherpointtoconsideristhattheservercacheisamemorycomponent,albeitanon-persistentone.Itgetsauto-flushedwhenthedatabaseinstancecrashesorrestarts.
WhatistheServerResultCache?StartingwithOracleDatabase11g,theServerResultCacheisacomponentofdatabaseinstancememory,thatresideswithinthesharedpoolofSGA.ItisusedtostoretheresultsofSQLqueriesandPL/SQLfunctions.Itisfurtherlogicallydividedintotwosub-poolcomponentsknownasSQLqueryResultCacheandPL/SQLfunctionResultCache.TheSQLqueryResultCachestorestheresultsSQLqueriesandtheirdependencies.ThePL/SQLfunctionResultCachestoresresultsfromPL/SQLfunctions.
TheServerResultCacheispre-configuredtouseasmallportionofthesharedpool.IfthedatabaseusesAutomaticMemoryManagement(memory_target)formemorysizing,then0.25percentofmemory_targetisallocatedtotheResultCache.Inthecaseofautomaticsharedmemorymanagement(sga_target),0.5percentofsga_targetispre-allocatedtotheResultCache.Formanualsharedmemorymanagement(shared_pool_size),theResultCacheispre-allocatedwith1percentofshared_pool_size.
YoucandefineyourownServerResultCachesizeusingtheinitializationparameterRESULT_CACHE_MAX_SIZE.Theuser-suppliedvaluetotheparameterisroundedofftothenearestmultipleof32K.Ifthevalueofthisparameteriszero,theresultcachingfeatureisdisabled.
Youmustalsonotethat,beinganativepartofSGA,theServerResultCacheisaffectedbyAutomaticMemoryManagement(AMM).Inaddition,itabidesbytheregularcachefeaturessuchasdynamicsizingandtheLeastRecentlyUsed(LRU)algorithmtoflushouttheresultsets.ThefollowingfigurelocatestheserverResultCachecomponentintheOracleDatabasememoryarchitecture:
OracleDatabasememoryarchitecture
ConfiguringtheServerResultCacheInthissection,wewilllearnabouttheconfigurationoftheserver-sideresultcachefeature.TherearefourinitializationparametersthatcontroltheresultcachefeatureintheOracleDatabase:
RESULT_CACHE_MAX_SIZE:Thisparameterdeterminesifthecachingisenabledordisabledonthedatabaseserver.Ifitiszero,thecachingfeatureisdisabled.Youmustsetthisparametertoavaluegreaterthanzerotoenableresultcachingontheserver.Actually,itsetsthemaximumsizeoftheserverresultcacheinthesharedpool.OraclerecommendstorestricttheServerResultCacheupto75percentofthesharedpool.
InRACenvironments,thisparametermustbesetateachinstance.
RESULT_CACHE_MAX_RESULT:Thisparameterdefinesthesizeofasingleresultsetintheservercache.ItisexpressedasapercentagevalueofRESULT_CACHE_MAX_SIZE.Bydefault,itsvalueis5percent.RESULT_CACHE_MODE:ItdetermineswhetheranSQLqueryhastobeservedfromtheSQLqueryresultcache.Inotherwords,theparameterdecidesiftheResultCacheoperationhastobeaddedinthequeryexecutionplan.ThecachingmodecanbeMANUALorFORCE:
MANUAL(default):TheservercachestheresultsofonlytheannotatedqueriesthataremarkedwiththeRESULT_CACHEhint.FORCE:Thedatabaseenforcesacachelookupforallthequeriesandwillattempttostoretheresultsforallthequeriesthatareexecutedontheserver.However,youcanusetheNO_RESULT_CACHEhinttoskipthecachelookup.
NoteUseFORCEmodecautiouslyasitenforcescachingforallSQLqueriesandthisbehaviormayexhausttheserverresultcache.
RESULT_CACHE_REMOTE_EXPIRATION:Thisparameterdefinestheretentiontimeofaresultcachedfromaremoteobject.Itisexpressedinminutesanditsvalueiszero,bydefault.
Forexample,thefollowingALTERSYSTEMcommandsetsthesizeoftheServerResultCache:
CONNECTsys/oracleasSYSDBA
ALTERSYSTEMSETresult_cache_max_size=25MSCOPE=BOTH
/
Let’squerytheV$PARAMETERviewtoconfirmtheeffectoftheprecedingcommand.NotetheISPDB_MODIFIABLEcolumn.
SELECTname,
value,
ispdb_modifiable
FROMv$parameterWHEREnamelike'result%'/
NAMEVALUEISPDB
-----------------------------------------------
result_cache_modeMANUALTRUE
result_cache_max_size26214400FALSE
result_cache_max_result5FALSE
result_cache_remote_expiration0TRUE
Theprecedingqueryoutputshowsthat,inamultitenantcontainerdatabase(OracleDatabase12c),theServerResultCacheiselasticallysharedbyallthepluggabledatabases.TheparametersthatcanbemodifiedfromthecontextofapluggabledatabaseareRESULT_CACHE_MODEandRESULT_CACHE_REMOTE_EXPIRATION.Apluggabledatabaseadministrator(PDBA)caneitherswitchonautomaticresultcachingforthedatabaseorusethemanualmodeofcaching.Inaddition,theresultsetexpirationtimecanvaryforeachpluggabledatabaseinamultitenantcontainerdatabase.Mission-criticaldatabasesorthoseathigherservicelevelscanretaintheirresultsetsforlongerthanlow-prioritydatabases.
Whathappenswhentheresultcachegetsfull?Theleastrecentlyusedresultisautomaticallyflushedfromthecachetomakeroomfornewresults.
ResultCacheversusBufferCacheTheResultcacheandbuffercachearepartofthedatabasememoryarchitecture,butbotharemeanttoachievedifferentobjectives.TheBuffercacheisusedtostorethedatablocksofatableandtheseblocksarenotcoupledtoanSQLquery.TheResultcachestorestheendresultsandnottheblocksfromtheSQLqueriesandthusistiedtoaparticularSQLquery.TheResultcachedoesn’tworkontheconceptsofblocksorbuffers.
ResultCacheversusOracle12cDatabaseIn-MemoryTheServerResultCachestorestheresultsfromSELECTqueriesandtheseresultsaredependentontheunderlyingdatasources.ButDatabaseIn-Memoryenablesthecolumnizationofrow-formatdataandstoresitwithintheIn-MemoryColumnStoreoftheSGA.ThecolumnardataintheIn-Memorycolumnstorecanbecompressedwhileresultsintheservercachecannotbecompressed.
ResultCacheversusIn-MemoryDatabaseCacheTheIn-MemoryDatabaseCache(IMDB)isadatabaseoptionthatusesOracle’sTimesTendatabaseunderthecovers.Itisdeployedintheapplicationtiertostagebusiness-criticaldataclosertotheapplicationand,henceimprovetheresponsetime.TheapplicationconnectstotheIMDBcacheandperformstransactionsonthecacheddata;thechangesarepostedtothedatabasetierthroughthesynchronousorasynchronousmethods.Ontheotherhand,theServerResultCachefeaturestorestheresultsofSQLqueriesandPL/SQLfunctions,butnotthetabledata.However,itisdependentonthetabledataandturnsstaleiftheunderlyingdatagetsmodified.
SQLqueryResultCacheYoucanstoretheresultsofaSQLqueryintheSQLqueryresultcacheinthreeways:
Enablingautomaticresultcacheatthedatabaselevel:AutomaticSQLresultcachingisenabledbysettingtheinitializationparameterRESULT_CACHE_MODEtoFORCE,whichenforcescachingforalltheSQLstatements.However,youcanpreventspecificSQLqueriesfromexhaustingtheServerResultCachebyusingtheNO_RESULT_CACHEhint.Enablingautomaticresultcacheatthetablelevel:YoucansetRESULT_CACHEmodetoFORCEforaparticulartablesothattheresultsfromthequeriesonthistablewillbecachedinthequeryresultcache.
ALTERTABLEmy_objectsRESULT_CACHE(MODEFORCE)
/
YoucanspecifyaNO_RESULT_CACHEhinttoavoidthecachelookupoperationforaqueryusingthecacheenforcedtable,andevenrollbackthecachingmodetoMANUAL.
ManuallyannotatingselectiveSQLqueries:YoucanalsospecifyaRESULT_CACHEhintinafrequentlyexecutedSQLquerytocacheitsresults.Thisisknownasmanualresultcaching.Inthiscase,RESULT_CACHE_MODEmustbesettoMANUAL.Queriesthatscanlargevolumesofdataandreturnasmallresultaregoodcandidatesforcaching.
NoteTheRESULT_CACHEhintcanalsobeusedinsub-queriesandin-lineviews.
HowaretheresultsstoredintheSQLqueryresultcache?Wheneveraqueryexecutes,thedatabaseperformsacachelookuptosearchforaresultfrompreviousexecutionsofthesamequery.Iftheresultisfound,thecachedresultisreturnedwithoutfurtherre-executingtheSQLquery.Iftheresultisnotfound,theSQLqueryisexecutedasusualandtheresultisreturnedtotheuser.Theresultisthencachedinthequeryresultcache.
Howisitdifferentfrommaterializedviews?ResultCachingandmaterializedviewsappearsimilarinconceptasbothimprovequeryperformancebymaintainingaseparatecopyofaqueryresult,buttheyareverydifferentinimplementation.AmaterializedviewoccupiesoccupydatabasestoragetostorethedatawhiletheServerResultCacheconsumestheinstancememory.Thedatainmaterializedviewsgetsperiodicallyrefreshedbyre-executingthebasequerybuttheresultcachegetsautomaticallybuiltonthesubsequentrunoftheSQLqueryorPL/SQLfunction.Materializedviewispersistentwhiletheresultcacheisnon-persistent.
Aresultsetintheservercachecanbeusedonlyifthesamequeryisre-executed(ignoringblankspacesandindentationofthequery).Aresultsetisuniquelyidentifiedasacombinationofdependenttables,predicates,literalinputs,andtheresult.Ifthequeryusesbindvariables,Oraclestoresadistinctresultsetforeachuniquecombinationofbindvariablevalues.
LetuscreateascenariotodemonstrateSQLresultcaching.Thefollowingscriptcreatesa
tablefromtheALL_OBJECTSdictionaryviewforourcasestudy:
CONNECTscott/tiger
CREATETABLEmy_objects
ASSELECT*FROMall_objects
/
SELECTcount(*)
FROMmy_objects
/
COUNT(*)
----------
89507
ThefollowingSQLgivesthecountofobjectsbytheirobjecttypeandstatus.NoticethattheRESULT_CACHEhinthasbeenusedtoaddtheResultCacheoperatorintheexecutionplananddoacachelookup.Additionally,wearealsoaddingGATHER_PLAN_STATISTICStogatheradditionalstatisticsforthequeryexecution:
SETTIMINGON
SELECT/*+RESULT_CACHEGATHER_PLAN_STATISTICS*/
object_type,
status,
count(*)
FROMmy_objects
GROUPBYobject_type,status
ORDERBYobject_type,status
/
Elapsed:00:00:00.92
Theprecedingqueryreturns43rows.Nowletuschecktheexplainplan:
SELECT*
FROMTABLE(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATSLAST'))
/
TheexplainplanshowstheRESULTCACHEoperation,whichconfirmstheresultofthecachelookupoperation.Sincethisisthefirstexecutionofthequery,theresultiscachedinthequeryresultcachebytheID'br0p4fgjgh7jp128u0paxavkns'.TheStartscolumnshowsthatalloperationswerecarriedoutatleastonceinthecurrentexecution.Theactualrows(A-Rows)showthecountofrowsscannedduringthefulltablescanandgroupedbyrowcount.
Letusre-executethisqueryandchecktheexplainplan:
SELECT/*+RESULT_CACHEGATHER_PLAN_STATISTICS*/
object_type,
status,
count(*)
FROMmy_objects
GROUPBYobject_type,status
ORDERBYobject_type,status
/
Elapsed:00:00:00.01
Notethatthesecondexecutionissignificantlyfasterthanthefirstexecution.Queryingtheexplainplan:
SELECT*
FROMTABLE(DBMS_XPLAN.DISPLAY_CURSOR(FORMAT=>'ALLSTATSLAST'))
/
TheStartscolumnshowsthattheresultisretrievedfromthequeryresultcache.ItshowszerofortheHASHGROUPBYandTABLEACCESSFULLoperations,whichmeansthattheseoperationswereignored.A-rowsvaluesarezeroastherewerenorowsscannedinthis
MonitoringtheSQLResultCacheOracleprovidesdynamicviewstoquerythecurrentstateoftheresultcache.TheseviewsareV$RESULT_CACHE_OBJECTS,V$RESULT_CACHE_STATISTICS,V$RESULT_CACHE_MEMORY,andV$RESULT_CACHE_DEPENDENCY.Beforequeryingtheseviews,letuscheckwhatisintheresultcache:
/*Monitortheresultcachecomponentsinsharedpool*/
SELECT*
FROMv$sgastat
WHEREPOOL='sharedpool'
andnamelike'Result%'
/
POOLNAMEBYTESCON_ID
----------------------------------------------------------
sharedpoolResultCache:MemoryMgr2080
sharedpoolResultCache:CacheMgr2560
sharedpoolResultCache:StateObjs29280
sharedpoolResultCache1639520
sharedpoolResultCache:BloomFltr20480
Fromtheprecedingqueryoutput,itisevidentthattheresultcacheisacomponentofthesharedpoolandcontainsmemorymanagementdriverssuchasmemorymanager,cachemanager,stateobjects,andbloomfilters.
TheRCBGbackgroundprocesscoordinatestheresultcachemanagementactivities.TheprocessplaysabiggerroleinOracleRACthaninasingleinstancedatabase:
/*QuerytheRCBGbackgroundprocess*/
SELECTpaddr,name,description
FROMv$bgprocess
WHEREname='RCBG'
/
PADDRNAMEDESCRIPTION
-----------------------------------------
00RCBGResultCache:Background
Comingbacktothecachedresults,thefollowingqueryshowsthepropertiesoftheresultsetcachedintheprecedingquery:
/*Querytheresultcacheobjects*/
SELECTstatus,
type,
build_time,
depend_count,
column_count,
scan_count,
row_count
FROMv$result_cache_objects
WHEREcache_id='br0p4fgjgh7jp128u0paxavkns'
/
STATUSTYPEBUILD_TIMEDEPEND_COUNTCOLUMN_COUNTSCAN_COUNT
ROW_COUNT
---------------------------------------------------------------------
---
PublishedResult2113143
Intheprecedingoutput:
BUILD_TIMEisthetimespentinbuildingtheresult(inhundredthsofasecond).DEPEND_COUNTisthecountofdependentobjectsforthisresult.Inthiscase,itisjustthetable(MY_OBJECTS).COLUMN_COUNTisthecountofcolumnsintheresult.SCAN_COUNTisthenumberoftimestheresultisusedbyanSQLquery.ROW_COUNTisthenumberofrowscontainedintheresult.STATUSisthecurrentstatusoftheresult;PUBLISHED,inthiscase.OthervaluesoftheSTATUScolumn,whichyoumightseeindifferentcases,canbe:
NEW:Anunder-constructioncacheresultPUBLISHED:AvalidresultreadyforuseINVALID:Aninvalidatedandnon-usableresultEXPIRED:AresultwhichhascrossedtheexpirationtimeBYPASS:AbypassresultispreventedfrombeingusedbyaSQLquery
TYPEisRESULT.TheothertypecanbeDEPENDENCYfortheobjectswhilebuildinguptheresult.
TipTheNAMESPACEcolumninV$RESULT_CACHE_OBJECTSdetermineswhetheraresultisfromaSQLquerycacheoraPL/SQLfunctioncache.ThefollowingSQLqueryliststhecountofresultsinSQLandPL/SQLresultcachesinthesharedpool:
SELECTnamespace,count(*)
FROMv$result_cache_objects
WHEREnamespaceISNOTNULL
GROUPBYnamespace
/
Thefollowingqueryliststheresultcachestatistics.Notethatthevaluesagainstthestatisticnamematchtheresultcachesettings:
/*Querytheresultcacheblockstatistics*/
SELECTid,name,value
FROMV$RESULT_CACHE_STATISTICS
/
IDNAMEVALUE
---------------------------------------------
1BlockSize(Bytes)1024
2BlockCountMaximum25600
3BlockCountCurrent32
4ResultSizeMaximum(Blocks)1280
5CreateCountSuccess1
6CreateCountFailure0
7FindCount0
8InvalidationCount0
9DeleteCountInvalid0
10DeleteCountValid0
11HashChainLength1
12FindCopyCount0
13Latch(Share)0
13rowsselected.
Interpretation:Thesizeofoneresultcacheblockintheservercacheis1kilobyte.Therefore,amaximumof25,600blockscanbeallowedinthecacheandasingleresultsizecancontainamaximumof1,280blocks(5percentof25600).Thecurrentresultcachehasoneresultandintotal32blocksarecurrentlyallocated.
Youcanalsoquerythese32blocksfromV$RESULT_CACHE_MEMORY.Outofthese32blocks,only3areoccupiedwhiletheother29arefree.Themathfor3occupiedblocksisquitesimple.SQLtakes2blockswhilethedependenttable(MY_OBJECTS)consumes1block:
/*Querythecountofoccupiedblocksinresultcachememory*/
SELECTfree,COUNT(*)
FROMv$result_cache_memory
GROUPBYfree
/
FREECOUNT(*)
---------------
NO3
YES29
YoucanquerythedependencymatrixoftheresultsetbyqueryingtheV$RESULT_CACHE_DEPENDENCYdictionaryview:
/*Querythedependenciesofcachedresults*/
SELECTrc.result_id,
o.object_name
FROMV$RESULT_CACHE_DEPENDENCYrc,user_objectso
WHERErc.object_no=o.object_id
/
RESULT_IDOBJECT_NAME
------------------------------
1MY_OBJECTS
InvalidationoftheSQLResultCacheForacachedresulttostayvalid,thestateofdependenttablesanddatamustbepreserved.Ifthetableisalteredortheunderlyingdataisupdated,thecachedresultgetsinvalidated.It’sonlyafterthenextexecutionthatthequeryresultisrebuiltandcachedasanewresult.ThefollowingUPDATEstatementmodifiesonerowintheMY_OBJECTStable.
UPDATEmy_objects
SETobject_name=initcap(object_name)
WHEREobject_id=30
/
COMMIT
/
Theresultinthequeryresultcachegetsinvalidated:
/*Querythecacheresultstatus*/
SELECTcache_id,status
FROMv$result_cache_objects
WHEREcache_id='br0p4fgjgh7jp128u0paxavkns'
/
CACHE_IDSTATUS
-------------------------------------
br0p4fgjgh7jp128u0paxavknsInvalid
Wewillre-executethegroupbyqueryingtheMY_OBJECTStabletorebuildtheresultinthequeryresultcache:
/*Re-executetheSQLquerytorebuildtheresult*/
SELECT/*+RESULT_CACHEGATHER_PLAN_STATISTICS*/
object_type,
status,
count(*)
FROMmy_objects
GROUPBYobject_type,status
ORDERBYobject_type,status
/
/*Querythecacheresultstatus*/
SELECTcache_id,status
FROMv$result_cache_objects
WHEREcache_id='br0p4fgjgh7jp128u0paxavkns'
/
CACHE_IDSTATUS
------------------------------------
br0p4fgjgh7jp128u0paxavknsPublished
br0p4fgjgh7jp128u0paxavknsInvalid
Notethattheinvalidatedresultisretainedinthequeryresultcacheunlessitismanuallyflushedout,agesout,orthedatabaseinstanceisrestarted.
ReadconsistencyoftheSQLResultCacheTheresultcacheusestheSystemChangeNumber(SCN)tomaintainthereadconsistencyofSQLquerieswhoseresultisretrievedfromtheSQLqueryresultcache.EachandeveryresultaddedtothequeryresultcachealsostorestheSCNuntilitisvalid.Aresultwillstayvalidorconsistentuntilanongoingtransactioniscommitted.
Forexample,intheprecedingcodelisting,notethechangeinSCNwhiletheresultinthequeryresultcachewasinvalidatedandgotrebuiltaftertheSQLwasre-executed:
/*QuerytheSCNnumbersforeachqueryresultcached*/
SELECTcache_id,status,scn
FROMv$result_cache_objects
WHEREcache_id='br0p4fgjgh7jp128u0paxavkns'
/
CACHE_IDSTATUSSCN
----------------------------------------------
br0p4fgjgh7jp128u0paxavknsPublished7713754
br0p4fgjgh7jp128u0paxavknsInvalid7680436
LimitationsTheSQLresultcachedoesn’tworkwith:
TemporarytablesSYS-orSYSTEM-ownedobjectsSequencepseudocolumns(CURRVALandNEXTVAL)DateandTimeSQLfunctionsTheSYS_CONTEXTfunctionwithanon-constantvariable
PL/SQLFunctionResultCacheYoumustcreateaPL/SQLfunctionwithaRESULT_CACHEclausetoadditsresulttothePL/SQLfunctionresultcache.Whenacache-enabledPL/SQLfunctionisinvokedforthefirsttime,thedatabaselooksintothePL/SQLresultcacheforitsresultwiththematchingarguments.Iftheresultisfound,itisreturnedtothecallingenvironmentwithoutexecutingthefunctionbody.Iftheresultisnotfound,thefunctionbodyisexecutedandtheresultisstoredinthePL/SQLfunctioncache.Uponsubsequentfunctioncallsforthesameinputparameters,theresultisfetcheddirectlyfromthecache.
Notethataresultcachefunctiondoesn’tneedthedependentdatabasetablestoberesult-cached.
NoteOracleDatabase11gRelease1usedtheRELIES_ONclausetospecifythedependentdatasourceswhosestatewouldaffectthestatusofthecachedresult.TheclausewasdeprecatedinOracleDatabase11gRelease2.
Doesitsoundsimilartodeterministicfunctions?DeveloperswhoarefamiliarwithdeterministicfunctionsinPL/SQLmightbethinkingthatthefunctioncachingconceptisquiteclosetodeterministicbehavior.Well,theideaissimilarbutfunctionresultcachingcomeswithmanymorecapabilities.Afunctionisdeterministicifitalwaysreturnsthesameoutputforthesameinputargumentsinagivensessiononly,wheninvokedfromanSQLquery.ThePL/SQLfunctionresultcacheovercomesthelimitationsofadeterministicfunctionbybeingsharableacrosssessionsofthesameuserandcanbeinvokedfromSQLaswellasPL/SQL.
DifferencesbetweenResultCacheandothercachingtechniquesYes,that’sagoodpoint.PriortotheintroductionofthisfeatureinOracleDatabase11g,cachingwasimplementedusingpackagelevelcollectionvariables.ThetwomajordrawbacksofthatapproachwerethatitservedasasessionlevelcacheandconsumedasubstantialamountofProcessGlobalArea(PGA).Beingasession-specificcache,thepackagedvariableswerenotsharablewithothersessions.PGAusagecangrowenormouslyforlargecollectionvariables,whichmayimpactperformance.TheServerresultcachewinsbyawidemarginonthesepoints.Itissharableacrossauser’ssessions,preservesdataintegrity,andmostimportantly,itusestheOracle-managedSGAinsteadofthrottlingthePGA.
IllustrationWewillcreateaPL/SQLfunctionF_COUNT_OBJwiththeRESULT_CACHEclause.Thefunctionreturnsthecountofobjectsforaspecificobjecttype:
/*AfunctionwiththeRESULT_CACHEclause*/
CREATEORREPLACEFUNCTIONf_count_obj(obj_typeVARCHAR2)
RETURNNUMBERRESULT_CACHEIS
l_countNUMBER;
BEGIN
/*Selectquerytofetchrecordcountinalocalvariable*/
SELECTCOUNT(object_type)
INTOl_count
FROMmy_objects
WHEREobject_type=obj_type;
RETURNl_count;
END;
/
WewillinvokethisfunctioninaSELECTstatementandcheckthestatistics:
SETAUTOTRACEON
/*InvokefunctioninSELECTstatementforavalidinput*/
SELECTf_count_obj('PROCEDURE')
FROMDUAL
/
M_PROC_COUNT
------------
214
Statistics
----------------------------------------------------------
2recursivecalls
0dbblockgets
348consistentgets
0physicalreads
0redosize
559bytessentviaSQL*Nettoclient
551bytesreceivedviaSQL*Netfromclient
2SQL*Netroundtripsto/fromclient
0sorts(memory)
0sorts(disk)
1rowsprocessed
Notetheconsistentgetsintheprecedingstatistics.ThisisfortheexecutionoftheSELECTstatementinthefunctionbody.Nowlet’srunthefunctionforthesecondtime:
/*InvokefunctioninSELECTstatementagainforthesameinput*/
SELECTf_count_obj('PROCEDURE')
FROMDUAL
/
M_PROC_COUNT
------------
214
Statistics
----------------------------------------------------------
0recursivecalls
0dbblockgets
0consistentgets
0physicalreads
0redosize
559bytessentviaSQL*Nettoclient
551bytesreceivedviaSQL*Netfromclient
2SQL*Netroundtripsto/fromclient
0sorts(memory)
0sorts(disk)
1rowsprocessed
TherewereabsolutelynoconsistentgetsthistimeastheresultisfetcheddirectlyfromthePL/SQLcache.Nowlet’sruntheF_COUNT_OBJfunctionforadifferentinputvalueandcheckthestatistics:
/*InvokefunctioninSELECTstatementforanotherinput*/
SELECTf_count_obj('FUNCTION')
FROMDUAL
/
F_COUNT_OBJ('FUNCTION')
-----------------------
356
Elapsed:00:00:00.09
Statistics
----------------------------------------------------------
4recursivecalls
0dbblockgets
348consistentgets
0physicalreads
0redosize
558bytessentviaSQL*Nettoclient
551bytesreceivedviaSQL*Netfromclient
2SQL*Netroundtripsto/fromclient
0sorts(memory)
0sorts(disk)
1rowsprocessed
Onceagain,consistentgetsappearinthestatisticsbecauseadifferentinputissuppliedsothefunctionbodyisexecutedandanewresultsetisaddedtothecache.
MonitoringthePL/SQLResultCacheFormonitoring,wecanquerythedynamicdictionaryviewsandconfirmthecachingofresultsfromthePL/SQLfunction.Thefollowingqueryliststheresultspresentintheservercache:
SELECTcache_id,name,status,depend_count,scan_count
FROMv$result_cache_objects,dba_users
WHEREcreator_uid=user_id
ANDusername='SCOTT'
/
Fromtheprecedingoutput,itisevidentthattherearetworesultsetsinthecache(thatistosay,fortwodifferentinputs).Alsotherearetwodependentobjects—theF_COUNT_OBJfunctionandtheMY_OBJECTStable.Anychangeinthestateofthesetwoobjectswillresultintheinvalidationofthecachedresults.
AnotherpointofinterestisthecacheID.Yes,boththeresultshavethesamecacheID.InthecaseofthePL/SQLfunctioncache,alltheresultshavethesamecacheIDbutdifferentcachekeys.
ThefollowingqueryretrievestwoPL/SQLresultcachestatisticsthatdeterminehowmanyresultswerecreatedinthecache(CreateCountSuccess)andhowmanytimestheywereserved(FindCount):
SELECT*
FROMv$result_cache_statistics
WHERENAMEIN('CreateCountSuccess','FindCount')
/
IDNAMEVALUECON_ID
------------------------------------------
5CreateCountSuccess20
7FindCount20
InvalidationofthePL/SQLResultCacheThefunctionresultcachegetsinvalidatedwhen:
TheunderlyingdatasourcesarealteredorthedataismodifiedThefunctionisrecompiled
Inthenextinvocationofthefunction,theresultisrebuiltandcachedinthePL/SQLfunctionresultcache.Notethattheinvalidatedresultsetwillstillexistandgetsflushedoffbyamanualflushoperationorduringaninstancerestart.Byvirtueofitbeingacache,theresultscanalsogetflushedoffbytheleastrecentlyused(LRU)algorithm.
LimitationThePL/SQLfunctionresultcachedoesnotworkfor:
PipelinedfunctionsOUTandINOUTparametersTheINparameterofBLOB,CLOB,NCLOB,refcursor,collection,object,orrecordBLOB,CLOB,NCLOBreturns,refcursor,collection,object,orrecordAfunctiondeclaredlocallyinananonymousPL/SQLblock
OCIClientresultscacheApplicationswiththeOracleCallInterface(OCI)clientcanlargelybenefitfromtheresultcachefeature.TheresultsfromanSQLqueryandaPL/SQLfunctioncanbecachedwithintheOCIclientprocesscacheandnotinthedatabaseservermemory.Cachingresultsintheclientprocesscachehelpsinmultipleways.First,thequeryresponsetimeimprovesdrasticallyastheresultsareserveddirectlyfromthecachewithoutevenhittingthedatabaseserver.Second,thereducednetworkroundtripsenhanceapplicationperformanceandtheeffectiveutilizationofdatabaseresources.
Howistheconsistencyofresultsintheclientprocesscachemaintained?TheOracleDatabaseserverisresponsibleformonitoringtheconsistencyofcachedresults.Iftheunderlyingdataismodified,thedatabaseservernotifiestheclientprocessandinvalidatestheresultset.Onitsnextroundtriptotheserver,theclientprocessrebuildsthestaleresults.
TheclientresultcacheisindependentofthedatabaseservercacheanddeducesthataresultfromanSQLquerycanbecachedonthedatabaseservercache,theclientprocesscache,orboth.
Tosetuptheclientresultcache,youarerequiredtosetthefollowingparameters:
CLIENT_RESULT_CACHE:Thisdeterminesthemaximumsizeoftheclientprocesscache,whichmustbemorethan32KB.CLIENT_RESULT_CACHE_LAG:Thisspecifiesthetime(inseconds)afterwhichtheOCIcalltothedatabaseisforcedtovalidatethecachedresults.Thedefaultvalueis3,000seconds.COMPATIBLE:ThisistheOracleDatabase-compatibleversion.
TheDBMS_RESULT_CACHEpackageTheOracle-suppliedpackageDBMS_RESULT_CACHEisusedtoregulatetheServerResultCachecomponentofthesharedpool.ThepackageisownedbySYSandonlyprivilegedusersshouldbegrantedtheEXECUTEprivilege.
Thepublicconstantsusedinthepackageareasfollows:
DBMS_RESULT_CACHEconstants(reference:Oracledocumentation)
STATUS_BYPS CONSTANTVARCHAR(10):='BYPASS';
STATUS_DISA CONSTANTVARCHAR(10):='DISABLED';
STATUS_ENAB CONSTANTVARCHAR(10):='ENABLED';
STATUS_SYNC CONSTANTVARCHAR(10):='SYNC';
STATUS_CORR CONSTANTVARCHAR(10):='CORRUPT';
Thesubprogramsusedinthepackagearedescribedinthefollowingtable:
DBMS_RESULT_CACHEsubprograms(reference:Oracledocumentation)
BYPASSprocedure
IfsettoTRUE,theresultcacheusageisbypassedinthecurrentoreverysession.UsedwhenmodifyingandrecompilingaPL/SQLfunctionwhoseresultshavebeencachedearlier.InRAC,sinceeachinstancehasitsownservercache,theBYPASSproceduremustberuninallinstances.
FLUSHfunctionandprocedureFlushesoutalltheresultsfromtheservercache.Youcanalsoretainorreleasememoryandstatistics.Defaultactionisrelease.
INVALIDATEfunctionsandprocedures
Invalidatesalltheresultsthataredependentonagivenobject.Returnsthenumberofresultsinvalidated.
INVALIDATE_OBJECTfunctionsandprocedures Invalidatesthespecifiedresultsetintheservercache.
MEMORY_REPORTprocedure Generatesthesummaryreportfortheserverresultcache.Specify(detailed=>TRUE)togenerateadetailedversionofthereport.
STATUSfunction Checksthestatusoftheresultcache.
DisplayingtheresultcachememoryreportYoucangenerateaservercachememoryreportviatheDBMS_RESULT_CACHEpackage.Asamplecachememoryreport(summarizingresultsfromourillustrations)looksasfollows:
CONNECTsys/oracleassysdba
SETSERVEROUTPUTON
/*Generatethecachememoryreport*/
EXECDBMS_RESULT_CACHE.MEMORY_REPORT
ResultCacheMemoryReport
[Parameters]
BlockSize=1Kbytes
MaximumCacheSize=25Mbytes(25Kblocks)
MaximumResultSize=1280Kbytes(1280blocks)
[Memory]
TotalMemory=169392bytes[0.044%oftheSharedPool]
...FixedMemory=5440bytes[0.001%oftheSharedPool]
...DynamicMemory=163952bytes[0.042%oftheSharedPool]
.......Overhead=131184bytes…....CacheMemory=32Kbytes(32blocks)
...........UnusedMemory=26blocks…........UsedMemory=6
blocks…............Dependencies=2blocks(2count)
...............Results=4blocks…................SQL=2blocks(1
count)
...................PLSQL=2blocks(2count)
PL/SQLproceduresuccessfullycompleted.
Theprecedingreportliststhemaximumcachesize,maximumresultsize,andstandardblocksize.Thereportcanbeinterpretedasfollows:
Theresultcacheisallocatedfromthedynamicsectionofthesharedpool.Currently,only169,392bytesareallocatedandthemaximumstretchisupto25MB.FixedmemoryisthememoryconsumedbyMemoryMgr,CacheMgr,StateObjsandBloomFltr.Outof32Kblocks,only6blocksareused.The6usedblocksinclude2fordependencies(1eachbyF_COUNT_OBJandMY_OBJECTS)and4bysub-pools(2bytheSQLqueryresultcacheand2bythePL/SQLfunctionresultcache—2functioncalls).
YoucanalsogenerateadetailedreportbyspecifyingtheDETAILEDparameterasTRUEintheMEMORY_REPORTprocedure:
execdbms_result_cache.memory_report(TRUE);
ResultCacheMemoryReport
[Parameters]
BlockSize=1Kbytes
MaximumCacheSize=25Mbytes(25Kblocks)
MaximumResultSize=1280Kbytes(1280blocks)
[Memory]
TotalMemory=169392bytes[0.044%oftheSharedPool]
...FixedMemory=5440bytes[0.001%oftheSharedPool]
.......MemoryMgr=208bytes…....CacheMgr=256bytes…....BloomFltr
=2Kbytes…....StateObjs=2928bytes…DynamicMemory=163952bytes
[0.042%oftheSharedPool]
.......Overhead=131184bytes…........HashTable=64Kbytes(4K
buckets)
...........ChunkPtrs=24Kbytes(3Kslots)
...........ChunkMaps=12Kbytes…........Miscellaneous=131184
bytes…....CacheMemory=32Kbytes(32blocks)
...........UnusedMemory=26blocks…........UsedMemory=6
blocks…............Dependencies=2blocks(2count)
...............Results=4blocks…................SQL=2blocks(1
count)
...................PLSQL=2blocks(2count)
PL/SQLproceduresuccessfullycompleted.
OracleDatabase12cenhancementstothePL/SQLfunctionResultCacheUntilOracleDatabase11g,resultsfromaPL/SQLfunctioncreatedwithinvoker’srights(thatis,theAUTHIDCURRENT_USERclause)cannotberesult-cached.Therestrictionwasimposedfromasecuritystandpointasthedatabaseuserscanhavedifferentaccesslevelswhichmaycontradicttheresultcachingmechanism.Forinstance,auserFINexecutesaPL/SQLfunctiontoretrievesalarydetailsofadepartmentandaddstheresulttothecache.AnotheruserCLERKinvokesthesamefunctionandgetstheresultsfromthePL/SQLfunctionresultcache.Haditbeenaninvoker’srightsfunction,hewouldhavereceivedanexception.
StartingfromOracleDatabase12c,theinvoker’srightsfunctioncanberesultcached.Theideaisquitesimple.Whileperformingacachelookup,Oraclepassesthecurrentuseralongwiththefunctionsignature.Whileaddingaresulttothecache,theuserinformationisalsocached.Nexttime,wheneverthefunctionisinvoked,thedatabaseverifieswhetherthecurrentuserhasinvokedthisfunctionearlier.Sonowaresultistightlycoupledwiththeuserwhohasaddeditinthecache.Consequently,aresultissharableacrossthesessionsofthesameuser.
Forexample,thefollowingPL/SQLfunctionisaninvoker’srightsfunctionwiththeresultcachefeature:
/*Createaninvokerrightresultcachefunction*/
CREATEORREPLACEFUNCTIONf_count_myobj(obj_typeVARCHAR2)
RETURNNUMBER
AUTHIDCURRENT_USER
RESULT_CACHEIS
l_countNUMBER;
BEGIN
/*Capturetherecordcountinalocalvariable*/
SELECTCOUNT(object_type)
INTOl_count
FROMmy_objects
WHEREobject_type=obj_type;
RETURNl_count;
END;
/
Functioncreated.
ResultcacheinRealApplicationClustersTheOracleDatabaseRealApplicationCluster(RAC)optionallowsthesharingofaclusterdatabaseacrossmultipledatabaseinstances.Itenhancesthescalabilityandavailabilityofdatabaseapplications.
TheResultcache,beingthenativecomponentofdatabaseinstancememory,issupportedonRACenvironments.ThebehaviorandhandlingofresultcachingonRACisthesameasthatofasingleinstancedatabase.HerearethesalientfeaturesofresultcachinginRAC:
EachRACinstancemaintainsalocalversionoftheServerResultCacheinthesharedpooloftheSGAAresultisaddedtotheinstanceresultcachewhenauserexecutesaSQLqueryoraPL/SQLfunctiononadatabaseinstanceIfthesameuserexecutesthesamequeryfromanotherinstance,thecachedresultiscopiedtothatinstance’sresultcacheoverRACinterconnectThedynamicviewGV$RESULT_CACHE_OBJECTSwillshowduplicateentrieswiththesamecacheID,butfordifferentinstances(INST_ID)Ifthetabledataismodifiedorthetableisaltered,theresultisinvalidatedintheServerResultCacheonalltheinstancesoftheclusterWhicheverinstancere-executesthequery,theresultisrebuiltandcachedforthatinstanceonly
SummaryInthischapter,wehaveexploredthecachingmechanismintheOracleDatabaseserver.WesawhowserverresultcachingcandramaticallyimproveperformanceinSQLandPL/SQLapplications.WelearnedhowtoconfiguretheServerResultCache,howtoenablemanualandautomaticSQLqueryresultcaches,andhowtoworkwiththePL/SQLfunctionresultcache.
Inthenextchapter,wewilllearnaboutPL/SQLcodeprofilingandtracingtechniques.
PracticeexerciseTheinitializationparametersettingsforyourdatabaseareasfollows:
MEMORY_TARGET=500M
RESULT_CACHE_MODE=MANUAL
RESULT_CACHE_MAX_SIZE=0
YouexecuteaquerybyusingtheRESULT_CACHEhint.Whichstatementistrueinthisscenario?
1. Thequeryresultsarenotstoredinthecachebecausenomemoryisallocatedfortheresultcache.
2. ThequeryresultsarestoredinthecachebecauseOracleimplicitlymanagesthecachememory.
3. ThequeryresultsarenotstoredinthecachebecauseRESULT_CACHE_MODEisMANUAL.
4. ThequeryresultsarestoredinthecacheautomaticallywhenRESULT_CACHE_MODEisMANUAL.
Yousetthefollowinginitializationparametersettingsforyourdatabase:
MEMORY_TARGET=500M
RESULT_CACHE_MODE=FORCE
RESULT_CACHE_MAX_SIZE=200M
Youexecutethefollowingquery:
SELECT/*+RESULT_CACHE*/ENAME,DEPTNO
FROMEMPLOYEES
WHEREEMPNO=7844
/
Whichofthefollowingstatementsaretrue?
1. ThequeryresultsarecachedbecauseSQLusestheRESULT_CACHEhint.2. ThequeryresultsarecachedbecausetheresultcachemodeisFORCE.3. ThequeryresultsarenotcachedbecauseSQLusestheRESULT_CACHEhint.4. TheRESULT_CACHEhintisignoredwhentheresultcachemodeisFORCE.
Thecachedqueryresultbecomesinvalidwhenthedataaccessedbythequerygetsmodified.
1. True.2. False.
TheSQLqueryresultcacheispersistentonlyforthecurrentsession.
1. True.2. False.
WhichofthefollowingPL/SQLobjectresultscannotbecached?
1. AStandalonefunction.2. AProcedure.3. Afunctionlocaltoaprocedure.4. APackagedfunction.
TheRELIES_ONclauseinthePL/SQLfunctionresultcachecanbeusedtospecifythedependenttablesorviewswhosestatewouldaffectthecachedresult.
1. True.2. False.
Serversettingsareasfollows:
MEMORY_TARGET=500M
RESULT_CACHE_MODE=FORCE
RESULT_CACHE_MAX_SIZE=200M
IdentifytheSQLquerieswhoseresultscannotbecachedbytheserver.
1. SELECTename,salFROMemployeesWHEREempno=7900;2. SELECTseq_empid.nextvalFROMDUAL;3. SELECTename,sysdate,hiredateFROMemployees;4. SELECTdname,locFROMdepartmentsWHEREdeptno=10;
IdentifythecorrectstatementsaboutthePL/SQLfunctionresultcache.
1. ThePL/SQLfunctionresultcacherequiresadditionalserverconfiguration.2. ThePL/SQLfunctionresultcachecannotbeoperatedonprocedures.3. ThePL/SQLfunctionresultcacheworkswithallcategoriesoffunctions.4. ThePL/SQLfunctionresultcachefeaturescanworkwithfunctionsthattake
collectiontypearguments.
IdentifytheadmissiblevalueoftheSTATUScolumninV$RESULT_CACHE_OBJECTS.
1. PUBLISHED.2. INVALID.3. USED.4. UNUSED.
Choosethecorrectstatementaboutthefollowingsamplecachememorystatisticsreport:
IDNAMEVALUE
---------------------------------------------
1BlockSize(Bytes)1024
2BlockCountMaximum204800
3BlockCountCurrent32
4ResultSizeMaximum(Blocks)40960
5CreateCountSuccess1
6CreateCountFailure0
7FindCount0
8InvalidationCount0
9DeleteCountInvalid0
10DeleteCountValid0
11HashChainLength1
1. CreateCountSuccessisthecountofsuccessfullycachedresults.2. FindCountisthecountofthesuccessfullycachedresultsfoundandusedinthe
queries.3. InvalidationCountisthecountoftheinvalidatedcachedresults.4. BlockCountMaximumisthestaticvalueoftotalblocksavailableinthecache
memory.
Chapter10.Analyzing,Profiling,andTracingPL/SQLCodeDuringthedatabasedevelopmentstageandevenafter,thedevelopersarerequiredtoanalyzeandmaintainthedatabaseobjects.AnalyzingthePL/SQLcodeisanessentialexercisethatenablesyoutodrawoutkeyinformationaboutaprogram.PL/SQLcodeanalysiscanbehelpthedevelopersin:trackingobjectdependencies,unusedvariables,retrievingcompilationsettings,trackingprogramexecutionflow,andbuildingtheperformanceprofileofanobject.
Oracleprovidesapowerfulsetofmetadatasources,knownasdictionaryviews,torevealthemetadataofPL/SQLobjects.Foralltheobjectsthatarecreated,modified,orcompiledinadatabase,Oraclecapturesthemetadataandcontinuestoupdateitateachaction.ThischapterwillfocusonhowtoanalyzeaPL/SQLcodeunit,howtotracetheprogramexecution,andhowtoprofileitinaverysimplisticway.Inthischapter,wewilllearntechniquesto:
AnalyzePL/SQLmetadatainformationthroughdictionaryviewsTracePL/SQLprogramexecutionflowProfilePL/SQLcodeforperformance
AsamplePL/SQLprogramBeforeweplungeintocodeanalysistechniques,letuswritedownastandardPL/SQLprogramfordemonstratingcodeanalysis,profiling,andtracing.ThefollowingPL/SQLprocedurecalculatesthescoreofauserinanexam(Notethatnegativescoringisapplicable).TheprocedureP_CALC_USER_POINTSdeclaresalocalfunctionandaproceduretocalculatethepoints:
/*CreateaPL/SQLprocedure*/
CREATEORREPLACEPROCEDUREp_calc_user_points
(p_userVARCHAR2DEFAULTUSER,p_correctNUMBER,p_wrongNUMBER)
IS
l_numNUMBER;
/*AlocalfunctionF_CALC_POINTS*/
FUNCTIONf_calc_points(p_quesNUMBER,p_factorNUMBER)
RETURNNUMBER
IS
BEGIN
RETURN(p_ques*p_factor);
END;
/*Alocalprocedure*/
PROCEDUREP_NET_CALC(p_net_pointsOUTNUMBER)IS
BEGIN
p_net_points:=f_calc_points(p_correct,4)+f_calc_points(p_wrong,-2);
END;
/*Mainprocedurebody*/
BEGIN
p_net_calc(l_num);
DBMS_OUTPUT.PUT_LINE(USER||'earned'||TO_CHAR(l_num)||'points');
END;
/
WewillnowquerytheOracle-supplieddictionaryviewstofindwaystotrackPL/SQLprogrampropertiessuchasargumentdetails,identifierusage,andobjectcompilationsettings.
TrackingPL/SQLcodinginformationTheOracle-supplieddictionaryviewsareagreatsourceofinformationforperformingdrill-downanalysisofPL/SQLcode.AlthoughthereareseveraldictionariesthatstorePL/SQLobjectinformation,theimportantonesareUSER_ARGUMENTS,USER_OBJECTS,USER_SOURCE,USER_PROCEDURES,andUSER_DEPENDENCIES.TheseviewsalsohavetheirALL_*andDBA_*counterparts.Foryourreference,theUSER,ALL,andDBAcategoryviewsaredescribedasfollows:
USER:ContainsonlytheobjectsthatareownedbyauserALL:ContainstheobjectsthatcanbeaccessedbyauserDBA:ContainsalltheobjectsaccessiblebytheSYSuserorauserwithDBAprivileges
YoucanquerythedatadictionaryviewsfromtheDICTIONARYviewandtheircolumnstructurefromDICT_COLUMNSview.LetusquerythemetadatainformationoftheprocedureP_CALC_USER_POINTSinthesedictionaryviews.
USER_ARGUMENTSTheUSER_ARGUMENTSviewcapturestheargumentinformationofaPL/SQLprogram.Theargumentinformationincludesthepositionofanargumentintheparameterlist,itsdatatype,defaults,andpassmode.
NoteUsageofaNOCOPYhintinanOUTorINOUTparameterisnottrackedinUSER_ARGUMENTS
Thefollowingquerylistsargument_name,itsposition,passmode,data_type,anddefault.
/*QuerytheargumentsoftheprocedureP_CALC_USER_POINTS*/
SELECTargument_name,data_type,defaulted,position,data_level,in_out,
pls_type
FROMuser_arguments
WHEREobject_nameIN('P_CALC_USER_POINTS')
ORDERBYposition
/
ARGUMENT_NAMEDATA_TYPEDPOSITIONDATA_LEVELIN_OUTPLS_TYPE
--------------------------------------------------------
P_USERVARCHAR2Y10INVARCHAR2
P_CORRECTNUMBERN20INNUMBER
P_WRONGNUMBERN30INNUMBER
Intheprecedingqueryresult,theDATA_LEVELrepresentsthelevelofnestinginacompositedatatype.Sincetheprocedurehadscalardatatypesonly,DATA_LEVELiszero.
USER_OBJECTSTheUSER_OBJECTSdictionaryviewistheprimarysourcetocheckthevalidityofaPL/SQLobject.Theviewalsoincludesrelevantdetailssuchascreationandlastupdatetimestamps,namespace,andedition.
/*QuerytheobjectpropertiesofP_CALC_USER_POINTS*/
SELECTobject_id,object_type,status,namespace
FROMuser_objects
WHEREobject_name='P_CALC_USER_POINTS'
/
OBJECT_IDOBJECT_TYPESTATUSNAMESPACE
--------------------------------------------
81410PROCEDUREVALID1
TheORACLE_MAINTAINEDcolumnofthedictionaryviewdeterminesifagivenobjectismanagedbytheOracleDatabaseortheuser.AlltheOracle-suppliedpackages(suchasSTANDARD,DBMS_OUTPUTandallothers)aremaintainedimplicitlybyOracleandcanbequeriedfromALL_OBJECTS.
USER_OBJECT_SIZETheUSER_OBJECT_SIZEviewprovidesthesize(inbytes)ofthesourcecode,parsedcodeandcompiledcodeofaPL/SQLobject.Thesizeinformationcanbequiterelevant,iftheprograminvocationresultsinout-of-memoryissues.DatabasedeveloperscandetermineifalargeprogramcanbebrokendownintosmallersubprogramsormultiplemodulescanbeclubbedunderasinglePL/SQLunit.
ThefollowingqueryshowsthesizeoftheP_CALC_USER_POINTSprocedure:
/*QuerythecodesizeofprocedureP_CALC_USER_POINTS*/
SELECTtype,source_size,parsed_size,code_size,error_size
FROMuser_object_size
WHEREname='P_CALC_USER_POINTS'
/
TYPESOURCE_SIZEPARSED_SIZECODE_SIZEERROR_SIZE
---------------------------------------------------
PROCEDURE47210968270
Intheprecedingoutput,ERROR_SIZEisthesizeoftheerrormessagesraisedduringcodecompilation.
USER_SOURCETheUSER_SOURCEdictionaryviewprovidesthetextsourcecodeofaPL/SQLobject.Thisviewcanbehandyinbuildingupatext-basedcodesearchengine.
ThefollowingqueryshowstheprogrambodyoftheprocedureP_CALC_USER_POINTS:
/*QuerythesourcecodeofP_CALC_USER_POINTS*/
SELECTline,text
FROMuser_source
WHEREname='P_CALC_USER_POINTS'
ORDERBYline
/
LINETEXT
------------------------------------------------------------
1PROCEDUREp_calc_user_points
2(p_userVARCHAR2DEFAULTUSER,p_correctNUMBER,p_wrongNUMBER)
3IS
4l_numNUMBER;
5FUNCTIONf_calc_points(p_quesNUMBER,p_factorNUMBER)
6RETURNNUMBER
7IS
8BEGIN
9RETURN(p_ques*p_factor);
10END;
11
12PROCEDUREP_NET_CALC(p_net_pointsOUTNUMBER)IS
13BEGIN
14p_net_points:=f_calc_points(p_correct,4)+f_calc_points
(p_wrong,-2);
15END;
16
17BEGIN
18p_net_calc(l_num);
19DBMS_OUTPUT.PUT_LINE(USER||'earned'||TO_CHAR(l_num)||'points');
20END;
20rowsselected.
ThefollowingSELECTqueryfindstheobjectsthathavecustomizedexceptionhandlingthroughRAISE_APPLICATION_ERROR:
/*Querytobuildtextbasedcodesearch*/
SELECTDISTINCTowner,name
FROMall_source
WHEREUPPER(text)LIKE'%RAISE_APPLICATION_ERROR%'
/
OWNERNAME
---------------------------------------------
SYSUTL_SMTP
SYSDBMS_STANDARD
SYSUTL_HTTP
APEX_040200WWV_FLOW_ERROR_API
USER_PROCEDURESTheUSER_PROCEDURESdictionaryviewcapturesthesubprogrampropertiesofanobject.Contrarytoitsname(whichjustsays“procedures”),itdisplaysthebehavioralaspectssuchasaggregate,pipelined,parallel,deterministic,orprivilegeauthenticationofnotjustprocedures,butalsoofPL/SQLfunctionsandPL/SQLpackages.
TheproceduralpropertiesoftheP_CALC_USER_POINTSsubprogramcanbequeriedfromtheviewasfollows:
/*QuerythesubprogrampropertiesofP_CALC_USER_POINTS*/
SELECTobject_type,
aggregate,
pipelined,
parallel,
interface,
deterministic,
authid
FROMuser_procedures
WHEREobject_name='P_CALC_USER_POINTS'
/
OBJECT_TYPEAGGPIPPARINTDETAUTHID
----------------------------------------
PROCEDURENONONONONODEFINER
USER_PLSQL_OBJECT_SETTINGSandUSER_STORED_SETTINGSTheUSER_PLSQL_OBJECT_SETTINGSandUSER_STORED_SETTINGSviewsareusedtodisplaythecompilationparametervaluesofaPL/SQLobject.ThedifferencebetweenthetwoviewsisthattheUSER_PLSQL_OBJECT_SETTINGSviewcontainsacolumnforeachcompilationparameter,whiletheUSER_STORED_SETTINGSviewstoresparametervaluesasakey-valuepair(theparameternameasthekey)foraPL/SQLprogram.
Let’scheckthevalueofcompilationparametersfrombothoftheviews.ThefollowingSELECTpivotqueryshowsthecompilationparametervaluesfortheprocedureP_CALC_USER_POINTS:
/*QuerythecompilationparametersforP_CALC_USER_POINTS*/
SELECTname,pname,pval
FROMuser_plsql_object_settings
UNPIVOTINCLUDENULLS
(
pvalFOR(pname)IN
(
PLSQL_CODE_TYPEas'PLSQL_CODE_TYPE',
PLSQL_DEBUGas'PLSQL_DEBUG',
PLSQL_WARNINGSas'PLSQL_WARNINGS',
NLS_LENGTH_SEMANTICSas'NLS_LENGTH_SEMANTICS',
PLSQL_CCFLAGSas'PLSQL_CCFLAGS',
PLSCOPE_SETTINGSas'PLSCOPE_SETTINGS'
)
)
WHEREname='P_CALC_USER_POINTS'
/
NAMEPNAMEPVAL
--------------------------------------------------------
P_CALC_USER_POINTSPLSQL_CODE_TYPNATIVE
P_CALC_USER_POINTSPLSQL_DEBUGFALSE
P_CALC_USER_POINTSPLSQL_WARNINGSDISABLE:ALL
P_CALC_USER_POINTSNLS_LENGTH_SEMANTICSBYTE
P_CALC_USER_POINTSPLSQL_CCFLAGS
P_CALC_USER_POINTSPLSCOPE_SETTINGSIDENTIFIERS:ALL
6rowsselected.
/*QuerythecompilationparametersforP_CALC_USER_POINTS*/
SELECTobject_name,param_name,param_value
FROMuser_stored_settings
WHEREobject_name='P_CALC_USER_POINTS'
/
OBJECT_NAMEPARAM_NAMEPARAM_VALUE
---------------------------------------------------------------
P_CALC_USER_POINTSplsql_optimize_level2
P_CALC_USER_POINTSplsql_code_typeNATIVE
P_CALC_USER_POINTSplsql_debugFALSE
P_CALC_USER_POINTSnls_length_semanticsBYTE
P_CALC_USER_POINTSplsql_warningsDISABLE:ALL
P_CALC_USER_POINTSplsql_ccflags
P_CALC_USER_POINTSplscope_settingsIDENTIFIERS:ALL
P_CALC_USER_POINTSplsql_compiler_flagsNATIVE,NON_DEBUG
8rowsselected.
USER_DEPENDENCIESTheUSER_DEPENDENCIESdictionaryviewgivesyouthelistofobjectsonwhichagivenPL/SQLsubprogramisdependent.Ifanyofthesedependentobjectsgetsinvalidated,thePL/SQLprogramwillalsobeinvalidated.ThefollowingqueryliststheobjectsthatarereferencedintheP_CALC_USER_POINTSfunction:
/*QuerythedependentobjectsofP_CALC_USER_POINTS*/
SELECTreferenced_owner,
referenced_namername,
referenced_typertype,
dependency_typedtype
FROMuser_dependencies
WHEREname='P_CALC_USER_POINTS'
/
OWNERRNAMERTYPEDTYP
----------------------------------------------------
SYSSTANDARDPACKAGEHARD
SYSSYS_STUB_FOR_PURITY_ANALYSISPACKAGEHARD
PUBLICDBMS_OUTPUTSYNONYMHARD
TheDBMS_DESCRIBEpackageTheDBMS_DESCRIBEpackageisanOraclesuppliedpackagethatisusedtodescribethestructureofaPL/SQLobject.Intermsoffunctionality,theDBMS_DESCRIBEpackagegivesinformationthatissimilartoUSER_ARGUMENTSorUSER_PROCEDURES,butitisusedwheretheprogramstructurehastobeexposedbasedonaclientrequest.ItisownedbySYSanditspublicsynonymisavailabletoallusers.
TheDBMS_DESCRIBEpackagecontainsonesubprogramDESCRIBE_PROCEDUREandusesassociativearraystocapturethePL/SQLobjectstructure.
TYPEVARCHAR2_TABLEISTABLEOFVARCHAR2(30)
INDEXBYBINARY_INTEGER;
TYPENUMBER_TABLEISTABLEOFNUMBER
INDEXBYBINARY_INTEGER;
ThefollowingPL/SQLblockretrievesthesignatureofthePL/SQLprocedureP_CALC_USER_POINTS:
SETSERVEROUTPUTON
DECLARE
/*Declarethelocalvariablesofassociativearraytype*/
v_overloadDBMS_DESCRIBE.NUMBER_TABLE;
v_positionDBMS_DESCRIBE.NUMBER_TABLE;
v_levelDBMS_DESCRIBE.NUMBER_TABLE;
v_arg_nameDBMS_DESCRIBE.VARCHAR2_TABLE;
v_datatypeDBMS_DESCRIBE.NUMBER_TABLE;
v_def_valueDBMS_DESCRIBE.NUMBER_TABLE;
v_in_outDBMS_DESCRIBE.NUMBER_TABLE;
v_lengthDBMS_DESCRIBE.NUMBER_TABLE;
v_precisionDBMS_DESCRIBE.NUMBER_TABLE;
v_scaleDBMS_DESCRIBE.NUMBER_TABLE;
v_radixDBMS_DESCRIBE.NUMBER_TABLE;
v_spareDBMS_DESCRIBE.NUMBER_TABLE;
BEGIN
/*CalltheprocedureDESCRIBE_PROCEDUREforP_CALC_USER_POINTS*/
DBMS_DESCRIBE.DESCRIBE_PROCEDURE
(object_name=>'P_CALC_USER_POINTS',
reserved1=>null,
reserved2=>null,
overload=>v_overload,
position=>v_position,
level=>v_level,
argument_name=>v_arg_name,datatype=>v_datatype,
default_value=>v_def_value,
in_out=>v_in_out,
length=>v_length,
precision=>v_precision,
scale=>v_scale,
radix=>v_radix,
spare=>v_spare,
include_string_constraints=>null);
FORiINv_arg_name.FIRST..v_arg_name.LAST
LOOP
DBMS_OUTPUT.PUT_LINE(RPAD('_',40,'_'));
/*Checkifthepositionifzeroornot*/
IFv_position(i)=0THEN
/*ZeropositionisreservedforRETURNtypes*/
DBMS_OUTPUT.PUT_LINE('RETURNtypeofthefunction:');
DBMS_OUTPUT.PUT_LINE(rpad('FunctionReturntype:',30,'
')||v_datatype(i));
ELSE
/*Printtheargumentname*/
DBMS_OUTPUT.PUT_LINE(RPAD('Parametername:',30,'')||v_arg_name(i));
ENDIF;
/*Displaytheposition,typeandmodeofparameters*/
DBMS_OUTPUT.PUT_LINE(rpad('Parameterposition:',30,'')||
v_position(i));
DBMS_OUTPUT.PUT_LINE(rpad('Parameterdatatype:',30,'')||
casev_datatype(i)
when1then'VARCHAR2'
when2then'NUMBER'
when3then'BINARY_INTEGER'
when8then'LONG'
when11then'ROWID'
when12then'DATE'
when23then'RAW'
when24then'LONGRAW'
when58then'OPAQUETYPE'
when96then'CHAR'
when106then'LONGRAW'
when121then'OBJECT'
when122then'NESTEDTABLE'
when123then'VARRAY'
when178then'TIME'
when179then'TIMEWITHTIMEZONE'
when180then'TIMESTAMP'
when230then'PL/SQLRECORD'
when251then'PL/SQLTABLE'
when252then'PL/SQLBOLLEAN'
end);
DBMS_OUTPUT.PUT_LINE(rpad('Parameterdefault:',30,'')||
casev_def_value(i)
when0then'NoDefault'
when1then'Defaulted'
end);
DBMS_OUTPUT.PUT_LINE(rpad('Parameterpassmode:',30,'')||
casev_in_out(i)
when0then'INmode'
when1then'OUTmode'
when2then'INOUTmode'
end);
DBMS_OUTPUT.PUT_LINE(rpad('_',40,'_'));
ENDLOOP;
END;
/
________________________________________
Parametername:P_USER
Parameterposition:1
Parameterdatatype:VARCHAR2
Parameterdefault:Defaulted
Parameterpassmode:INmode
________________________________________
________________________________________
Parametername:P_CORRECT
Parameterposition:2
Parameterdatatype:NUMBER
Parameterdefault:NoDefault
Parameterpassmode:INmode
________________________________________
________________________________________
Parametername:P_WRONG
Parameterposition:3
Parameterdatatype:NUMBER
Parameterdefault:NoDefault
Parameterpassmode:INmode
________________________________________
PL/SQLproceduresuccessfullycompleted.
TrackingtheprogramexecutionsubprogramcallstackThecallstackinformationletsyoudeterminethestagesofprogramexecution.Aprogramcallstackincludesthenestedinformationofthereferencedsubprograms.YoucantrackthecallstackforaprogramusingtheDBMS_UTILITY.FORMAT_CALL_STACKfunctionorUTL_CALL_STACKpackage.
ThefunctionFORMAT_CALL_STACKreturnsthecurrentcallstackinformation,whichincludestheobjecthandlenumber,linenumber,andthenameofthesubprogram.
Let’screatethreestandaloneprocedures:P1,P2,andP3.P3invokesP2,whileP2invokesP1.BythetimetheprogramcontrolreachesP1,thecallstackincludesP1,P3andP2.
/*CreatetheprocedureP1*/
CREATEORREPLACEPROCEDUREP1
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('ExecutingP1..');
DBMS_OUTPUT.PUT_LINE(RPAD('~',15,'~'));
DBMS_OUTPUT.PUT_LINE(dbms_utility.format_call_Stack);
END;
/
/*CreatetheprocedureP2*/
CREATEORREPLACEPROCEDUREP2
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('ExecutingP2..');
DBMS_OUTPUT.PUT_LINE('CallingP1..');
DBMS_OUTPUT.PUT_LINE(RPAD('~',15,'~'));
/*CallprocedureP1*/
P1;
END;
/
/*CreatetheprocedureP3*/
CREATEORREPLACEPROCEDUREP3
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('ExecutingP3..');
DBMS_OUTPUT.PUT_LINE('CallingP2..');
DBMS_OUTPUT.PUT_LINE(RPAD('~',15,'~'));
/*CallprocedureP2*/
P2;
END;
/
/*Enabletheserveroutputtodisplaytheerrormessages*/
SETSERVEROUTPUTON
/*StartaPL/SQLblocktoinvokeP3*/
BEGIN
/*CallP3*/
P3;
END;
/
ExecutingP3..
CallingP2..
~~~~~~~~~~~~~~~
ExecutingP2..
CallingP1..
~~~~~~~~~~~~~~~
ExecutingP1..
~~~~~~~~~~~~~~~
-------PL/SQLCallStack-------
objecthandlelinenumberobjectname
0xec4c4ce06procedureSCOTT.P1
0xec4382208procedureSCOTT.P2
0xe4e004488procedureSCOTT.P3
0xe4c982981anonymousblock
PL/SQLproceduresuccessfullycompleted.
Intheprecedingprogramoutput,youcanchecktheprogramexecutionflowfromP3toP2,followedbyP1.ButoneissuewiththeFORMAT_CALL_STACKoutputistheinabilitytoextractthedrill-downuptolocalroutineinformationanduseitfordebuggingtasks.
OracleDatabase12cintroducesanewAPI,knownasUTL_CALL_STACK,togiveastructuredcallstackaswellaserrorstack.Thestructuredcallstackoutputallowsdeveloperstoextracttheinformationanduseitfordebugpurposes.
TheprocedureSHOW_CALL_STACKusestheUTL_CALL_STACKsubprogramstodisplaythestructuredcallstackinformation:
/*CreatetheproceduretoprintcallstackusingUTL_CALL_STACK*/
CREATEORREPLACEPROCEDUREshow_call_stack
is
lvlPLS_INTEGER;
BEGIN
/*Retrievethedynamicdepthofthecallstack*/
lvl:=UTL_CALL_STACK.DYNAMIC_DEPTH();
/*Iteratethecalldepthstructure*/
FORiIN1..lvlLOOP
DBMS_OUTPUT.put_line(
RPAD('Calldepth:'||UTL_CALL_STACK.lexical_depth(i),15)||
RPAD('Line:'||TO_CHAR(UTL_CALL_STACK.unit_line(i),'99'),15)||
UTL_CALL_STACK.CONCATENATE_SUBPROGRAM
(UTL_CALL_STACK.SUBPROGRAM(i))
);
ENDLOOP;
END;
/
Intheprecedingprocedure:
DYNAMIC_DEPTHdenotesthenumberofsubprogramsinthecallstackLEXICAL_DEPTHistherelativecalldepthwithinasubprogramUNIT_LINEisthelinenumberwherethecallstatementismadeSUBPROGRAMreturnsthenameofthesubprogramcurrentlyunderexecutionCONCATENATE_SUBPROGRAMconcatenatesasubprogramnametoitscallingprogram
P_CALC_POINT_CALLSTACKinvokesSHOW_CALL_STACKtoprintthestructuredcallstack:
/*CreateaproceduretoinvokeSHOW_CALL_STACK*/
CREATEORREPLACEPROCEDUREp_calc_point_callstack
(p_userVARCHAR2,p_correctNUMBER,p_wrongNUMBER)
IS
l_numNUMBER;
FUNCTIONf_calc_points(p_quesNUMBER,p_factorNUMBER)
RETURNNUMBER
IS
BEGIN
/*InvokeSHOW_CALL_STACK*/
show_call_stack;
RETURN(p_ques*p_factor);
END;
PROCEDUREp_net_calc(p_net_pointsOUTNUMBER)IS
BEGIN
p_net_points:=f_calc_points(p_correct,4)+f_calc_points(p_wrong,-2);
END;
BEGIN
p_net_calc(l_num);
DBMS_OUTPUT.PUT_LINE(USER||'earned'||TO_CHAR(l_num)||'points');
end;
/
ExecutetheprecedingprocedureinaPL/SQLblock:
SETSERVEROUTPUTON
BEGIN
p_calc_point_callstack(user,10,3);
END;
/
Calldepth:1Line:10P_CALC_POINT_CALLSTACK.F_CALC_POINTS
Calldepth:1Line:15P_CALC_POINT_CALLSTACK.P_NET_CALC
Calldepth:0Line:18P_CALC_POINT_CALLSTACK
Calldepth:0Line:2__anonymous_block
Calldepth:0Line:6SHOW_CALL_STACK
Calldepth:1Line:10P_CALC_POINT_CALLSTACK.F_CALC_POINTS
Calldepth:1Line:15P_CALC_POINT_CALLSTACK.P_NET_CALC
Calldepth:0Line:18P_CALC_POINT_CALLSTACK
Calldepth:0Line:2__anonymous_block
SCOTTearned34points
PL/SQLproceduresuccessfullycompleted.
Theprecedingoutputshowsthecallstackinlast-in-first-outorder.Toreadthestackfrom
TrackingpropagatingexceptionsinPL/SQLcodeTraditionally,databasedevelopersarekeentouseSQLERRMandSQLCODEtofindanexceptioncodeandmessage.Inamodularprogrammingapproach,PL/SQLprogramsinvokeroutinesanditmayhappenthataroutinecallfailswithanexception.Theexceptionpropagatestothecallingblockandtraversesthroughmultipleblocksinsearchofitshandler.
Ifyouwanttotrackthepathofpropagatingexceptions,youcaneitherusetheFORMAT_ERROR_BACKTRACEfunctionfromDBMS_UTILITYorthenewUTL_CALL_STACKpackage.
ThePL/SQLprocedurehereraisesuser-definedexceptionstodemonstratetheworkingofback-tracingtheexceptions:
/*Createaproceduretotraceprinterrorstack*/
CREATEORREPLACEPROCEDUREp_calc_point_errStack
(p_userVARCHAR2,p_correctNUMBER,p_wrongNUMBER)
IS
l_numNUMBER;
/*Declareuserdefinedexceptions*/
myFunExpEXCEPTION;
myProcExpEXCEPTION;
myBlkExpEXCEPTION;
PRAGMAEXCEPTION_INIT(myFunExp,-20020);
PRAGMAEXCEPTION_INIT(myProcExp,-20021);
PRAGMAEXCEPTION_INIT(myBlkExp,-20022);
/*Explicitlyraisetheuserdefinedexceptioninthelocalfunction*/
FUNCTIONf_calc_points(p_quesNUMBER,p_factorNUMBER)
RETURNNUMBER
IS
BEGIN
RAISEmyFunExp;
RETURN(p_ques*p_factor);
EXCEPTION
WHENmyFunExpTHEN
RAISEmyProcExp;
END;
/*Explicitlyraisetheuserdefinedexceptioninthelocalprocedure*/
PROCEDUREp_net_calc(p_net_pointsOUTNUMBER)IS
BEGIN
p_net_points:=f_calc_points(p_correct,4)+f_calc_points(p_wrong,-2);
EXCEPTION
WHENmyProcExpTHEN
RAISEmyBlkExp;
END;
/*Explicitlyraisetheuserdefinedexceptionintheprogrambody*/
BEGIN
p_net_calc(l_num);
DBMS_OUTPUT.PUT_LINE(USER||'earned'||to_char(l_num)||'points');
EXCEPTION
WHENmyBlkExpTHEN
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END;
/
Uponexecution,theblockgivesthefollowingoutput:
SETSERVEROUTPUTON
BEGIN
p_calc_point_errstack(USER,10,3);
END;
/
ORA-06512:at"SCOTT.P_CALC_POINTS_ERRSTACK",line28
ORA-06512:at"SCOTT.P_CALC_POINTS_ERRSTACK",line20
ORA-06512:at"SCOTT.P_CALC_POINTS_ERRSTACK",line32
PL/SQLproceduresuccessfullycompleted.
Notethat,sincetheexceptionintheinnerblockisnothandledintheexceptionsectionsoftheouterblocks,itpropagatesthroughthelinenumbers19(F_CALC_POINTS),27(P_NET_CALC),and31(P_CALC_POINTS_ERRSTACK).
Onceagain,FORMAT_ERROR_BACKTRACEpresentsanoutputwhichishardtoparseanddoesn’tincludethenamesoflocalsubprograms.Let’sre-writetheprogramusingUTL_CALL_STACK.
ThefollowingprocedureDISPLAY_ERROR_STACKshowstheerrorstackalongwiththeerrornumbersraisedintheerrorblock:
/*CreateaproceduretoprinterrorstackusingUTL_CALL_STACK*/
CREATEORREPLACEPROCEDUREdisplay_error_stackAS
l_depthPLS_INTEGER;
BEGIN
/*Retrievethecountoftheerrorstack*/
l_depth:=UTL_CALL_STACK.ERROR_DEPTH;
/*Iteratetheerrorstackstructuretoprinterrors*/
FORiIN1..l_depthLOOP
DBMS_OUTPUT.put_line(
RPAD(i,10)||
RPAD('ORA-'||LPAD(UTL_CALL_STACK.error_number(i),5,'0'),10)||
UTL_CALL_STACK.error_msg(i)
);
ENDLOOP;
END;
/
Intheprecedingprogramcode:
ERROR_DEPTHisthecountoferrorsintheerrorstackERROR_NUMBERandERROR_MSGaretheerrornumberandstatementoftheerrorinthestack
/*RewritetheprocedurallogictoinvokeDISPLAY_ERROR_STACK*/
CREATEORREPLACEPROCEDUREp_calc_point_errStack
(p_userVARCHAR2,p_correctNUMBER,p_wrongNUMBER)
IS
l_numNUMBER;
/*Declareuser-definedexceptions*/
myFunExpEXCEPTION;
myProcExpEXCEPTION;
myBlkExpEXCEPTION;
PRAGMAEXCEPTION_INIT(myFunExp,-20020);
PRAGMAEXCEPTION_INIT(myProcExp,-20021);
PRAGMAEXCEPTION_INIT(myBlkExp,-20022);
/*Explicitlyraisetheuserdefinedexceptioninthelocalfunction*/
FUNCTIONf_calc_points(p_quesNUMBER,p_factorNUMBER)
RETURNNUMBER
IS
BEGIN
RAISEmyFunExp;
RETURN(p_ques*p_factor);
EXCEPTION
WHENmyFunExpTHEN
RAISEmyProcExp;
END;
/*Explicitlyraisetheuserdefinedexceptioninthelocalprocedure*/
PROCEDUREp_net_calc(p_net_pointsOUTNUMBER)IS
BEGIN
p_net_points:=f_calc_points(p_correct,4)+f_calc_points
(p_wrong,-2);
EXCEPTION
WHENmyProcExpTHEN
RAISEmyBlkExp;
END;
/*Explicitlyraisetheuserdefinedexceptionintheprogrambody*/
BEGIN
p_net_calc(l_num);
DBMS_OUTPUT.PUT_LINE(USER||'earned'||to_char(l_num)||'points');
EXCEPTION
WHENmyBlkExpTHEN
display_error_stack;
END;
/
ExecutetheprocedureP_CALC_POINT_ERRSTACK:
SETSERVEROUTPUTON
BEGIN
p_calc_point_errStack(user,10,3);
END;
/
1ORA-20022
2ORA-06512at"SCOTT.P_CALC_POINT_ERRSTACK",line27
3ORA-20021
4ORA-06512at"SCOTT.P_CALC_POINT_ERRSTACK",line19
5ORA-20020
PL/SQLproceduresuccessfullycompleted.
DeterminingidentifiertypesandusagesAlexicalunitinaPL/SQLprogramcodeisbuiltupusingliterals,identifiers,delimiters,andcomments.AllitemsthataredeclaredinaPL/SQLprogramasvariables,cursors,constants,andsubprogramnamesareidentifiers.Identifierscanbereservedwords(suchasBEGINandEND),predefined(declaredgloballywithinSTANDARDpackage),orquoted.
USER_IDENTIFIERSTheUSER_IDENTIFIERSdictionaryviewreportstheusageofidentifiersinaPL/SQLprogramunit.Theviewincludesinformationaboutanidentifier’sname,itstype,andusagebylinenumberinaPL/SQLprogram.
Trackingidentifierdetailsforallthesubprogramswouldbeadditionaltaskduringcodecompilationandtherefore,itiscollectedonlyforenabledPL/SQLobjects.
ThestructureoftheUSER_IDENTIFIERSviewisasfollows:
NameNull?Type
-----------------------------------------------
NAMEVARCHAR2(128)
SIGNATUREVARCHAR2(32)
TYPEVARCHAR2(18)
OBJECT_NAMENOTNULLVARCHAR2(128)
OBJECT_TYPEVARCHAR2(13)
USAGEVARCHAR2(11)
USAGE_IDNUMBER
LINENUMBER
COLNUMBER
USAGE_CONTEXT_IDNUMBER
ORIGIN_CON_IDNUMBER
Keypointstonote:
TheSIGNATUREistheuniquecodeofanidentifieranddifferentiatesidentifierswiththesamenameUseofanidentifiercanbeDECLARATION,DEFINITION,ASSIGNMENT,CALL,orREFERENCE
UseofanidentifierinaprogramunitisuniquelyidentifiedbyitsUsageIDorthecombinationofline,column,andusageTheUSAGE_CONTEXT_IDestablishesaself-referencingintegritywiththeusageID
ThePL/ScopetoolThePL/ScopetoolwasintroducedinOracleDatabase11gtocapturetheuseofidentifiersinaPL/SQLprogram.TheidentifierdetailsarestoredintheSYSAUXtablespaceandcanbequeriedfromtheUSER_IDENTIFIERSdictionaryview(oritsALL_*orDBA_*views).
NoteYoucanusethePL/ScopetoolfromSQLDeveloper.
KeyfeaturesofthePL/Scopetoolareasfollows:
Thefeaturecanbeenabledatthedatabaseinstanceorsessionlevel.APL/SQLsubprogramcanbecompiledforPL/Scope.ThePL/Scopetoolcannotcaptureinformationforobfuscatedsubprograms.ThePL/ScopetoolcannotcollecttheidentifierinformationiftheSYSAUXtablespaceisabsent.However,noerrorisraisedbutawarningisstoredintheUSER_ERRORSview.
ThePLSCOPE_SETTINGSparameterThecompilationparameterPLSCOPE_SETTINGSenablesthecollectionofidentifierdatainaPL/SQLprogram.Bydefault,theparameterisdisabled(IDENTIFIERS:NONE).ItshouldbesettoIDENTIFIERS:ALLinordertoenableidentifiertracking.
Ifyouenablethisparameterattheinstancelevel,Oraclewillcapturedatabasewideidentifierinformation.Youmustbecarefulwhilesettingthisparameteratthedatabaseinstancelevelasitmightimpactthecompilationperformanceoflargepackages.
SettingPLSCOPE_SETTINGSatsystemorsessionlevel:
ALTER[SYSTEM|SESSION]
SETPLSCOPE_SETTINGS=['IDENTIFIERS:ALL'|'IDENTIFIERS:NONE']
Beingacompilationparameter,youcanalsocompileaPL/SQLsubprogramforidentifiertrackingbyspecifyingthePLSCOPE_SETTINGSparameter:
ALTER[PROGRAMNAME]COMPILE
PLSCOPE_SETTINGS=['IDENTIFIERS:ALL'|'IDENTIFIERS:NONE']
YoucanquerythecurrentsettingofthePLSCOPE_SETTINGSparameterfromtheV$PARAMETERdynamicdictionaryview.
/*ViewthecurrentsettingofPLSCOPE_SETTINGSparameter*/
SELECTvalue
FROMv$parameter
WHEREname='plscope_settings'
/
VALUE
-----------------
IDENTIFIERS:NONE
YoucanviewthespaceconsumedbythePL/ScopetoolinSYSAUXtablespacebyrunning
thefollowingqueryasSYSDBA:
/*VerifythePL/ScopeoccupancyinSYSAUXtablespace*/
SELECToccupant_desc,schema_name,space_usage_kbytes
FROMv$sysaux_occupants
WHEREoccupant_name='PL/SCOPE'
/
OCCUPANT_DESCSCHEMA_NAMESPACE_USAGE_KBYTES
------------------------------------------------------------
PL/SQLIdentifierCollectionSYS2496
LetusrecompiletheprocedureP_CALC_USER_POINTSwiththePLSCOPE_SETTINGSparameter:
ALTERPROCEDUREp_calc_user_pointsCOMPILE
PLSCOPE_SETTINGS='IDENTIFIERS:ALL'
/
QuerytheUSER_PLSQL_OBJECT_SETTINGSviewtoverifywhethertheidentifierinformationhasbeencaptured:
SELECTplscope_settings
FROMuser_plsql_object_settings
WHEREname='P_CALC_USER_POINTS'
/
PLSCOPE_SETTINGS
------------------
IDENTIFIERS:ALL
OracleDatabasedocumentationprovidesahandyscriptforgeneratingahierarchicalreportofprogramidentifiersbyitsusage.ThefollowingscriptgeneratesthePL/ScopeidentifierreportfromtheUSER_IDENTIFIERSdictionaryview:
WITHvAS
(
SELECTline,col,
name,
LOWER(type)Type,
LOWER(usage)Usage,
usage_id,
usage_context_id
FROMuser_identifiers
WHEREobject_name='P_CALC_USER_POINTS'
ANDobject_type='PROCEDURE'
)
SELECTline,RPAD(LPAD('',2*(level-1))||name,25,'.')||''||
RPAD(Type,15)||RPAD(Usage,15)IDENTIFIER_USAGE_CONTEXTS
FROMv
STARTWITHusage_context_id=0
CONNECTBYPRIORusage_id=usage_context_id
ORDERSIBLINGSBYline,col
/
LINEIDENTIFIER_USAGE_CONTEXTS
----------------------------------------------------------------
1P_CALC_USER_POINTS….....proceduredeclaration
1P_CALC_USER_POINTS…...proceduredefinition
1P_USER….............formalindeclaration
1P_USER….............formalinassignment
1USER….............functioncall
1VARCHAR2…...........characterdatatypereference
1P_CORRECT…..........formalindeclaration
1NUMBER….............numberdatatypereference
1P_WRONG…............formalindeclaration
1NUMBER….............numberdatatypereference
3L_NUM…..............variabledeclaration
3NUMBER….............numberdatatypereference
4F_CALC_POINTS…......functiondeclaration
4F_CALC_POINTS…......functiondefinition
4P_QUES…...........formalindeclaration
4NUMBER….........numberdatatypereference
4P_FACTOR….........formalindeclaration
4NUMBER….........numberdatatypereference
5NUMBER…...........numberdatatypereference
9P_QUES…...........formalinreference
9P_FACTOR….........formalinreference
12P_NET_CALC….........proceduredeclaration
12P_NET_CALC….........proceduredefinition
12P_NET_POINTS….....formaloutdeclaration
1NUMBER….........numberdatatypereference
14P_NET_POINTS….....formaloutassignment
1F_CALC_POINTS…..functioncall
14P_CORRECT…....formalinreference
14F_CALC_POINTS…..functioncall
14P_WRONG…......formalinreference
17P_NET_CALC….........procedurecall
17L_NUM…..............variablereference
32rowsselected.
Inasimilarwaytotheprecedingquery,applicationdeveloperscanexploremultipleusecaseswhereidentifierinformationcanbeuseful.
TheDBMS_METADATApackageTheDBMS_METADATApackagewasintroducedinOracle9i.TheAPIenablestheextractionofobjectmetadatafromdatabasedictionariesthatcanbeoptionallymanipulatedandre-executedonadatabaseserver.ThepackageisownedbySYSwhosepublicsynonymisusedbyallusers.AuserwithSELECT_CATALOG_ROLEcandirectlyaccesstheDBMS_METADATApackage.
NoteDBMS_METADATAisakeyenablerofmetadataexportfunctionalityinDataPump
Thepackagepullstheobject’smetadatainXMLformfromthedatabasedictionaryandprovidestransformhandlerstobuilditinthedesiredform.TheformattedXMLcanthenbere-executedinthedatabase.
DBMS_METADATAdatatypesandsubprogramsAswesaidearlier,theDBMS_METADATApackageusesthepublicsynonymsofSYS-owneddatastructures.ThefollowinglistshowsSYS-ownedobjecttypes:
SYS.KU$_PARSED_ITEM:Anobjecttypeusedtocapturetheattributesofanobject’smetadata.Theobjecttypestructureisasfollows:
CREATETYPEsys.ku$_parsed_itemASOBJECT
(
itemVARCHAR2(30),
valueVARCHAR2(4000),
object_rowNUMBER
)
ITEM,VALUEformtheattributename-valuepairforOBJECT_ROW.
SYS.KU$_PARSED_ITEMS:AnestedtableofSYS.KU$PARSED_ITEMusedtoholdtheobjectmetadataattributesformultipleobjects.SYS.KU$_DDL:AnobjecttypeusedtocapturetheDDLofanobjectalongwithitsparsediteminformation.Theobjecttypestructureisasfollows:
CREATETYPEsys.ku$_ddlASOBJECT
(
ddlTextCLOB,
parsedItemsys.ku$_parsed_items
)
TheparsedobjectinformationisstoredinPARSEDITEM.
SYS.KU$_DDLS:AnestedtableofSYS.KU$_DDLreturnedbytheFETCH_DDLsubprogramusedtoholdthemetadataofanobjecttransformedintomultipleDDLstatements.SYS.KU$_MULTI_DDL:AnobjecttypeusedtoholdtheDDLforanobjectinmultipletransforms.SYS.KU$_MULTI_DDLS:AnestedtableofSYS.KU$_MULTI_DDLreturnedbytheCONVERTsubprogram.SYS.KU$_ERRORLINE:Anobjecttypeusedtocaptureerrorinformation.Theobjecttypestructureisasfollows:
CREATETYPEsys.ku$_ErrorLineISOBJECT
(
errorNumberNUMBER,
errorTextVARCHAR2(2000)
)
SYS.KU$_ERRORLINES:AnestedtableoftheSYS.KU$_ERRORLINEobjecttypeusedtoholdbulkerrorinformationduringextractionofeachDDLstatement.SYS.KU$_SUBMITRESULT:AnobjecttypeusedtocapturethecompleteerrorinformationincurredinaDDLstatement.Theobjecttypestructureisasfollows:
CREATETYPEsys.ku$_SubmitResultASOBJECT
(
ddlsys.ku$_ddl,
errorLinessys.ku$_ErrorLines
)
SYS.KU$_SUBMITRESULTS:AnestedtableoftheSYS.KU$_SUBMITRESULTobjecttypeusedtoholdmultipleDDLstatementsandassociatederrorinformation.
NoteAcompletelistofsubprogramscanbefoundonOracledocumentationathttps://docs.oracle.com/database/121/ARPLS/d_metada.htm
ThefollowingtableshowsthefrequentlyusedsubprogramsoftheDBMS_METADATApackage:
Subprogram Remarks
ADD_TRANSFORMfunction SpecifiesatransformthatFETCH_[XML|DDL|CLOB]appliestotheXMLrepresentationoftheretrievedobjects
CLOSEprocedure InvalidatesthehandlereturnedbyOPENandcleansuptheassociatedstate
CONVERTfunctionsandprocedures ConvertanXMLdocumenttoDDL
FETCH_[XML|DDL|CLOB]functionsandprocedures
ReturnsmetadataforobjectsmeetingthecriteriaestablishedbyOPEN,SET_FILTER,SET_COUNT,ADD_TRANSFORM,andsoon
GET_[XML|DDL|CLOB]functions FetchesthemetadataforaspecifiedobjectasXMLorDDLinasinglecall
GET_QUERYfunction ReturnsthetextofthequeriesthatareusedbyFETCH_[XML|DDL|CLOB]
OPENfunction Specifiesthetypeofobjecttoberetrieved,theversionofitsmetadata,andtheobjectmodel
OPENWfunction Opensawritecontext
PUTfunction SubmitsanXMLdocumenttothedatabase
SET_COUNTprocedure SpecifiesthemaximumnumberofobjectstoberetrievedinasingleFETCH_[XML|DDL|CLOB]call
SET_FILTERprocedure Specifiesrestrictionsontheobjectstoberetrieved—forexample,theobjectnameorschema
SET_PARSE_ITEMprocedure Enablesoutputparsingbyspecifyinganobjectattributetobeparsedandreturned
SET_TRANSFORM_PARAMandSET_REMAP_PARAMprocedures SpecifiesparameterstotheXSLTstylesheetsidentifiedbytransform_handle
Outoftheprecedinglist,thesubprogramscanbegroupedbasedontheirworkfunction:
Subprogramsusedtoretrievemultipleobjectsfromthedatabase
SubprogramsusedtosubmitXMLmetadatatothedatabase
ADD_TRANSFORMfunction ADD_TRANSFORMfunction
CLOSEprocedure CLOSEprocedure2
FETCH_[XML|DDL|CLOB]functionsandprocedures CONVERTfunctionsandprocedures
GET_QUERYfunction OPENWfunction
GET_[XML|DDL|CLOB]functions PUTfunction
OPENfunction SET_PARSE_ITEMprocedure
SET_COUNTprocedure SET_TRANSFORM_PARAMandSET_REMAP_PARAMprocedures
SET_FILTERprocedure
SET_PARSE_ITEMprocedure
SET_TRANSFORM_PARAMandSET_REMAP_PARAMprocedures
ParameterrequirementsYoumustnotethattheparameterstothemetadataAPIarecase-sensitiveandshouldbepassedintheirrespectivepositiononly(nonamednotation).
TheDBMS_METADATAtransformationparametersandfiltersAslistedintheprecedingAPIlist,theSET_TRANSFORM_PARAMsubprogramisusedtoformatandcontroltheDDLoutput.Itisusedforbothretrievalandsubmissionofmetadatafromortothedatabase.Itisanoverloadedprocedurewiththefollowingsyntax:
DBMS_METADATA.SET_TRANSFORM_PARAM
(
transform_handleINNUMBER,
nameINVARCHAR2,
valueINVARCHAR2,
object_typeINVARCHAR2DEFAULTNULL
);
DBMS_METADATA.SET_TRANSFORM_PARAM
(
transform_handleINNUMBER,
nameINVARCHAR2,
valueINBOOLEANDEFAULTTRUE,
object_typeINVARCHAR2DEFAULTNULL
);
DBMS_METADATA.SET_TRANSFORM_PARAM
(
transform_handleINNUMBER,
nameINVARCHAR2,
valueINNUMBER,
object_typeINVARCHAR2DEFAULTNULL
);
Intheprecedingprogramsignature:
TRANSFORM_HANDLE:AhandlereitherfromADD_TRANSFORM,oragenerichandlerconstantSESSION_TRANSFORMusedtoaffectthewholesessionNAME:NameoftheparametertobemodifiedVALUE:Newvalueoftheparameter
Thefollowingisalistofthecommonsetofparametersthatareapplicabletoallobjectsinaschema:
Parameter Value Meaning
PRETTY TRUE|FALSE(defaultvalueisTRUE) IfTRUE,producesproperlyindentedoutput
SQLTERMINATOR TRUE|FALSE(defaultvalueisFALSE) IfTRUE,appendsSQLterminator(;or/)aftereachDDL
DEFAULT TRUE|FALSE IfTRUE,resetsallparameterstotheirdefaultstate
INHERIT TRUE|FALSE IfTRUE,inheritssession-levelsettings
Transformhandlersapplicablefortablesandviewsareasfollows:
Parameter Value Meaning
SEGMENT_ATTRIBUTESTRUE|FALSE(defaultvalueisTRUE)
IfTRUE,includessegment,tablespace,logging,andphysicalattributes
STORAGETRUE|FALSE(defaultvalueisFALSE) IfTRUE,includesstorageclause
TABLESPACE TRUE|FALSE IfTRUE,includestablespacespecification
CONSTRAINTS TRUE|FALSE IfTRUE,includestableconstraints
REF_CONSTRAINTS TRUE|FALSE IfTRUE,includesreferentialconstraints
CONSTRAINTS_AS_ALTER TRUE|FALSE IfTRUE,includesconstraintsintheALTERTABLEstatements
OID TRUE|FALSE IfTRUE,includestheobjecttableOID
SIZE_BYTE_KEYWORD TRUE|FALSE IfTRUE,includestheBYTEkeywordsinstringtypecolumnspecifications
FORCE TRUE|FALSE IfTRUE,createsviewwiththeFORCEoption
TheDBMS_METADATA.SET_FILTERprocedureisusedtospecifythefiltersontheschemaobjects.Itacceptsthemetadatahandle,filtername,anditsvalueasinputarguments.
PROCEDUREset_filter(
handleINNUMBER,
nameINVARCHAR2,
valueINVARCHAR2|BOOLEAN|NUMBER,
object_type_pathVARCHAR2
)
Frequentlyusedfilterscanbeschema,user,objectdependencies,tabledata,tables,indexes,constraints,andsoon.Therearemorethan70filtersavailableinOracle11g.Itcanbesetasfollows:
DBMS_METADATA.SET_FILTER(handle,'SCHEMA','SCOTT');
DBMS_METADATA.SET_FILTER(handle,'NAME','DEPARTMENTS');
DemonstrationLetusretrievetheDDLoftheentireEMPtableintheSCOTTschema.TheSQLqueryreturnsaCLOBoutput:
/*QuerytoretrieveDDLofEMPtable*/
SELECTdbms_metadata.get_ddl('TABLE','EMP','SCOTT')
FROMDUAL
/
CREATETABLE"SCOTT"."EMP"
("EMPNO"NUMBER(4,0),
"ENAME"VARCHAR2(10),
"JOB"VARCHAR2(9),
"MGR"NUMBER(4,0),
"HIREDATE"DATE,
"SAL"NUMBER(7,2),
"COMM"NUMBER(7,2),
"DEPTNO"NUMBER(2,0),
"EMAIL"VARCHAR2(50),
CONSTRAINT"PK_EMP"PRIMARYKEY("EMPNO")
USINGINDEX
PCTFREE10
INITRANS2
MAXTRANS255
COMPUTESTATISTICS
STORAGE(INITIAL65536
NEXT1048576
MINEXTENTS1
MAXEXTENTS2147483645
PCTINCREASE0
FREELISTS1
FREELISTGROUPS1
BUFFER_POOLDEFAULT
FLASH_CACHEDEFAULT
CELL_FLASH_CACHEDEFAULT)
TABLESPACE"USERS"ENABLE,
CONSTRAINT"FK_DEPTNO"
FOREIGNKEY("DEPTNO")
REFERENCES"SCOTT"."DEPT"("DEPTNO")ENABLE)
SEGMENTCREATIONIMMEDIATE
PCTFREE10PCTUSED40INITRANS1MAXTRANS255
NOCOMPRESSLOGGING
STORAGE(INITIAL65536
NEXT1048576
MINEXTENTS1
MAXEXTENTS2147483645
PCTINCREASE0
FREELISTS1
FREELISTGROUPS1
BUFFER_POOLDEFAULT
FLASH_CACHEDEFAULT
CELL_FLASH_CACHEDEFAULT)
TABLESPACE"USERS"
Intheprecedingoutput,ifyouwishtoskipthestorageclausespecificationforthetable,youcandosobysettingthetransformparameters:
/*Anonymousblocktosettransformhandles*/
BEGIN
DBMS_METADATA.SET_TRANSFORM_PARAM
(DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',false);
DBMS_METADATA.SET_TRANSFORM_PARAM
(DBMS_METADATA.SESSION_TRANSFORM,'SEGMENT_ATTRIBUTES',false);
DBMS_METADATA.SET_TRANSFORM_PARAM
(DBMS_METADATA.SESSION_TRANSFORM,'PRETTY',true);
DBMS_METADATA.SET_TRANSFORM_PARAM
(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',true);
DBMS_METADATA.SET_TRANSFORM_PARAM
(DBMS_METADATA.SESSION_TRANSFORM,'REF_CONSTRAINTS',false);
DBMS_METADATA.SET_TRANSFORM_PARAM
(DBMS_METADATA.SESSION_TRANSFORM,'TABLESPACE',false);
DBMS_METADATA.SET_TRANSFORM_PARAM
(DBMS_METADATA.SESSION_TRANSFORM,'SIZE_BYTE_KEYWORD',false);
END;
/
Now,ifyouexecutetheGET_DDLfunctiontoretrievetheDDLoftheEMPtable,theoutputwillbemuchneaterandcleaner:
/*QuerytoretrieveDDLofEMPtable*/
SELECTdbms_metadata.get_ddl('TABLE','EMP','SCOTT')
FROMDUAL
/
CREATETABLE"SCOTT"."EMP"
("EMPNO"NUMBER(4,0),
"ENAME"VARCHAR2(10),
"JOB"VARCHAR2(9),
"MGR"NUMBER(4,0),
"HIREDATE"DATE,
"SAL"NUMBER(7,2),
"COMM"NUMBER(7,2),
"DEPTNO"NUMBER(2,0),
"EMAIL"VARCHAR2(50),
CONSTRAINT"PK_EMP"PRIMARYKEY("EMPNO")
USINGINDEXENABLE
);
YoucanusetheGET_XMLfunctiontoretrievetheXMLformatoftheEMPtable.
ThefollowingSQLqueryretrievestheobjectgrantsoftheEMPtableusingtheGET_DEPENDENT_DDLfunction:
/*QuerytoretrieveDDLofobjectgrantsofEMP*/
SELECT
DBMS_METADATA.GET_DEPENDENT_DLL('OBJECT_GRANT','EMP','SCOTT')OBJ_GRANTS
FROMDUAL
/
GRANTSELECTON"SCOTT"."EMP"TO"SALES";
GRANTSELECTON"SCOTT"."EMP"TO"MGR";
GRANTSELECTON"SCOTT"."EMP"TO"CLERK";
GRANTINSERTON"SCOTT"."EMP"TO"SALES";
GRANTINSERTON"SCOTT"."EMP"TO"MGR";
GRANTINSERTON"SCOTT"."EMP"TO"CLERK";
YoucanalsoretrievetheDDLfortheindexesonthetablecolumns.ThefollowingSELECTquerydisplaystheDDLfortheuniqueindexontheEMPNOcolumnoftheEMPtable:
/*QuerytoretrieveDDLofprimarykeyinEMPtable*/
SELECTDBMS_METADATA.GET_DDL('INDEX','PK_EMP','SCOTT')
FROMDUAL
/
CREATEUNIQUEINDEX"SCOTT"."PK_EMP"ON"SCOTT"."EMP"("EMPNO")
;
TracingPL/SQLprogramsusingDBMS_TRACETracingprogramexecutionisanimportantexerciseinascrumbaseddatabasedevelopmentenvironment.Sometimes,inamodularprogrammingmodel,itbecomesdifficulttotracktheprogramexecutionpath.OracleprovidestheDBMS_TRACEpackagetotracePL/SQLprogramcode.
DBMS_TRACEisanOraclesuppliedpackagethatcanbeusedtoenableanddisabletracingindatabasesessions.TheprogramexecutionpathistracedwhenyouexecuteaPL/SQLprograminatrace-enabledsession.Thetraceinformationiscapturedandstoredindatabasetables.ThesetracetablescanbefurtheranalyzedtoexaminetheexecutionpathofaPL/SQLprogram.
ThefollowingfigureshowsthestepsinvolvedinPL/SQLcodetracing:
NotePL/SQLcodetracingcannotbedoneinasharedserverenvironment
InstallingtheDBMS_TRACEpackageYoucaninstalltheDBMS_TRACEpackagebyrunningthefollowingscriptsfromthe$ORACLE_HOME/rdbms/adminfolder:
dbmspbt.sql:ThisscriptcreatestheDBMS_TRACEpackagespecificationprvtpbt.plb:ThisscriptcreatestheDBMS_TRACEpackagebody
TipThescriptsmustbeexecutedastheSYSuserandinthesameorder.
DBMS_TRACEsubprogramsTheDBMS_TRACEpackagecontainstraceconstantsandmembersubprograms.Thetraceconstantsareusedtospecifythetracinglevelinasession.
NoteForcompletedetails,pleaserefertotheOracledocumentationathttps://docs.oracle.com/database/121/ARPLS/d_trace.htm.
TheDBMS_TRACEconstantsaresummarizedasfollows:
DBMS_TRACEconstant Default Remarks
TRACE_ALL_CALLS 1 Tracesallcalls
TRACE_ENABLED_CALLS 2 Tracescallsthatareenabledfortracing
TRACE_ALL_EXCEPTIONS 4 Tracesallexceptions
TRACE_ENABLED_EXCEPTIONS 8 Tracesexceptionsthatareenabledfortracing
TRACE_ALL_SQL 32 TracesallSQLstatements
TRACE_ENABLED_SQL 64 TracesSQLstatementsthatareenabledfortracing
TRACE_ALL_LINES 128 Traceseachline
TRACE_ENABLED_LINES 256 Traceslinesthatareenabledfortracing
TRACE_PAUSE 4096 Pausestracing(controlsthetracingprocess)
TRACE_RESUME 8192 Resumetracing(controlsthetracingprocess)
TRACE_STOP 16384 Stopstracing(controlsthetracingprocess)
TRACE_LIMIT 16 Limitsthetraceinformation(controlsthetracingprocess)
TRACE_MINOR_VERSION 0 Administersthetracingprocess
TRACE_MAJOR_VERSION 1 Administersthetracingprocess
NO_TRACE_ADMINISTRATIVE 32768
Preventstracingofadministrativeeventssuchas:
PL/SQLTraceToolstarted
Traceflagschanged
PL/SQLVirtualMachinestarted
PL/SQLVirtualMachinestopped
NO_TRACE_HANDLED_EXCEPTIONS 65536 Preventstracingofhandledexceptions
ThesubprogramscontainedintheDBMS_TRACEpackageareasfollows:
DBMS_TRACEsubprogram Remarks
CLEAR_PLSQL_TRACEprocedure Stopstracedatadumpinginsession
GET_PLSQL_TRACE_LEVELfunction Getsthetracelevel
GET_PLSQL_TRACE_RUNNUMBERfunction Getsthecurrentsequenceofexecutionoftrace
PLSQL_TRACE_VERSIONprocedure Getstheversionnumberofthetracepackage
SET_PLSQL_TRACEprocedure Startstracinginthecurrentsession
COMMENT_PLSQL_TRACEprocedure IncludescommentonthePL/SQLtracing
INTERNAL_VERSION_CHECKfunction Hasavalueas0,iftheinternalversioncheckhasnotbeendone
LIMIT_PLSQL_TRACEprocedure SetslimitforthePL/SQLtracing
PAUSE_PLSQL_TRACEprocedure PausesthePL/SQLtracing
RESUME_PLSQL_TRACEprocedure ResumesthePL/SQLtracing
Intheprecedinglist,thekeysubprogramsare:
SET_PLSQL_TRACE:ItkicksoffthePL/SQLtracingsession.Forexample,DBMS_TRACE.SET_PLSQL_TRACE(DBMS_TRACE.TRACE_ALL_SQL)tracesallSQLintheprogram.CLEAR_PLSQL_TRACE:Itstopsthetracingsession.
ThePLSQL_TRACE_VERSIONreturnsthecurrenttraceversionastheOUTparameter.
NoteThetracelevelthatcontrolsthetracingprocess(stop,pause,resume,andlimit)cannotbeusedincombinationwithothertracelevels
CompilingaPL/SQLprogramfordebuggingAPL/SQLsubprogramcanbetracedonlyafteritiscompiledindebugmode.YoumustcompiletheprogramtobetracedbyspecifyingthePLSQL_OPTIMIZE_LEVELas1.(Inearlierreleases,thecompilationparameterPLSQL_DEBUGwasusedtocompileaprogramfordebug.)
NoteThePLSQL_DEBUGparameterhasbeendeprecatedinOracleDatabase12c,butretainedforbackward-compatibility.OraclerecommendstousePLSQL_OPTIMIZE_LEVELas1tocompileaPL/SQLprogramfordebugging.
ViewingthePL/SQLtraceinformationThetraceinformationisloggedintothetracetablesthatcanbecreatedbyinvokingthe$ORACLE_HOME/rdbms/admin/tracetab.sqlscriptfromtheSYSaccount.Thesuccessfulexecutionofthescriptwillcreatethefollowingtwotables:
PLSQL_TRACE_RUNS:Thetablestoresexecution-specificinformation.RUNIDisauniquerunidentifierthatderivesitsvaluefromasequence,PLSQL_TRACE_RUNNUMBER.TheRUN_DATEandRUN_ENDcolumnsspecifythestartandendtimeoftherunrespectively.TheRUN_SYSTEM_INFOandSPARE1columnsarecurrentlyunusedcolumnsinthetable.PLSQL_TRACE_EVENTS:Thistabledisplaysthetracesoftheprogramexecutionpath.Thetablestructureisdescribedasfollows:
TheRUNIDcolumnreferencestheRUNIDcolumnofthePLSQL_TRACE_RUNStableTheEVENT_SEQistheuniqueeventidentifierwithinasinglerunTheEVENT_UNIT,EVENT_UNIT_KIND,EVENT_UNIT_OWNER,andEVENT_LINEcolumnscapturetheprogramunitinformation(suchasname,type,owner,andlinenumber)thatinitiatesthetraceeventThePROC_NAME,PROC_UNIT,PROC_UNIT_KIND,PROC_OWNER,andPROC_LINEcolumnscapturetheprocedureinformation(suchasname,type,owner,andlinenumber)thatiscurrentlytracedTheEXCPandUSER_EXCPcolumnsapplytotheexceptionsoccurringduringthetraceTheEVENT_COMMENTcolumngivesauser-definedcommentortheactualeventdescriptionTheMODULE,ACTION,CLIENT_INFO,CLIENT_ID,ECID_ID,andECID_SEQcolumnscaptureinformationaboutthesessionrunningonaSQL*PlusclientTheCALLSTACKandERRORSTACKcolumnsstorethecallstackinformation
Oncethescripthasbeenexecuted,theDBAcanoptionallycreatetheirpublicsynonymsthatcanbeaccessedbyallusers.
/*ConnectasSYSDBA*/
Connsys/oracleasSYSDBA
/*CreatesynonymforPLSQL_TRACE_RUNS*/
CREATEPUBLICSYNONYMplsql_trace_runsFORplsql_trace_runs
/
/*CreatesynonymforPLSQL_TRACE_EVENTS*/
CREATEPUBLICSYNONYMplsql_trace_eventsFORplsql_trace_events
/
/*CreatesynonymforPLSQL_TRACE_RUNNUMBERsequence*/
CREATEPUBLICSYNONYMplsql_trace_runnumberFORplsql_trace_runnumber
/
/*GrantprivilegesonthePLSQL_TRACE_RUNS*/
GRANTselect,insert,update,deleteONplsql_trace_runsTOPUBLIC
/
/*GrantprivilegesonthePLSQL_TRACE_EVENTS*/
GRANTselect,insert,update,deleteONplsql_trace_eventsTOPUBLIC
/
/*GrantprivilegesonthePLSQL_TRACE_RUNNUMBER*/
GRANTselectONplsql_trace_runnumberTOPUBLIC
/
StepstotracePL/SQLprogramexecutionPL/SQLtracingisdemonstratedinthefollowingsteps:
1. CompiletheprocedureP_CALC_USER_POINTSfordebugbyspecifyingPLSQL_OPTIMIZE_LEVELas1:
ALTERPROCEDUREp_calc_user_pointsCOMPILEPLSQL_OPTIMIZE_LEVEL=1
/
2. Enabletracinginthesession:
Notethetracelevelswhileenablingtracinginthecurrentsession.ThefollowingPL/SQLblockwillenabletracingofallcallsexcludingthetracingofadministrativeevents.
BEGIN
/*Enabletracingforallcallsinthesession*/
DBMS_TRACE.SET_PLSQL_TRACE(
DBMS_TRACE.TRACE_ALL_CALLS+
DBMS_TRACE.NO_TRACE_ADMINISTRATIVE);
END;
/
3. ExecutetheprocedureP_CALC_USER_POINTS:
SETSERVEROUTPUTON
BEGIN
p_calc_user_points(USER,10,3);
END;
/
4. Disabletracinginthesession:
BEGIN
/*Stopthetracesession*/
DBMS_TRACE.CLEAR_PLSQL_TRACE;
END;
/
5. QuerythetracelogtablesPLSQL_TRACE_RUNSandPLSQL_TRACE_EVENTS:
QuerytheRUNIDofthecurrenttracefromPLSQL_TRACE_RUNS
SELECTMAX(runid)
FROMPLSQL_TRACE_RUNS
WHERErun_owner='SCOTT'
/
MAX(RUNID)
----------
13
ForRUNID=13,querythetraceeventsfromPLSQL_TRACE_EVENTS
SELECTevent_seq,
event_comment,
event_unit_owner||'.'||event_unitunit,
proc_name,
proc_unit,
proc_unit_kind
FROMPLSQL_TRACE_EVENTS
WHERERUNID=13
ORDERBYEVENT_SEQ
/
ProfilingPL/SQLcodeOracleenablesdatabasedeveloperstoperformdynamicanalysisoftheirPL/SQLcodethroughtracingandprofiling.Asanapplicationdeveloper,youwriteamulti-linePL/SQLsubprogram,whichmayincludeSQLstatements,PL/SQLconstructs,callstoroutinesubprograms,exceptions,andmanymoreitems.YoucanfollowtheexecutionflowoftheprogrambyusingtheDBMS_TRACEpackage,butitdoesn’trevealthetimeconsumedateachstep.YoucanprofilethePL/SQLprogramtocheckitsperformanceaspects.TheperformanceprofilerevealshowmuchtimeisspentateachlineofcodeinaPL/SQLprogram.
Profilingisavitalexerciseinthedevelopmentstageofadatabase,asyoucanidentifytheareasinyourPL/SQLprogramcodethatcanbefine-tunedforperformance.Oracleprovidestwobuilt-inutilitypackagestoprofilePL/SQLcode:DBMS_PROFILERandDBMS_HPROF.TheDBMS_PROFILERpackagegatherstheperformancemetricsandproducesaflatprofileroutput.Ontheotherhand,DBMS_HPROFgatherstheprofilerdataandwritestheprofileinformationintointeractiveHTMLreports.
Inthescopeofthischapter,wewilldiscusstheDBMS_HPROFpackage.
TheDBMS_HPROFpackageTheDBMS_HPROFpackagewasintroducedinOracleDatabase11gRelease1.ItenableshierarchicalprofilingofaPL/SQLprogramandprovidesadetailedperformanceanalysisoftimespentbysubprogramcalls,bynamespace,andbycalldescendantsthroughtheHTMLreports.Itisknownasa“hierarchicalprofiler”becauseofitsabilitytodrill-downtodescendantandsub-treelevelsofasubprogramexecution.Thedistinctivefeaturesofahierarchicalprofilerareasfollows:
ItgathersandstoresprofilerinformationintodatabasetablesItissupportedbySQLDeveloperItreportstheperformanceofSQLandPL/SQLexecutionintheprogramThenumberofdistinctsubprogramscallsandtimespentineachoneofthemThesubprogramcallhierarchy
TheDBMS_HPROFpackageisinstalledbydefaultandisexecutedwiththeinvoker’sprivileges.AusershouldhavetheEXECUTEprivilegeontheSYS-ownedDBMS_HPROFtool.
DifferencesbetweenDBMS_PROFILERandDBMS_HPROFDBMS_PROFILERprofilesagivenPL/SQLprogramatthelinelevel,whileDBMS_HPROFbuildsacalllevelprofileofaprogram.DBMS_HPROFiseasytouseandrequiresnoadditionaleffortswhenrunoncriticaldatabaseenvironments.DBMS_PROFILERproducesflatoutputwhiletherawdatafromDBMS_HPROFcanbefurtheranalyzedandwrittenintoHTMLreports.
DBMS_HPROFsubprogramsTheDBMS_HPROFpackagecontainsthesubprogramstocollecttheprofiledata(DataCollector)andanalyzeit(Analyzer).
DataCollector:Thefollowingsubprogramsopenandclosetheprofilingwindow.AllthePL/SQLprogramsexecutedwithinthiswindowwillbeprofiledandwritteninrawformattoafile.
START_PROFILINGprocedureSTOP_PROFILINGprocedure
Analyzer:TheANALYZEsubprogramreadsandanalyzestherawprofilerdataandpopulatestheprofilertables.Youcananalyzeeitherthecompleterawprofilerdataorevenaparticularsubprogramcall.OraclealsoletsyouprofiletheallocationofUGA(UserGlobalArea)andPGA(ProgramGlobalArea)forafunctionduringtheprogramexecution.
CollectingrawprofiledataWewilllistthestepstoprofiletheexecutionoftheP_CALC_USER_POINTSprocedure:
1. Createadatabasedirectory.Oraclewillcreatetherawprofilerdataoutputfileinthislocation:
connectsys/oracleasSYSDBA
CREATEDIRECTORYdir_profiles
AS'/u01/app/oracle/diag/profiles/'
/
2. MakethenecessarygrantstotheSCOTTuser.Thisstepisanimportantpre-requisiteforausertousetheDBMS_HPROFpackage:
connectsys/oracleasSYSDBA
GRANTREAD,WRITEONDIRECTORYdir_profilesTOSCOTT
/
GRANTEXECUTEONDBMS_HPROFTOSCOTT
/
3. Enableprofilinginthecurrentsession:
connectscott/tiger
BEGIN
DBMS_HPROF.START_PROFILING('DIR_PROFILES','hprof_p_calc.log');
END;
/
4. ExecutetheP_CALC_USER_POINTSprocedure:
connectscott/tiger
SETSERVEROUTON
BEGIN
P_CALC_USER_POINTS(USER,10,3);
END;
/
5. Stopprofilinginthesession
connectscott/tiger
BEGIN
/*Stoptheprofiling*/
DBMS_HPROF.STOP_PROFILING;
END;
/
6. Checktherawprofilerdatacreatedatthespecifieddirectorylocation:
Oraclegatherstheprofilerdataintextformatbuttherawformatishardtointerpretanddrawconclusionsfrom.Followingarethefirstinitiallinesoftherawprofilerdata:
P#VPLSHPROFInternalVersion1.0
P#!PL/SQLTimerStarted
P#CPLSQL."".""."__plsql_vm"
P#X14
P#CPLSQL."".""."__anonymous_block"
P#X334
P#CSQL."SYS"."STANDARD"::11."__static_sql_exec_line180"#180
P#X3504
P#R
P#X132056
P#C
PLSQL."SCOTT"."P_CALC_USER_POINTS"::7."P_CALC_USER_POINTS"#9d831f6c5a52
6d3e#1
P#X224
P#C
PLSQL."SCOTT"."P_CALC_USER_POINTS"::7."P_CALC_USER_POINTS.P_NET_CALC"#e
17d780a3c3eae3d#12
P#X1
InterpretingtherawprofilerdataAlthoughtherawprofilerdataisabittrickytounderstandandinterpret,youcangetfirst-levelindicationsfromthefollowinginformation.
Eventindicators—eachlineoftheprofilerstartswithaneventindicator,whichcarriesameaning.Herearethedistincteventindicatorsfromtheprofileroutput:
P#V:PLSHPROFbannerinformationP#!:CommentP#C:CalltoSQLorPL/SQLsubprogram:
Determinesthecallnamespace,linenumber,callingandcalledsubprogramname,andhashsignature.
P#X:ElapsedtimebetweenthetwoeventsP#R:Returnfromasubprogramcall
Operationalfunctions—FunctionstoexecuteaPL/SQLprogramcanbethefollowing:
__anonymous_blockindicatesanonymousblockexecution__dyn_sql_exec_lineindicatesdynamicSQLexecutionatline#__pkg_initindicatesPL/SQLpackageinitialization__plsql_vmindicatesPL/SQLvirtualmachinecall__sql_fetch_lineindicatesfetchoperationatline#__static_sql_exec_lineindicatesstaticSQLexecutionatline#
AnalyzingprofilerdataAftertherawprofilerdataiscollected,wewillanalyzeitandpopulatetheprofilertables.Letusnowcreatetheprofilertables.
CreatingtheprofilertablesBydefault,theprofilertablesarenotcreated.Therefore,eithertheSYSDBAortheuserwithDBAprivilegeswillhavetorunthe$ORACLE_HOME/rdbms/admin/dbmshtab.sqlscripttocreatetheprofilertables.Onexecutionofthisscript,thefollowingthreetablesarecreated:
DBMSHP_RUNS:MaintainsflatinformationabouteachcommandexecutedduringprofilingDBMSHP_FUNCTION_INFO:ContainsinformationabouttheprofiledfunctionDBMSHP_PARENT_CHILD_INFO:Containsparent-childprofilerinformation
AdatabaseadministratorcancreateapublicsynonymontheprecedingtablesorgranttheSELECTprivilegetotheuserwhointendstousetheprofiler.
AnalyzingtheprofileroutputBeforeinvokingthesubprogramtoanalyzetherawprofilerdata,firstgrantobjectprivilegestotheSCOTTuser:
connectsys/oracleassysdba
GRANTselect,insertonDBMSHP_RUNStoscott
/
GRANTselect,insertonDBMSHP_FUNCTION_INFOtoscott
/
GRANTselect,insertonDBMSHP_PARENT_CHILD_INFOtoscott
/
ThefollowingPL/SQLanonymousblockinvokestheANALYZEsubprogramtointerpretthetracefilepassedastheparameter:
connectscott/tiger
/*StartthePL/SQLblock*/
DECLARE
l_runidNUMBER;
BEGIN
/*InvoketheanalyzerAPI*/
l_runid:=DBMS_HPROF.analyze
(location=>'DIR_PROFILES',
FILENAME=>'hprof_p_calc.log',
run_comment=>'AnalyzingtheexecutionofP_CALC_USER_POINTS');
DBMS_OUTPUT.put_line('l_runid='||l_runid);
END;
/
Queryingtheprofilertables
YoucanqueryprofilerdatafromtheDBMSHP_RUNS,DBMSHP_FUNCTION_INFO,andDBMSHP_PARENT_CHILD_INFOtables.ThefollowingSQLqueryselectsthemostrecentRUNIDfromtheDBMSHP_RUNStable:
SELECTrunid,total_elapsed_time,run_comment
FROMdbmshp_runs
ORDERBYrunid
/
RUNIDTOTAL_ELRUN_COMMENT
---------------------------------------------------------------
219973AnalyzingtheexecutionofP_CALC_USER_POINTS
ThefollowingSQLqueryselectsthesubprograminformationfromDBMSHP_FUNCTION_INFO:
SELECTnamespace,
function,
module,
calls,
function_elapsed_time"time_ms"
FROMdbmshp_function_info
WHERErunid=2
/
NAMESFUNCTIONMODULECALLS
time_ms
-----------------------------------------------------------------------
------
PLSQL__anonymous_block2
132558
PLSQL__plsql_vm223
PLSQLP_CALC_USER_POINTSP_CALC_USER_POINTS12489
PLSQLP_CALC_USER_POINTS.F_CALC_POINTSP_CALC_USER_POINTS214
PLSQLP_CALC_USER_POINTS.P_NET_CALCP_CALC_USER_POINTS16
PLSQLSTOP_PROFILINGDBMS_HPROF10
PLSQLPUT_LINEDBMS_OUTPUT13
SQL__static_sql_exec_line180STANDARD23727
8rowsselected.
Theprecedingoutputshowsthetimeelapsedineachprogramfunctionalongwiththenamespacetowhichitbelongs.Theprofilerdatainthetablescanbeusedtobuildcustomreportsindevelopmenttools.
TheplshprofutilityOracleprovidesacommand-lineutilitytool,calledplshprof,toperformin-depthanalysisofrawprofilerdataandgenerateneatHTMLreports.Itcanalsobeusedtogenerateadifferencereportbetweentworawprofileroutputfiles.Thetoolisnotdependentontheanalyzerphaseortheprofilertable’sdata.
Theplshprofutilitysyntaxisasfollows:
[oracle@packt~]$plshprof
PLSHPROF:OracleDatabase12cEnterpriseEditionRelease12.1.0.2.0-64bit
Production
Usage:plshprof[<option>...]<tracefile1>[<tracefile2>]
Options:
-trace<symbol>(nodefault)specifyfunctionnameoftreeroot
-skip<count>(default=0)skipfirst<count>invokations
-collect<count>(default=1)collectinfofor<count>invokations
-output<filename>(default=<symbol>.htmlor<tracefile1>.html)
-summaryprinttimeonly
Inthefollowingexample,theplshprofutilitysummarizestherawprofilerdatafromtheloghprof_p_calc.log.
[oracle@profiles]$plshprof-summaryhprof_p_calc.log
PLSHPROF:OracleDatabase12cEnterpriseEditionRelease12.1.0.2.0-64bit
Production
Totalsubtreetime:138820microsecs(elapsedtime)
Notethatthesummaryonlygivesyouthetotalelapsedtime.LetusnowfullyanalyzetheprofilerdataandgeneratetheHTMLoutput:
[oracle@profiles]$plshprof-outputHPROF_PCALChprof_p_calc.log
PLSHPROF:OracleDatabase12cEnterpriseEditionRelease12.1.0.2.0-64bit
Production
[8symbolsprocessed]
[Reportwrittento'HPROF_PCALC.html']
Oncetheplshprofutilityisprocessed,thefollowingHTMLfilesaregeneratedinthedirectorylocation:
[oracle@profiles]$ls*.html
HPROF_PCALC_2c.htmlHPROF_PCALC_mf.htmlHPROF_PCALC_tc.html
HPROF_PCALC_2f.htmlHPROF_PCALC_ms.htmlHPROF_PCALC_td.html
HPROF_PCALC_2n.htmlHPROF_PCALC_nsc.htmlHPROF_PCALC_tf.html
HPROF_PCALC_fn.htmlHPROF_PCALC_nsf.htmlHPROF_PCALC_ts.html
HPROF_PCALC.htmlHPROF_PCALC_nsp.html
HPROF_PCALC_md.htmlHPROF_PCALC_pc.html
Here,HPROF_PCALC.htmlisthereportindexfileandlinksallotherprofilerreports.Themainindexpageisshowninthefollowingscreenshot:
Whatdothesereportsreveal?Thevariousreportsgiveadetailedbreakdownofelapsedtimebyeachprogramfunction,module,descendent,andnamespace.Let’sexplorethemainreportsfromthecompleteset:
FunctionElapsedTime(microsecs)DatasortedbyTotalSubtreeElapsedTime(microsecs):Thisreportprovidesaflatviewoftherawprofilerdata.Itincludesthetotalcallcount,selftime,subtreetime,anddescendantsofeachfunction.FunctionElapsedTime(microsecs)DatasortedbyTotalFunctionElapsedTime(microsecs):Thismodule-levelsummaryreportshowsthetotaltimespentineachmoduleandthetotalcallstothefunctionsinthemodule.NamespaceElapsedTime(microsecs)DatasortedbyNamespace:ThisreportprovidesthedistributionoftimespentbythePL/SQLandSQLengines.SQLandPL/SQLarethetwonamespacecategoriesavailableforablock.ItisveryusefulinreducingthediskI/Oandhenceenhancingblockperformance.Thenetsumofthedistributionisalways100percent.
SummaryInthischapter,welearnedvarioustechniquestomaintainPL/SQLprogramcode.AskillinanalyzingaPL/SQLprogramisrequiredinordertotroubleshootcodeissuesordiagnoseperformancebottlenecks.Therearemanydictionaryviewsthatcanprovidelotofmetadataaboutaprogram,butdevelopersneedtopicktherightoneforthejob.Tracingandprofilingarethetechniqueswithwhichdatabasedevelopersshouldbefamiliar.Inlargescaledevelopments,tracingandprofilingcanbeofgreathelpinidentifyingopportunitiestoimproveperformance.
Inthenextchapter,wewilldiscusshowtosafeguardyourdatabaseapplicationsagainstSQLinjectionattacks.
PracticeexerciseWhichofthefollowingdictionaryviewsisusedtogetinformationaboutsubprogramarguments?
1. ALL_OBJECTS2. ALL_ARGUMENTS3. ALL_DEPENDENCIES4. ALL_PROGRAMS
Thetablespaceinformationonadatabaseserverisasfollows:
SELECTtablespace_name
FROMDBA_TABLESPACES
/
TABLESPACE_NAME
----------------
SYSTEM
UNDOTBS1
TEMP
USERS
EXAMPLE
Youexecutethefollowingcommandinthesession:
SQL>ALTERSESSIONSETPLSCOPE_SETTINGS='IDENTIFIERS:ALL';
Sessionaltered.
Identifythecorrectstatements:
1. TheidentifierinformationwouldbecapturedbyPL/Scopefortheprogramcreatedorcompiledinthesession.
2. TheidentifierinformationwouldnotbecapturedbyPL/ScopeasIDENTIFIERS:ALLcanbeenabledonlyattheSYSTEMlevel.
3. TheidentifierinformationwouldbecapturedbyPL/Scopeonlyfortheprogramsthatarecreatedinthesession.
4. TheidentifierinformationwouldnotbecapturedbyPL/ScopesincetheSYSAUXtablespaceisnotavailable.
TheparametersspecifiedinDBMS_METADATAarecase-sensitive:
1. True2. False
DBMS_UTILITY.FORMAT_CALL_STACKaccomplisheswhichofthefollowingobjectives:
1. CapturesexceptionsinaPL/SQLblock.2. Preparesthestackofsequentialcalls.3. Preparesthestackofexecutionactions.
4. Preparesthestackofblockprofiler.
WhichofthefollowingdoestheDBMS_METADATApackageachieve:
1. Generatesreportofinvalidatedobjectsinaschema.2. GeneratesDDLforagivenorallobject(s)inaschema.3. Generatesanobject-to-tabledependencyreportinaschema4. Generatesareportofobjectstatisticsinaschema
ThePL/ScopetoolcanstoreidentifierdataonlyintheUSERStablespace.
1. True2. False
WhichofthefollowingarethevalidparametervaluesofSET_TRANSFORM_PARAMfortablesalone?
1. STORAGE2. FORCE3. PRETTY4. INHERIT
Chapter11.SafeguardingPL/SQLCodeagainstSQLinjectionAnincidenceofasecuritybreachinvolves:ahackerandavulnerablesystem.Ahackercanbeaninsideroranoutsider,whoattacksthesystemtoexposeandaccessconfidentialinformation,whichmayleadtofatalconsequences.Asystemcouldbevulnerabletoattacksbecauseoflowcodingstandardsandahalf-bakedunderstandingoftechnologies.Thesteepgrowthofwebapplicationusersandsharpriseinsocialmediainteractionshaswidenedtheattacksurfacearea.Thesystemsthatareahacker’sparadisearethosewhichcontainpersonalidentifiableinformation,financialinformation,governmentdata,andbusinesstransactions.Thehazardousconsequencesofasecuritybreachhavepushedmanyorganizationstolookseriouslyafterdatasecurity.Asafirstlayerofprotection,organizationsmustboltthenetworkpenetrationthroughtheadoptionofproductslikeAuditVaultandDatabaseFirewall(AVDF)andprotectdataaccessthroughstrongdataaccesspolicies,encryptionorredaction.
SQLinjectionisatechniquetobreakthroughtheapplicationdesignandextractsensitivedata.In1998,anauthorbypennameRainForestPuppy(rfp)firstidentifiedthetechnologyvulnerabilitiesinhispaperNTWebTechnologyVulnerabilitiesforPhrackmagazineandevangelizedthebestpracticesofwritingcodetodilutesuchacts.Thechapteroutlineisasfollows:
WhatisSQLinjection?PreventingSQLinjectionattacksTestingthecodeforSQLinjectionflaws
WhatisSQLinjection?AdatabaseapplicationontheserversidecontainstheprogrammablelogicembeddedwithinthePL/SQLpackagesandsubprograms.ThesePL/SQLprogramunitsmaycontainSQLstatements,whichareintendedtoperformspecificoperations.TheSQLstatements,whosequerytextisbuiltatruntime(dynamicallyderived)andbasedonclient-suppliedinputs,openwaysforSQLinjection.AmalicioususercansupplyamanipulatedinputthatcanbreakthroughthePL/SQLprogramlogicbyreplacingtheSQLsyntaxandperformarbitraryexecution.
ThereasonitisknownasInjectionisbecausethemanipulatedtext,whichreplacesorappendstotheoriginalSQLtextinaPL/SQLprogramunit,isparsedalongwiththeoriginalSQLstatement.Theundetectedattacker’scodeislegallyexecutedbytheSQLengine,alongwiththeoriginalprogrammedSQL.
Forexample,astringtypemaliciousinputfromtheclientisexecutedaslegalcodebytheSQLengine;thus,exploitingaserver-sideSQLstatement.Asaconsequence,anattackercangainaccesstosensitiveandrestrictedinformationfromthedatabase.Thedata,consideredtobeattack-prone,canbepersonalinformation,creditcardinformation,anorganization’sinternaldata,orgovernmentdata.
Althoughtherearemultipleplatformtargets,techniquesandremediesforSQLinjection,thischapterrestrictsthescopeofdiscussiontotheattacksonPL/SQLunitswiththebestpracticestoavoidthem.
SQLinjectiontargetsInmanyofthecasesreportedtodate,theclient-suppliedinputswereidentifiedasthemajorcauseofSQLinjectionattacks.ThedynamicSQL,whichworksdirectlywiththeclient-suppliedinputs,ismorepronetoinjectionattacks.Afterthecodevulnerabilitiesarediscovered,anattackercanexploitthecodetoanyextent.Byextractingrestricteddata,theycanupdateordeletesensitiveinformation.Notonlythedatamodification,datadefinitionscanalsobemodifiedthroughSQLinjection.
Apartfromtheclient-suppliedinputs,adefinerPL/SQLprogramunitcanindirectlyleadtocodeinjectionbecauseitexecuteswiththeprivilegesoftheunitownerandnottheinvoker.Therefore,aninvokercanexecuteaPL/SQLprogramwithanelevatedsetofprivileges.
HowtoexploitthePL/SQLcode?TherearenumerousformsofSQLinjection.AnattackercancreateafunctiontoupdatesensitiveinformationwithPRAGMAAUTONOMOUS_TRANSACTION.HecangainaccesstotheDBAprivilegesandmakeirrevocablechangestothedatabase.
Let’sunderstandtheSQLinjectionthroughacreditcardcasestudy.ThefollowingCREATETABLEstatementcreatesanEMP_CREDIT_BALtable,whichcontainsthecreditcarddetailsofemployees:
/*Testtabletogeneratecreditcarddetailsofemployees*/
CREATETABLEemp_credit_bal
AS
SELECTempnocard_holder,
deptno,
ename,
job,
sal,
REGEXP_REPLACE(str,'(\d{4})(\d{4})(\d{4})(\d{4})','\1-\2-\3-\4')card_no,
TRUNC(DBMS_RANDOM.VALUE(sal,5*sal))credit_balance
FROMempE,
(SELECTTO_CHAR(
TRUNC(
DBMS_RANDOM.VALUE(1000000000000000,
9999999999999999)))str
FROMdual
)
/
/*Verifythedatainthetable*/
SELECTename,
card_no,
credit_balance
FROMemp_credit_bal
/
ENAMECARD_NOCREDIT_BALANCE
--------------------------------------------
SMITH4020-3009-1084-03452844
ALLEN9205-3519-4278-79932034
WARD7838-5801-5970-80604038
JONES7556-7454-2248-08504336
MARTIN6689-9703-5168-52821690
BLAKE3662-7700-4489-31875443
CLARK6195-2171-8232-324011152
SCOTT1961-7153-0620-936614337
KING7930-1567-7029-094319497
TURNER8166-4431-5647-35792286
ADAMS8155-2229-9107-36342301
JAMES4788-5716-1863-69831540
FORD8683-1130-1302-14989750
MILLER5522-2843-9553-51883585
14rowsselected.
AP_REP_CC_BALprocedureisalowstandardprogramthatacceptsthelastfourdigitsofthecreditcardandprintsthecreditbalancereportoftheemployee:
/*Proceduretoprintthecreditcardinfoofacardholder*/
CREATEORREPLACEPROCEDUREp_rep_cc_bal(p_card_noVARCHAR2)
IS
/*Declarerefcursorvariable*/
TYPEc_refISREFCURSOR;
cc_balC_REF;
/*DeclarearecordofEMP_CREDIT_CARDrowtype*/
emp_cc_recemp_credit_bal%rowtype;
BEGIN
/*OpentherefcursorvariableforaSELECTquery*/
OPENcc_balFOR'SELECT*FROMemp_credit_bal
WHEREsubstr(card_no,-4,4)='||p_card_no;
LOOP
/*Iteratethroughtheresultsettofetchtherecord*/
FETCHcc_balINTOemp_cc_rec;
EXITWHENcc_bal%NOTFOUND;
/*Printthecreditcardinformation*/
DBMS_OUTPUT.PUT_LINE(RPAD('_',50,'_'));
DBMS_OUTPUT.PUT_LINE('EmpName/Title:'||emp_cc_rec.ename||'|
'||INITCAP(emp_cc_rec.job));
DBMS_OUTPUT.PUT_LINE('EmpCCard:'||emp_cc_rec.card_no);
DBMS_OUTPUT.PUT_LINE('CCardBalance:'||emp_cc_rec.credit_balance);
ENDLOOP;
CLOSEcc_bal;
END;
/
/*EnabletheSERVEROUTPUTtoprinttheprogramoutput*/
SETSERVEROUTPUTON
Let’stesttheprecedingprocedurewithasampleinput:
EXECp_rep_cc_bal('0345');
__________________________________________________
EmpName/Title:SMITH|Clerk
EmpCCard:4020-3009-1084-0345
CCardBalance:2844
PL/SQLproceduresuccessfullycompleted.
Let’scheckhowahackercantweakthestringinputtoextractthedetailsofthePRESIDENT:
EXECp_rep_cc_bal('''XXX''ORJOB=''PRESIDENT''');
__________________________________________________
EmpName/Title:KING|President
EmpCCard:7930-1567-7029-0943
CCardBalance:19497
PL/SQLproceduresuccessfullycompleted.
Whatwehavejustseenishowamanipulatedinputbypassestheprocedurallogicbysupplyingamanipulatedvaluetotheexistingpredicate(s).ItappendsanewpredicatetotheSQLthatfetchesthepresident’screditdetails.Thefollowingprocedurecallfetchesthecreditcarddetailsofemployeesfromdepartment10:
EXECp_rep_cc_bal('''XXX''ORDEPTNO=10');
__________________________________________________
EmpName/Title:CLARK|Manager
EmpCCard:6195-2171-8232-3240
CCardBalance:11152
__________________________________________________
EmpName/Title:KING|President
EmpCCard:7930-1567-7029-0943
CCardBalance:19497
__________________________________________________
EmpName/Title:MILLER|Clerk
EmpCCard:5522-2843-9553-5188
CCardBalance:3585
PL/SQLproceduresuccessfullycompleted.
Likewise,anattackercangeneratethereportforalltheemployeesbybypassingallthefiltersandpredicates:
EXECp_rep_cc_bal('''XXX''OR1=1');
__________________________________________________
EmpName/Title:SMITH|Clerk
EmpCCard:4020-3009-1084-0345
CCardBalance:2844
__________________________________________________
EmpName/Title:ALLEN|Salesman
EmpCCard:9205-3519-4278-7993
CCardBalance:2034
__________________________________________________
EmpName/Title:WARD|Salesman
EmpCCard:7838-5801-5970-8060
CCardBalance:4038
__________________________________________________
EmpName/Title:JONES|Manager
EmpCCard:7556-7454-2248-0850
CCardBalance:4336
__________________________________________________
EmpName/Title:MARTIN|Salesman
EmpCCard:6689-9703-5168-5282
CCardBalance:1690
__________________________________________________
EmpName/Title:BLAKE|Manager
EmpCCard:3662-7700-4489-3187
CCardBalance:5443
__________________________________________________
EmpName/Title:CLARK|Manager
EmpCCard:6195-2171-8232-3240
CCardBalance:11152
__________________________________________________
EmpName/Title:SCOTT|Analyst
EmpCCard:1961-7153-0620-9366
CCardBalance:14337
__________________________________________________
EmpName/Title:KING|President
EmpCCard:7930-1567-7029-0943
CCardBalance:19497
__________________________________________________
EmpName/Title:TURNER|Salesman
EmpCCard:8166-4431-5647-3579
CCardBalance:2286
__________________________________________________
EmpName/Title:ADAMS|Clerk
EmpCCard:8155-2229-9107-3634
CCardBalance:2301
__________________________________________________
EmpName/Title:JAMES|Clerk
EmpCCard:4788-5716-1863-6983
CCardBalance:1540
__________________________________________________
EmpName/Title:FORD|Analyst
EmpCCard:8683-1130-1302-1498
CCardBalance:9750
__________________________________________________
EmpName/Title:MILLER|Clerk
EmpCCard:5522-2843-9553-5188
CCardBalance:3585
PL/SQLproceduresuccessfullycompleted.
Now,youcanrealizehowthegoodoldargumentscanbeexploitedtoleakconfidentialinformation.Abadlycodedprocedure,whichisnottoouncommon,isvulnerabletosuchattacks.
TheprecedingcasestudyisaclassicexampleofaFirstOrderAttack,wherethedatalosesitsconfidentialityafteritisattacked.Ifthedataattackdoesnothappenthroughprogramexecution,itiscalledaSecondOrderAttack.
ThefollowingdiagrambranchestheimpactsofSQLinjection:
PreventingSQLinjectionattacksSQLinjectionisnotadesignbug,butanintentionalmaliciouspractice.DatabasedevelopersmustadoptbestpracticeswhilewritingPL/SQLcode.Ifcodemodificationisnotpossible,theapplicationinterfacelayermayalsoworktoreducetheattacksurfacearea.
Let’stakeabrieflookattheprecautionarymeasurestominimizeinjectionattacks:
CheckyourdynamicSQL:DynamicSQLquerytext,whichisconstructedatruntimeanddirectlyusestheuser-suppliedinputs,createsapregnablehitchpointintheapplication.Youcanprotectthemagainstinjectionattacksthrougheitherofthesetechniques:
ReducethedirectexposureofclientinputstodynamicSQL:Youcansanitizeandvalidatetheclient-suppliedinputsbeforetheyareusedindynamicSQL.OracleprovidestheDBMS_ASSERTpackagetoverifytheinputs.UsebindargumentsindynamicSQL:Databasedevelopersareencouragedtomakeuseofbindargumentsformultiplereasonsandoneofthemissecurity.Bindargumentsnearlyeliminatethepossibilityofattacks.Manipulatedargumentvalueswouldendinanexception,therebyterminatingtheprogramexecution.
Monitorauser’sobjectprivileges:Irregularityinobjectprivilegescanbeapotentialthreattoanapplication.Ausercaninvokeadefiner’sprogramunitwhichmaybeatahigherprivilegelevel.Fromasecuritystandpoint,auseratalowerprivilegelevelcangainaccesstounauthorizeddatasetsobjects.Theuseoftheinvoker’sprogramunitsshouldbeencouragedtoregulateobjectprivileges.OracleDatabase12cenhancesthesecurityofthedefiner’sprogramunitsbyallowingthegrantingofrolestoprogramunits.
SanitizinginputsusingDBMS_ASSERTOracle10gRelease2introducedtheDBMS_ASSERTpackagetovalidateuserinputsbeforetheyareconsumedbytheserver-sideprogramunits.Thepackageassertsorpostulatesaninputforacertainfactsuchasquotedandunquotedidentifiers,orobjectvalidity,andsoon.Uponassertion,theinputisreturnedastheactualinstance.Iftheassertionfails,theVALUE_ERRORexceptionwillberaised.
TheDBMS_ASSERTpackageisownedbySYSandcontainssevenpackagedfunctions.Thepackagesubprogramsaredemonstratedasfollows:
Subprograms Description
ENQUOTE_LITERALfunction Enclosesastringliteralwithinsinglequotes
ENQUOTE_NAMEfunction Enclosestheinputstringindoublequotes
NOOPfunctions Anoverloadedfunctionreturnsthevaluewithoutanychecking;doesnooperation
QUALIFIED_SQL_NAMEfunction VerifiesiftheinputstringisaqualifiedSQLnameRaisesORA-44004iftheinputstringisnotavalidqualifiedSQLname
SCHEMA_NAMEfunction VerifiesiftheinputstringisavalidschemanameRaisesORA-44001iftheinputstringisaninvalidschemaname
SIMPLE_SQL_NAMEfunction Verifiesiftheinputstringisasimpleidentifier(quotedandunquoted)RaisesORA-44003iftheinputstringisaninvalidSQLname
SQL_OBJECT_NAMEfunction VerifiesiftheinputparameterstringisavalidobjectinthedatabaseRaisesORA-44002iftheinputstringisaninvalidobjectname
ChoosetherightsubprogramfortherightidentifierTheDBMS_ASSERTsubprogramaimstoverifythepropertiesofidentifiersandliterals.Anidentifierisusedtodenoteeachandeveryitemusedinthedatabase.AlltheobjectnamesorvariablenamesinaPL/SQLblockareidentifiers.Anidentifiercanbequoted,unquoted,orliteral.
Unquotedidentifiers
ThisidentifierabidesbythenamingconventionoftheOracleDatabase:itmustbeginwithanalphabetfollowedbynumbersorasetofdefinedspecialcharacters(_).Theverificationalgorithmofunquotedidentifiersisbasicanditcheckswhethertheidentifierfollowsapropernamingconvention.
YoucanuseSIMPLE_SQL_NAMEtocheckwhetheranunquotedidentifiercontainsanynonadmissiblecharactersandstartswithanalphabet.Notethatitdoesn’tverifythevaliditystatusoftheinputidentifier.
Inthefollowingexample,SIMPLE_SQL_NAMEconfirmstheinputidentifierasitcorrectlyfollowsthenamingconvention:
/*VerifyanunquotedidentifierusingSIMPLE_SQL_NAME*/
SELECTDBMS_ASSERT.SIMPLE_SQL_NAME('emp_credit_bal')
FROMDUAL
/
DBMS_ASSERT.SIMPLE_SQL_NAME('EMP_CREDIT_BAL')
-----------------------------------------------
emp_credit_bal
Anyviolationinthenamingconventionwouldthrowanexception:
/*VerifyanunquotedidentifierusingSIMPLE_SQL_NAME*/
SELECTDBMS_ASSERT.SIMPLE_SQL_NAME('1emp_credit_bal')
FROMDUAL
/
*
ERRORatline1:
ORA-44003:invalidSQLname
ORA-06512:at"SYS.DBMS_ASSERT",line206
AnidentifierwithmorethanoneSQLnameshouldbevalidatedthroughQUALIFIED_SQL_NAME.Aqualifiermayincludeaschemaname,anobjectname,oradatabaselink:
/*VerifyanunquotedqualifierusingSIMPLE_SQL_NAME*/
SELECTDBMS_ASSERT.SIMPLE_SQL_NAME('scott.emp_credit_bal')
FROMDUAL
/
SELECTDBMS_ASSERT.SIMPLE_SQL_NAME('scott.emp_credit_bal')FROMDUAL
*
ERRORatline1:
ORA-44003:invalidSQLname
ORA-06512:at"SYS.DBMS_ASSERT",line206
/*VerifyanunquotedqualifierusingQUALIFIED_SQL_NAME*/
SELECTDBMS_ASSERT.QUALIFIED_SQL_NAME('scott.emp_credit_bal')FROMDUAL
/
DBMS_ASSERT.QUALIFIED_SQL_NAME('SCOTT.EMP_CREDIT_BAL')
---------------------------------------------------------
scott.emp_credit_bal
SchemanamesandobjectnamescanbedistinctlyverifiedusingtheSCHEMA_NAMEandSQL_OBJECT_NAMEsubprogramsofDBMS_ASSERT.Forexample,thefollowingSELECTqueryverifiestheschemanameandobjectnamebeforesanitizingthequalifier:
/*VerifyanunquotedqualifierusingQUALIFIED_SQL_NAME*/
SELECTDBMS_ASSERT.QUALIFIED_SQL_NAME(
DBMS_ASSERT.SCHEMA_NAME('SCOTT')||'.'||
DBMS_ASSERT.SQL_OBJECT_NAME('emp_credit_bal'))obj
FROMDUAL
/
OBJ
------------------------
SCOTT.emp_credit_bal
TipSCHEMA_NAMEisacase-sensitivesubprogram.Alowercasestringinputwillnotbeverifiedasaschemaname.
Quotedidentifiers
Aquotedidentifierisalwaysenclosedwithindoublequotesandfollowsnonamingconvention.Itmaystartwithanumberorevencontainanyspecialcharacter.YoucanuseSIMPLE_SQL_NAMEtocheckthesanityofquotedidentifiers:
/*Unquotedidentifierwithspecialcharactersraiseexception*/
SELECTDBMS_ASSERT.SIMPLE_SQL_NAME('***emp_credit_bal***')
FROMDUAL
/
ERRORatline1:
ORA-44003:invalidSQLname
ORA-06512:at"SYS.DBMS_ASSERT",line206
/*Quotedidentifierwithspecialcharactersreturnvalue*/
SELECTDBMS_ASSERT.SIMPLE_SQL_NAME('"***emp_credit_bal***"')FROMDUAL
/
DBMS_ASSERT.SIMPLE_SQL_NAME('"***EMP_CREDIT_BAL***"')
--------------------------------------------------------------
"***emp_credit_bal***"
YoucanalsousetheENQUOTE_NAMEsubprogramtoencloseaconstantvalueoridentifierindoublequotes.Quotedidentifiers,whicharequalifiers,canbeverifiedusingtheQUALIFIED_SQL_NAMEsubprogram.
NoteTheOracle-suppliedDBMS_UTILITY.NAME_TOKENIZEsubprogramhelpsindifferentiatingasimpleSQLnamefromaqualifiedSQLname.
Literals
AliteralcanbeanyfixedconstantusedinaSQLqueryoraPL/SQLprogram:
/*DemonstratetheuseofaliteralinaSELECTquery*/
SELECT*
FROMemp
WHEREename='KING'
/
/*Use(EMP)asaliteral*/
SELECT*
FROMuser_tables
WHEREtable_name='EMP'
/
Whileworkingwithliterals,youcanuseENQUOTE_LITERALtosanitizetheclient-suppliedinputsandavoidadditionalpredicatesortheunionSELECTquery.Let’slookatauserinputthatwasusedearliertoinjectandextractthecreditcardinformationofemployees:
/*Sanitizetheinputbeforesupplyingittoprocedurecall*/
DECLARE
l_ccVARCHAR2(4000):='''XXX''ORDEPTNO=10';
BEGIN
/*SanitizeusingDBMS_ASSERT*/
l_cc:=DBMS_ASSERT.ENQUOTE_LITERAL(l_cc);
p_rep_cc_bal(l_cc);
END;
/
DECLARE
*
ERRORatline1:
ORA-06502:PL/SQL:numericorvalueerror
ORA-06512:at"SYS.DBMS_ASSERT",line409
ORA-06512:at"SYS.DBMS_ASSERT",line493
ORA-06512:atline4
TheprecedingblockthrowsanexceptionbecausetheclientinputcouldnotbeverifiedbytheDBMS_ASSERTpackage.
DBMS_ASSERT–limitationsThelimitationsoftheDBMS_ASSERTpackagearelistedasfollows:
NovalidationfortheTNSconnectionstrings.Novalidationforstringlengthsorbufferoverflowattacks.NovalidationforthevalidityofSQLidentifiers.Novalidationforobjectprivilegesortheunintendeduseofprivileges.Forprivilegeevaluation,youcanusetheOracleDatabase12cprivilegeanalysisfeaturetodeterminewhethertoretainorrevokeobjectprivileges.
UseofbindvariablestopreventinjectionattacksUsingbindvariablesisagoodprogrammingpractice.Fromaperformancestandpoint,bindvariableseliminatehardparsesofSQLstatementsandimprovetheperformanceofaPL/SQLblock.Fromasecuritystandpoint,abindvariableavoidstheconcatenationofliteralvaluestoadynamicSQLstatement.
Let’srevisitthecreditcardcasestudyandrewritetheprocedurewiththehelpofbindvariables.NotetheuseoftheB_CARD_NObindvariableintherefcursor:
/*Re-writetheprocedureP_REP_CC_BALtousebindvariables*/
CREATEORREPLACEPROCEDUREp_rep_cc_bal(p_card_noVARCHAR2)
IS
/*Declarerefcursorvariable*/
TYPEc_refISREFCURSOR;
cc_balC_REF;
/*DeclarerecordstructureofEMP_CREDITBALrowtype*/
emp_cc_recemp_credit_bal%rowtype;
BEGIN
/*Opentherefcursorvariablewithabindvariable*/
OPENcc_balFOR'SELECT*FROMemp_credit_bal
WHEREsubstr(card_no,-4,4)=:b_card_no'
USINGp_card_no;
LOOP
/*Iteratetheresultsetandprintthecreditcardinfo*/
FETCHcc_balINTOemp_cc_rec;
EXITWHENcc_bal%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(RPAD('_',50,'_'));
DBMS_OUTPUT.PUT_LINE('EmpName/Title:'||emp_cc_rec.ename||'|
'||INITCAP(emp_cc_rec.job));
DBMS_OUTPUT.PUT_LINE('EmpCCard:'||emp_cc_rec.card_no);
DBMS_OUTPUT.PUT_LINE('CCardBalance:'||emp_cc_rec.credit_balance);
ENDLOOP;
CLOSEcc_bal;
END;
/
SETSERVEROUTPUTON
Youcanchecktheprocedureoutputwithatestinput:
/*VerifywithInput-1*/
EXECp_rep_cc_bal('0345');
__________________________________________________
EmpName/Title:SMITH|Clerk
EmpCCard:4020-3009-1084-0345
CCardBalance:2844
PL/SQLproceduresuccessfullycompleted.
Let’sinvoketheprocedurewiththemanipulatedinputs,whichwereearlierusedtoaccess
restricteddata:
/*VerifywithInput-2*/
EXECp_rep_cc_bal('''XXX''ORJOB=''PRESIDENT''');
PL/SQLproceduresuccessfullycompleted.
/*VerifywithInput-3*/
EXECp_rep_cc_bal('''XXX''ORDEPTNO=10');
PL/SQLproceduresuccessfullycompleted.
/*VerifywithInput-4*/
EXECp_rep_cc_bal('''XXX''OR1=1');
PL/SQLproceduresuccessfullycompleted.
Well,noneofthemreturnedanoutput,becausethebindvariablevalueorthetweakedinputdidn’tcreateavalidSQLcursor.Therefore,itcouldnotbeexecuted.
BestpracticestoavoidSQLinjectionTherearemultiplebestpracticestomitigatetheeffectofSQLinjection.Theobjectiveofthesebestpracticesistoreducetheattacksurfaceareabycoveringthevulnerableareasofthedatabasecode.Thelistedbestpracticesaresafetofollowandeasytoremember:
AvoiddynamicallyconstructedSQLquerytextinthePL/SQLprogramunits.UsestaticSQLwhereverpossible,asitavoidsthecodevulnerability.WithdynamicSQL,bindvariablesshouldbeused.ExposedatabaseprogramunitstotheclientthroughtheAPIunitsonly.MonitorandcontroltheobjectprivilegescarefullybeforegrantingtheEXECUTEprivilegeonanobjecttoauser.EncouragetheuseoftheDBMS_ASSERTsubprograminpolicing;notjustforuserinputs,butalsodynamicSQLtextsandplaceholdervaluesinaSQLstatement.Applicationclientscanalsoprogrammaticallyrestrictarbitraryinputsandallowonlytheexpectedones.ExamineandevaluatetheuseofPUBLICprivileges.Encouragetheadoptionofdatasecuritysolutionssuchasencryption,dataredaction,databasevault,auditvault,anddatabasefirewall.
TestingthecodeforSQLinjectionflawsSofar,wehavediscussedthesymptomsandremediesofSQLinjection.Wedemonstratedtheprogrammingrecommendationstomitigatetheeffectsofcodeinjectionsandsmuggles.Assuringcodequalityduringthetestingcycleplaysacrucialroletowardspreventingcodeattacks.Thecodetestingresourcesmustadoptaconcretestrategytodiscoverandhituponthecode’svulnerabilitiesbeforeitinvitesanattackertoexploitthedatabase.Now,wewilldiscusssomeofthetestingconsiderationstotestthecodeforSQLinjectionflaws.
TeststrategyAlogicalandefficientteststrategymustbeemployedtodiscoverinjectionflaws.Ofcourse,thereisnomagicbullettofilteroutallthevulnerabilitiesofapieceofcode.
Usualcodereviewsareapartofstatictestingwhiletestingprogramswithsampledataandinputscomeunderdynamictesting.Thesedays,statictestinghasbeenabsorbedintothedevelopmentstage,wheredevelopersandtheirpeersandseniorsreviewthecode.Majorsyntacticalerrors,logicalissues,codepractices,andinjectionbugscanbetracedatthislevel.TheDryRunconceptcanevencheckmultiplescenariosandensurebug-freeapplicationsubmissiontothequalityassuranceteam.
AneffectivecodereviewAsacodereviewer,thefirstandforemoststepistomeasuretheattacksurfacearea.Thecodereviewermustverifytheexposureofthedatabaseprogramunitsintheapplicationinterfacelayer.Inaddition,theymustchecktheprivilegesavailabletothedatabaseusers.Oncethesestepsarepassedwiththerightjustification,thePL/SQLcodecanbereviewedtoidentifythevulnerableareas.InPL/SQL-basedapplications,alwaysbecarefultolookfor:
DynamicSQLusing:
EXECUTEIMMEDIATEREFCURSORqueriesDBMS_SQL
DBMS_SYS_SQL
CheckfortheappropriateusageofbindargumentsParametersanitizationusingDBMS_ASSERT
Similarly,inaJavaorCclientarchitecture,thereviewermustlookfordynamiccallablestatementpreparation.
StaticcodeanalysisSQLinjectionattacksaremostlyduetocodingunawarenessanddynamicSQL.Therefore,staticcodeanalyzerscannoteasilytraceanapplication’svulnerability.TheOracledocumentationdefinesstaticcodeanalysisasfollows:
Staticcodeanalysisistheanalysisofcomputersoftwarethatisperformedwithoutexecutingprogramsbuiltfromthatsoftware.Inmostcases,theanalysisisperformedonsomeversionofthesourcecodeandinothercases,someformoftheobjectcode.Thetermisusuallyappliedtotheanalysisperformedbyanautomatedtool.
Itisadvisablethatsuchanalysistoolsshouldnotbeconsideredasthetestingbenchmarkandconfirmatorytools.Instead,theycanbeusedforwhiteboxtesting,wheretheapplicationistestedforasmoothlogicalflowandtheprogramexecutionsfordifferentnatureofinputdata.
FuzztoolsFuzztestingisaroughtestingthatisnotbasedonanypresetlogicorusecase.Itmeasurestheapplication’ssustainabilityagainstjunkandmaliciousinputs.Withoutanypreconceptionofthesystemorprogrambehavior,itusesrawinputstochecktheprogramsemantics.Theenvironmentforfuzztestingtoolscanbeexplicitlymadebymodifyingthecontextvaluesandmanipulatingthetestdatatoallodds.
Thebugsreportedinfuzztestingmaynotalwaysberealthreatstotheapplication,buttheymayprovideacluetothevulnerabilityattacks.
GeneratingtestcasesThelastandthefinalcallisthepreparationoftestcases.Althoughthisisskippedduringthedevelopmentstage,thetestcasesserveastheproofoftestingatlaterstages.Testcasescanmeasuretherobustnessofdatabaseprograms,applicationsecurity,andthevalidationofclientinputs.
SummaryInthischapter,welearnedaboutamalicioushackingconcept—SQLinjection.Wediscussedthecausesofacodeattackanditsimpactonthedatabase.Wecoveredthetechniquestosafeguardanapplicationagainsttheinjectionattacksthroughdemonstrationsandillustrations.Attheendofthechapter,wediscussedsomeofthetestingconsiderationstoexposethevulnerableareasinthecode.
PracticeexerciseWhichmethodwouldyouemploytoprotectthePL/SQLcodeagainstSQLinjectionattacks?
1. ReplaceDynamicSQLswithStaticSQLs.2. ReplaceconcatenatedinputsinDynamicSQLwithbindarguments.3. DeclarethePL/SQLprogramtobeexecutedbyitsinvoker’srights.4. Removestringtypeparametersfromtheprocedure.
YoushouldusestaticSQLtoavoidSQLinjectionwhenallOracleidentifiersareknownatthetimeofcodeexecution.
1. True.2. False.
ChoosetheimpactofSQLinjectionattacks:
1. Maliciousstringinputscanextractconfidentialinformation.2. Unauthorizedaccesscandropadatabase.3. ItcaninserttheORDERdataintotheEMPLOYEEStable.4. Aprocedureexecutedbyowners,(SYS)rightscanchangethepasswordofauser.
PickthecorrectstrategiestofightagainstSQLinjection:
1. SanitizethemaliciousinputsfromtheapplicationlayerwithDBMS_ASSERT.2. RemovestringconcatenatedinputsfromtheOraclesubprogram.3. DynamicSQLshouldberemovedfromthestage.4. ExecuteaPL/SQLprogramwithitscreator’srights.
Statisticalcodeanalysisprovidesanefficienttechniquetotracetheapplication’svulnerabilitybyusingidealandexpectedparametervalues.
1. True.2. False.
Thefuzztooltechniqueisaharshandrigorousformatoftestingwhichusesrawinputsandchecksaprograms’sanctity.
1. True.2. False.
ChoosetheobjectivesthatcanbeaddressedbytheDBMS_ASSERTpackagetopreventSQLinjection
1. Encloseagivenstringinsinglequotes.
2. Encloseagivenstringindoublequotes.3. Verifyaschemaobjectname.4. VerifyasimpleSQLandqualifiedSQLidentifier.
IdentifythenatureofthetablenameinthefollowingSELECTstatement:
SELECTTOTAL
FROM"ORDERS"
WHEREORD_ID=P_ORDID
/
1. Aunquotedidentifier.2. Aquotedidentifier.3. Aliteral.4. Aplaceholder.
WhichofthefollowingDBMS_ASSERTsubprogramsmodifiestheinputvalue?
1. SIMPLE_SQL_NAME.2. ENQUOTE_LITERAL.3. QUALIFIED_SQL_NAME.4. NOOP.
ThecodereviewsmustidentifycertainvulnerablekeyareasforSQLinjection.Selectthecorrectonesfromthefollowinglist:
1. DBMS_SQL.2. BULKCOLLECT.3. EXECUTEIMMEDIATE.4. REFCURSOR.
TheAUTHIDCURRENT_USERclauseachieveswhichofthefollowingpurposes?
1. Thecodeexecuteswiththeinvoker’srights.2. Thecodeexecuteswiththecurrentloggedinuser.3. IteliminatesSQLinjectionvulnerabilities.4. Thecodeexecuteswiththecreator’srights.
Chapter12.WorkingwithOracleSQLDeveloperSQLDeveloperisanintegrateddevelopmentenvironmentfromOraclethatservesasaone-stopsolutionformajorOracleDatabaseactivities,therebystandardizingthedevelopmenttasksandenhancingtheproductivityofdatabaseprofessionals.Asafreegraphicaluserinterface(GUI)tool,SQLDeveloperoffersawidesetoffeaturesandsolutionsfordatabasedevelopment,administration,andmanagement,inon-premiseandclouddeployments.TheSQLDevelopertoolsupportsOracleDatabase10g,11g,and12c.
Fordatabasedevelopers,SQLDeveloperoffersricheditorsforworkingwithcoreandadvancedfunctionalities,suchasexecute,debug,andtest,usingSQL,PL/SQL,XML,StoredJavaprocedures,querytuning,andmuchmore.DatabaseadministratorscanuseSQLDevelopertoperformvariousoperationslikedataexportandimportviadatapump,databasebackupandrecoverytasksviaRMAN,resourcemonitorandmanagement,performanceanalysisanddiagnosis,usedatamodelerandthird-partymigration.
Inthischapter,wewilldescribethebenefitsofSQLDeveloper,fordatabaseadministrators,andarchitects.Notethatthechapterdoesnotintendtoprovideastep-by-steptutorialforvarioustooloperations.Theoutlineofthechapterisasfollows:
OverviewofSQLDeveloper
KeydifferentiatorsHistoryandbackgroundSQLDeveloperforDBASQLDeveloperforDevelopers
GettingstartedwithSQLDeveloperNewfeaturesofSQLDeveloper4.0and4.1
AnoverviewofSQLDeveloperSQLDeveloperisafreeintegrateddevelopmentenvironmentfromOraclethatallowsthedatabasecommunitytodevelopPL/SQLapplicationsand,performadministrativetasks,andenablesmanagementactivitiessuchasdatamodeling,versioning,scripting,andthird-partymigration.ThelatestversionofSQLDeveloper(asofthetimeofwritingthisbook)is4.1.1.
ThetoolisbuiltusingJava(onJDeveloperFramework),whichenablesittorunonWindows,Linux,andMacOSX.Bydefault,itusesthethinJDBC(TypeIVJavadriver)drivertoconnecttothedatabase,thusreducingtherequirementsofanyfurtherdatabaseclients.Inaddition,theextensiblearchitectureofSQLDeveloperallowsthedevelopercommunitytoincorporatetheirowncustomextensionsintothetool.YoucanleverageOracleJDeveloper’sExtensionSDK(SoftwareDevelopmentKit)todevelopandaddtherequiredfunctionalityasanextensiontotheSQLDevelopertool.
TipVisittheSQLDeveloperExtensionsExchange(http://www.oracle.com/technetwork/developer-tools/sql-developer/extensions-083825.html)tolookforextensionsthatwerebuiltwithinandoutsideOracle.
KeydifferentiatorsThefollowingarethekeyfactorsthatdifferentiateSQLDeveloperfromothercontemporarytools:
SQLDeveloperisafreetoolandshippedalongwiththeOracleDatabasesoftware.Noseparateinstallationisrequired.OraclesupportisavailableforthecustomerswhohavelicensedtheOracleDatabase.Itsupportstraditionalon-premiseaswellasclouddeploymentsofOracleDatabase.ItsupportsdatabaseproductssuchasDataMiner,TimesTen,Spatial,andGraph.Itisdeveloper-richandadministrator-friendlytoo.TheDBAconsoleprovidesawidesetoffeaturesforadministrativetasks.Therearepre-builtreportsforprovidinginformationaboutthedatabasemanagement,databaseschemas,andperformance.Thereisprovisionforcreatingcustomreportsandcreatingmultilevelwithpredefinedreports.Thereislogical,relational,andphysicalmodellingenabledthroughtheDataModelerextension.IthastheabilitytoconnecttonotjusttheOracleDatabase,butalsonon-OracledatabasessuchasSQLserver,Sybase,andDB2.BuildontheJDeveloperframework.Thereisprovisionforincludingcustom-builtextensionsinthetool.ThereisawidecommunityofSQLDeveloperuserswhointeractthroughvariouschannels,suchasOracleTechnologyNetworkforums,developercommunities,andblogs.UsersareencouragedtoparticipateintheOracleSQLDeveloperExchangeprogram(https://sqldeveloper.oracle.com),whereyoucanregisterafeaturerequestandsubmitcodesnippetsortooltips.
HistoryandbackgroundThefirstreleaseofSQLDeveloperwasmadeinMarch2006.Theinitialreleaseincludedthebasicfunctionalities,suchasexecutingSQLqueriesandPL/SQLblocks,andinvokingSQL*Plusscripts.Thereafter,therewereafewquickpatchesandanimportantreleaseofSQLDeveloper1.1wasmadeinDecember2006.Sincethen,thetoolhasevolvedwithabroadspectrumoffeaturesandsupportfordatabaseoptions.
Let’stakeaquickglanceattheearlierreleasesoftheSQLDevelopertool:
SQLDeveloperreleaseversion
Releasedate Keynewfeatures
SQLDeveloper1.0 March2006 InitialreleaseenabledtheexecutionofSQLandPL/SQLstatements
SQLDeveloper1.1 December2006
File-basedPL/SQLediting.PatchesSQLDeveloper1.1.1(Jan2007),SQLDeveloper1.1.2(March2007),andSQLDeveloper1.1.3(May2007)
SQLDeveloper1.2 June2007 DevelopermigrationworkbenchSupportforOracleApplicationExpress3.0.1
SQLDeveloper1.5 April2008 Supportforversioncontrol
SQLDeveloper2.1 December2009
Third-partydatabasemigrationsupportPL/SQLunittestingIntegrateddatamodelerviewer
SQLDeveloper2.1.1 March2010 Patchrelease
SQLDeveloper3.0 March2011
QuerybuilderDBAnavigatorSchedulebuilder
SQLDeveloper3.1 February2012
SupportforRecoveryManager(RMAN)SupportforDataPumpPDFreporting
SQLDeveloper3.2 November2012
SupportformanagingtheAPEXlistenerImprovedDatabaseDiffandDBDOCfeatures
SQLDeveloper4.0 December2013
SupportforOracleDatabase12cMultitenantandDatabaseasaServiceplatformStablereleasewithupdatedframework
SQLDeveloper4.1 May2015OptimalmemoryfootprintRequirementforJava7JDKSupportsubversion1.7
SQLDeveloperforDevelopersSQLDeveloperprovidesapowerfuleditorforrunningandanalyzingSQLqueriesanddevelopingPL/SQLprograms.Asadatabasedeveloper,youcanbrowseschemaobjects,viewobjectattributes,andcompilestoredsubprograms.YoucanrunaSQLquery(orinvokeascript),retrievetheresult,exportitintoanXML,XLS,orPDF,andexaminethequeryexplainplan.Youcancreate,edit,debug,compile,ordropstoredPL/SQLsubprograms.
SQLDeveloperforDatabaseAdministratorsInitsinitialdays,SQLDeveloperwasadeveloper-centrictool.However,thelaterreleasesofthetoolbroadeneditsadministrativeofferings.Databaseadministratorscanperformtheirroutinedatabaseactivitiesincludingstoragemanagement,backupandrecoveryoperations,dataexportandimport,databaseauditing,diagnosticspackfeatures,anddatabaseresourcemanagement.
ThelatestversionofSQLDevelopersupportspluggabledatabaseoperationsinamultitenantcontainerdatabase.Youcancreate,drop,unplug,plug,orclone,apluggabledatabase.
TheManageDatabaseoptionintheconnectiontreeallowsauserwithSYSDBAprivilegetoreporttheusageofdatabasetablespaces.Besides,thereareavarietyofpre-definedDatabaseAdministrationreports,whichfurnishagreatdealofinformationfromadatabase-managementstandpoint.AnewdedicatedDBApanelisavailablefordatabaseadministrationactivities.ExistingDBAconnectionscanbecopiedfromtheconnectiontreetotheDBApanelandcanbeusedtomanagetheOracleDatabase.
Notonlyfordevelopersandadministrators,SQLDevelopersuccessfullyconnectsthearchitectcommunityaswell.DatabasearchitectscanperformdatamodelingwiththeSDDM(SQLDeveloperDataModeler)module,integratedwithSQLDeveloper.
SQLcl–ThenewSQLcommandlineSQLclisthemodernizedandrebrandedversionofthegoodoldSQL*Plus.SQL*Plushasbeentheprimarycommand-lineinterfaceforSQLexecutionformanyyears.
OracleSQLDeveloper,asweareallaware,providesmultiple-userinterfacefeaturesforapplicationdeveloperstoformatandeditSQLtext,exportqueryresultindesiredfileformats,objectnamecompletion,maintainsSQLhistory,anddoesmuchmore.SQLcl,beingacommand-lineinterfaceutility,inheritsthedeveloper-friendlyformattingandeditingelementsofSQLworksheetfromtheSQLDeveloper.WithSQLcl,thedeveloperanduserexperienceswillbeimprovedbyanorderofmagnitude.
NoteYoucandownloadtheSQLcl-EarlyAdopterbinariesfromthedownloadspageofSQLDeveloper(http://www.oracle.com/technetwork/developer-tools/sql-developer/downloads/index.html).
Currently,theutilityisavailableforstandalonedownload,butinfutureitwillbepartoftheSQLDeveloper4.1andOracleDatabase12cRelease2softwarepackages.Forinstallation,youmusthaveJavaRuntimeEnvironment(JRE)1.7orhigheronyoursystem.
NoteFortheSQLcloverview,watchtheYouTubevideoathttps://www.youtube.com/watch?v=HApdy-o525A.
Let’sbrieflydiscusssomeofthekeyfeaturesandcommandsofSQLcl:
Databaseconnection:SQLclsupportsdatabaseconnectionthroughEZConnect,TNSfromtheOracleclientortheTNS_ADMINenvironmentvariable,andLDAP.YoucanstorethedatabaseconnectionsusingtheNETcommand.Object-name/Commandcompletion:PressingtheTabkeywhileyoutypeanobjectnamewillauto-completetheobjectnameinuppercase.Multilineedits:InsteadofusinganeditortomakechangestotheSQLquery,SQLclallowsyoutoworkwiththekeyboardkeys(Enter,Backspace,forwardandbackward)toedittheSQLquery.ALIAS:SQLclenablesyoutocreateanaliasforanSQLqueryoraPL/SQLblock.Toinvokethealias,simplytypethealiasnameintheSQLclprompt.CD:SimilarlytotheOScommand,youcanchangethedirectoryfromtheSQLclinterfacebyusingtheCDcommand.ThiscommandwillpreventSQLdevelopersfromincludingOSpathsinthescripts.CTAS:ThisacronymcanbeuseddirectlyinplaceofCREATETABLEASSELECTtogenerateaDDLscriptofanewtablefromanexistingone.YoucantransformthecommandoutputbysettingthetransformationparametersusingtheDBMS_METADATApackage.DDL:ThiscommandgeneratestheDDLscriptforagivenobject(itoptionallywritestheoutputtoafiletoo).
SQLFORMAT:Youcanapplydifferentformatstothequeryresults.Itmaybeapplyingadifferentcolorinansiconsole,JSON,XML,CSV,HTML,insert,loader,delimited,ortext.SQLhistory:SQLclstoresthelast100commandsexecutedbyallthedatabaseusers.INFORMATION:ThenewSQLclcommandisanadvancedversionoftheDESCRIBEcommand.Besideslistingtheobjectstructureoraprogramsignature,theINFOandINFO+commandsprovidemoredetailedinformation.
GettingstartedwithSQLDeveloperTostartworkingwiththeSQLDevelopertool,youmustfollowthefollowingsteps:
1. DownloadthelatestbinariesoftheSQLDevelopertoolfromtheOracleTechnologyNetwork.
NoteGotohttp://www.oracle.com/technology/products/database/sql_developerforthemostrecentstandaloneversionofthetool.Thistoolcanbedownloadedforfree.
2. Alternatively,youmayalsofindthesoftwarebinariesshippedalongwiththeOracleDatabaseorOracleJDevelopersoftwaremedia.
3. EnsurethattheJavaDevelopmentKit(JDK)isinstalledonthetargetsystem.Usually,theSQLDeveloperproductdoesn’tincludetheJDKexceptonMicrosoftWindows.OnWindows,aversionofproductbinariesalsoincludestheJDK.Afterstartup,thecorrectJDKpathmustbespecifiedforSQLDeveloper.
4. RunthesqldeveloperexecutablefromtheunzippedSQLDeveloperfolder.SpecifythefullpathoftheJDK:
TheSQLDeveloperhomepageincludesmultipletutorialstohelpyougetstarted,anditassistsyouwiththekeyfunctionalitiesofthetool:
CreatingadatabaseconnectionIfyouknowthelogincredentialsofadatabaseuser,youcansavetheconnectiondetailswithinSQLDeveloper.Thelogincredentialsincludetheusername,password,serverIPaddress,anddatabaseSID.ThefollowingimageshowshowtocreateadatabaseconnectioninSQLDeveloper:
Thestepsforcreatingadatabaseconnectionareasfollows:
1. ProvideaConnectionName,databaseUsername,andPassword.2. Providetheconnectiontype,role(default/SYSDBA),anddatabaseserverdetailssuch
asthemachinenameorIPaddress,Port,anddatabaseSID.3. ClickonTesttoverifytheconnectiondetails.Status:Successwillconfirmthe
connectionproperties.4. ClickonSavetostoretheconnectionpropertiesforfutureuse.5. ClickonConnecttoconnecttothedatabaseusingthecurrentconnectiondetails.
UsingtheSQLworksheetAfterestablishingtheconnectiontothedatabase,SQLDeveloperopensupanSQLworksheettoexecuteSQLqueriesandPL/SQLprograms.
Forexample,thefollowingscreenshotfromSQLDevelopershowsaSELECTqueryontheEMPtableandthequeryoutputinthefollowinggrid.NotetheschemabrowserandtheDBApanelintheleftpaneofthetool:
SQLWorksheetintheSQLDeveloper
EachoftheSQLworksheetscomprisemultipleicons,asshowninthefollowingfigure:
Thefunctionofeachicon,goingfromlefttoright,isdescribedasfollows:
RunStatement:SelectanSQLquerytextorPL/SQLblockandclickonthisto
executeitRunScript:executeastoredscriptExplainPlan:generatetheexplainplanofanSQLAutotrace:examinetheautotraceparametersSQLTuningAdvisor:analyzesimpleorcomplexSQLstatementsandprovidetuningrecommendationsCommit:COMMITanactivetransactionRollback:ROLLBACKatransactionOpenaSQLWorksheet:openanonsharedSQLworksheetToUpper/Lower/Initcap:changethecaseofthequeryidentifiersClear:clearthecontentoftheSQLworksheetSQLHistory:listtheSQLstatementspreviouslyexecutedTimesTenIndexAdvisor:analyzetheSQLworkloadandrecommendindexes
Theresultinggridatthebottomprovidesiconsforpinningaqueryresult,printingoutput,refreshingtheresult,anddisplayingtheSQLstatement.Attheresultsetlevel,itincludesthefollowingfunctionalities:
SaveGridasReport:ThisallowstheusertosaveanSQLqueryasareport.SingleRecordView:Thisprovidesasinglerecordviewinadialogbox.CountRows:Thisreturnsthecountofrowsinthequeryresultset.Find/Highlight:Thissearchesfortextandhighlightsitsoccurrences.PublishtoAPEX:ThisallowsquickcreationofanAPEXapplicationpagefromtheSQLquery.Itrequiresdetailssuchastheworkspace,applicationname,theme,pagename,andunderlyingSQL.Export:Thisexportsthequeryresultsetasinsertscripts,SQL*Loader,CSV,delimited,HTML,XLS,PDF,orXML.
CorefeaturesofSQLDeveloperThecorefunctionalitiesofSQLDeveloperarethosethathelpdevelopersandadministratorstodrivetheirday-to-dayactivitieswitheaseandenhancedproductivity.
ObjectBrowserYoucanbrowsetheobjectsinauserschemabyexpandingasavedconnection(whichrepresentsaschema).Youcanfindtables,(editioning)views,indexes,packages,procedures,functions,(crossedition)triggers,types,sequences,materializedviews,materializedviewlogs,(public)synonyms,(public)databaselinks,editions,directories,andotherschemaobjects.
PL/SQLEditorandDebuggerTheprocedureeditorallowsyoutocreateoreditaPL/SQLpackage,storedprocedure,orstoredfunction.Youcancompile/compilefordebug,debug,orprofiletheprogramunitsfromtheeditor.
Thefollowingscreenshotshowsaprocedure,P_CALC_POINT_CALLSTACK,intheprocedureeditor.NotetheErrors,Grants,Profiles,References,Details,andDependenciestabs.Thetoolbariconsallowtheusertorun,debug,compile,setread-onlymode,andprofiletheprogramunit:
DBAPanelYoucaneitheraddexistingconnectionsfromtheconnectiontreeorcreateanewconnectionwithSYSDBAprivileges.UndertheDBApanel,youcanperformthecorefunctionsofadatabaseadministratorliketheoneshowninthefollowingfigure:
NoteUseofPerformanceunderDBAConsolerequiresOracleDiagnosticsPack.ItisincludedinSQLDeveloper4.0.
DatabaseUtilitiesThissectionbrieflydescribesthedatabaseutilitiesavailableinSQLDeveloper:
DatabaseCopy:Thisallowsthecopyingofdatafromoneconnectiontoanotherconnection.Copyoptionscanbeobjectcopy,schemacopyortablespacecopy.DatabaseDiff:Thisutilitycomparestwoconnectionsonallorselectedtypesofobject,andgeneratesthedeltareport.DatabaseExport:Thisisusedtogeneratethecreation(DDL),aswellasdatainsertscripts,forallselectedobjecttypes.Migration:Thisisusedtomigrateathird-partydatabasetoOracle.Thenon-Oracle
databasesthatcanbetranslatedtoOraclecanbeMySQL,MicrosoftSQLServer,Sybase,andIBMDB2.SQLDeveloperallowsyoutocreateadatabaseconnectiontothenon-Oracledatabases.Themigrationprocessinvolvesthecreationofamigrationprojectandamigrationrepositorytoholdthemetainformationofthenon-Oracleobjects.Thetranslationframeworkisthenusedtotranslateallnon-OracleobjectstoOracle-specificcodeandgeneratetheDDLscripts.AftertheDDLscriptsareexecuted,thelaststepoftheprocessisdatamigration.SQLMonitor:Thisenablesreal-timeSQLmonitoringforaconnection.ThefeaturerequirestheOracleTuningPack.
TheDataModelerTheDataModelerisafreedatabasedesignandmodelingtoolintegratedwithSQLDeveloper.SQLDeveloperprovidesagraphicaluserinterfacetocreateandmanagedatamodels.TheuniquecapabilitiesoftheDataModelersimplifymodelingtasksandhelpsdesignerstoachievebetterproductivity.AlthoughitisintegratedwithSQLDeveloperasanextension,thetoolisavailableforstandalonedownloadaswell.
Thistoolallowsyoutostrategizeandanalyzelogicaldatamodels.Italsoallowsyoutodrawrelationalandphysicaldatamodels.YoucanalsoimporttheERDsandsharethemwithyourpeersforreviewdiscussions,futurereference,re-engineeringormanagementapproval.
SQLDeveloperreportsOracleSQLDeveloperstoresmultiplepredefinedreports,whichrunbasedonuser-providedinputs.Theusermustsupplythevaluesforthebindvariablesrequiredforthereportexecution.Someofthepopularreportsareobjectreports,PL/SQLreports,andDBAreports.Objectreportscanbeusedtogeneratedependencytrackingandinvalidobjects.PL/SQLreportscanbeusedtoreporttheargumentusageinagivenprogramunitorcompleteschema.DatabaseadministrationreportscanbeusedtogeneratereportsonSQLcursors,databaseparameters,locks,memoryconsumption,session-wiseinformation,topSQLreports,andwaitsandevents.Otherreports,suchastheAWRandASHreports,revealactivesessionhistorystatisticsandthelastAWRgenerated.
Notethatthesereportsaredifferentfromtheuser-definedreports.TheOracle-definedreportsarenon-editable,buttheycanbeincludedintheuser-definedreportsaschildreportsormultilevelreports:
VersioncontrolSQLDeveloperincludessupportforversioncontrol,whichhelpsinmaintainingthesourcecodeversions.Youcanimplementsourcecontrolbyimportingthefilestobeversioned,check-outwhenrequired,andcheck-inafterthechangeshavebeencommitted.
TheSQLTranslationFrameworkTheSQLTranslationFrameworkisusedtotranslateSQLstatementsfromanon-OracleDatabasescripttoanOracleDatabaseSQLscript.ItisinstalledalongwiththeOracleDatabasesoftware.However,itmustbeconfiguredwiththeappropriateSQLTranslatortoidentifythenon-OraclecodeandconvertitintoOracle-compliantcode.Duringthetranslationprocess,aprofile(knownastheSQLTranslationProfile)isgeneratedfortheSQLTranslatortoreviewandeditthetranslations.ASQLTranslatormayhavemultipleSQLTranslationProfiles.
SQLDeveloper4.0and4.1NewFeaturesThelatestversion,SQLDeveloper4.1,introducesnumerousenhancementsandfeatures.Thefollowingisalistofnewfeatures:
SupportforJDK8:SQLDeveloper4.1runsonJDK8.Databaseperformancemonitoring:SQLDeveloper4.0includedanodeundertheDBAconnectiontreeforOracleDiagnosticsPack.Theperformanceengineerscannowcapturesnapshots,establishbaselines,runASHandAWR,anddisplayAutomaticDatabaseDiagnosticMonitor(ADDM)reports.FullsupportforOracleDatabase12cfeatures:SQLDeveloper4.0fullysupportstheOracleDatabase12cfeatures.Inamultitenantdatabase,acontainerdatabaseadministratorcancomfortablyworkwithSQLDevelopertomanagepluggabledatabases.Youcancreate,clone,drop,plug,orunplugapluggabledatabase.Similarly,youcancreateandmanagedataredactionpoliciesonthetables.YoucanalsocloneapluggabledatabasedirectlytotheOraclecloud.
OtherlanguageenhancementsinOracleDatabase12c,suchastheIDENTITYcolumns,FETCHFIRST,32KVARCHAR2support,implicitcursors,anddefaulttoasequencegenerator,enableefficientmigrationfromnon-OracletoOracle.
SupportforOracleDatabaseproducts:SQLDeveloper4.0supportsDataMining,TimesTen,XMLDB,andSpatialandgraphs.InstanceViewer:Withouttheneedforanagentinstallationontheserver,SQLDevelopercandisplayyourdatabaseinstancestatusandcurrentactivity.Theinstanceactivityislocallycachedandgraphicallydrawn,andgetsrefreshedfromtimetotime.FromtheDBAPanelconnectiontree,selectDatabaseStatusnodeandclickonDBInstance.Objectsearch:Theenhancedobjectsearchallowsanobjecttobesearchedacrossschemasandobjecttypesandthroughtheidentifiersandtheirappearances.Thehistoryofsearchedobjects,alongwiththechoices,issavedforfutureaccess:
Newsearchandreplace:Thesearchtextfieldintheprocedureeditorisenhancedtohighlighttheoccurrencesofsearchedtext,savethehistoryoftextssearched,andtoallowreplacementofexistingtextwithreplacementtext.Inaddition,multicursoreditingenableseasyformattingofmultiplerowsinanSQLworksheet.PDBcloningtoOracleDatabaseCloudService:SQLDeveloper4.1allowsaPDBtobecloneddirectlytotheOracleDatabaseCloud.AcloudconnectionmustbecreatedwiththeDatabaseCloudServiceenvironmentdetails.SupportforOracleNoSQLDatabase:SQLDeveloper4.1supportsOracleNoSQLKVLitestores.Importdatafromaspreadsheet:SQLDeveloper4.1allowsthedatafromaspreadsheettobedirectlyimportedintoatable.Thespreadsheetdatacanbeimportedtoanexistingtableoranewtable.
SummarySQLDeveloperhasmaturedimmenselyovertheyearsandhasemergedastheprimaryIDEforOracleDatabase.FullsupportforOracleDatabaseoptionsintraditionalaswellasclouddeploymentsandthemostrecentdatabasefeaturesarethekeydifferentiatorsofthetool.Thistoolisnotonlymeantforapplicationdevelopers,butalsoprovideswidesupportfordatabaseadministratorsandarchitects.SQLclisgainingalotoftractioninthedevelopercommunitybecauseofitsadvancedformattingandeditingfeatures.
IndexA
ActiveSessionHistory(ASH)/In-MemoryAdvisorAmericanNationalStandardInstitute(ANSI)/IDENTITYcolumnsarchivelogs/DatabaseconsolidationandthenewMultitenantarchitectureassociativeaarays
about/Collectiontypesassociativearrays
about/Associativearraysfeatures/Associativearrays
AutomaticDatabaseDiagnosticMonitor(ADDM)about/SQLDeveloper4.0and4.1NewFeatures
AutomaticSegmentSpaceManagement(ASSM)/DeduplicationandcompressionAutomaticWorkloadRepository(AWR)/In-MemoryAdvisor
BBasicFiles
migrating,toSecureFiles/MigratingBasicFilestoSecureFilesBFILE/BFILEbinaries,SQLDeveloper
URL,fordownloading/GettingstartedwithSQLDeveloperBinaryLargeObject(BLOB)/BLOBandCLOBBufferCache
versusResultCache/ResultCacheversusBufferCachebulkbinding/FORALLBULKCOLLECT/BULKCOLLECTbulkprocessing,inPL/SQL
about/BulkprocessinginPL/SQLBULKCOLLECT/BULKCOLLECTFORALL/FORALLFORALLandexceptionhandling/FORALLandexceptionhandling
CCharacterLargeObject(CLOB)/BLOBandCLOBcollection
overview/Introductiontocollectionsnon-persistentcollection/Introductiontocollectionspersistentcollection/Introductiontocollectionstypes/Collectiontypesassociativearray/Collectiontypesnestedtable/Collectiontypesvarray/Collectiontypes
collectionmethods,PL/SQLabout/PL/SQLcollectionmethodsEXISTSfunction/EXISTSCOUNTfunction/COUNTLIMITfunction/LIMITFIRSTfunction/FIRSTandLASTLastfunction/FIRSTandLASTPRIORfunction/PRIORandNEXTNEXTfunction/PRIORandNEXTEXTENDfunction/EXTENDTRIMfunction/TRIMDELETEfunction/DELETE
collectiontypescomparing/Comparingthecollectiontypesselecting/Selectingtheappropriatecollectiontype
compilationmodeselecting/Selectingtheappropriatecompilationmodesetting/Settingthecompilationmodesettings,querying/Queryingthecompilationsettings
COUNTfunction/COUNTcursorattributes
%ROWCOUNT/Cursorattributes,Cursorattributes%ISOPEN/Cursorattributes,Cursorattributes%FOUND/Cursorattributes,Cursorattributes%NOTFOUND/Cursorattributes,Cursorattributesabout/Cursorattributes
cursorexecutioncycleabout/Cursorexecutioncycle
cursorexecutioncycle,stagesOPEN/CursorexecutioncyclePARSE/CursorexecutioncycleBIND/CursorexecutioncycleEXECUTE/Cursorexecutioncycle
FETCH/CursorexecutioncycleCLOSE/Cursorexecutioncycle
cursorsabout/Cursors–anoverviewexecutioncycle/Thecursorexecutioncyclecursorattributes/CursorattributesCursorFORloop/CursorFORloop
cursorstructuresabout/Cursorstructuresimplicitcursors/Cursorstructures,Implicitcursorsexplicitcursors/Cursorstructures,Explicitcursorscursorexecutioncycle/Cursorexecutioncycle
cursorvariablesabout/Cursorvariablesweakrefcursor,types/Strongandweakrefcursortypesstrongrefcursor,types/Strongandweakrefcursortypesworkingwith/WorkingwithcursorvariablesSYS_REFCURSOR/SYS_REFCURSORasarguments/Cursorvariablesasargumentsrestrictions/Cursorvariables–restrictionscursordesign,considerations/Cursordesignconsiderationscursordesign,guidelines/Cursordesign–guidelines
Ddatabaseconnection
creating/Creatingadatabaseconnectiondatabaseconsolidation
about/DatabaseconsolidationandthenewMultitenantarchitecturedatabasedependency
managing/Managingdatabasedependenciesdirect/Managingdatabasedependenciesindirect/Managingdatabasedependenciesdirectdependency,displaying/Displayingthedirectandindirectdependenciesindirectdependency,displaying/Displayingthedirectandindirectdependenciesmetadata/Dependencymetadataissues/Dependencyissuesandenhancementsenhancement/Dependencyissuesandenhancements
DatabaseIn-MemoryversusResultCache/ResultCacheversusOracle12cDatabaseIn-Memory
databaseresourcemanager(DBRM)/CDBResourceManagementDatabaseUtilitiesoption
DatabaseCopy/DatabaseUtilitiesDatabaseDiff/DatabaseUtilitiesDatabaseExport/DatabaseUtilitiesMigration/DatabaseUtilitiesSQLMonitor/DatabaseUtilities
DataModelerabout/TheDataModeler
DBMS_ASSERTsubprogramused,forsanitizinginputs/SanitizinginputsusingDBMS_ASSERTunquotedidentifier/Unquotedidentifiersquotedidentifier/Quotedidentifiersliteral/Literalslimitations/DBMS_ASSERT–limitations
DBMS_HPROFpackageabout/TheDBMS_HPROFpackageandDBMS_PROFILER,differences/DifferencesbetweenDBMS_PROFILERandDBMS_HPROFsubprograms/DBMS_HPROFsubprogramsDataCollector/DBMS_HPROFsubprogramsAnalyzer/DBMS_HPROFsubprograms
DBMS_LOBpackageabout/TheDBMS_LOBpackageDBMS_LOBconstants/TheDBMS_LOBconstantsDBMS_LOBdatatypes/TheDBMS_LOBdatatypes
DBMS_LOBsubprograms/TheDBMS_LOBsubprogramsDBMS_METADATApackage
about/TheDBMS_METADATApackagedatatypes/DBMS_METADATAdatatypesandsubprogramsURL/DBMS_METADATAdatatypesandsubprogramssubprograms/DBMS_METADATAdatatypesandsubprogramstransformationparameters/TheDBMS_METADATAtransformationparametersandfiltersfilters/TheDBMS_METADATAtransformationparametersandfiltersdemonstration/Demonstration
DBMS_RESULT_CACHEpackageabout/TheDBMS_RESULT_CACHEpackageresultcachememoryreport,displaying/DisplayingtheresultcachememoryreportOracleDatabase12cenhancements,toPL/SQLfunctioncache/OracleDatabase12cenhancementstothePL/SQLfunctionResultCache
DBMS_TRACEpackageinstalling/InstallingtheDBMS_TRACEpackagesubprograms/DBMS_TRACEsubprograms
DBMS_TRACEsubprogramsURL/DBMS_TRACEsubprograms
deadcodeabout/Case2:WhenPLSQL_OPTIMIZE_LEVEL=1
DEFAULTONNULLclause/TheDEFAULTONNULLclausedensecollection/Nestedtablesdynamiclinkedlibrary(DLL)/ExternalProcedures,Nativeandinterpretedcompilationtechniques
EEarlyAdopterbinaries,SQLcl
URL/SQLcl–ThenewSQLcommandlineenvironmentsetup,externalprocedures
TNSNAMES.ora/TNSNAMES.oraEXTPROC.ora/EXTPROC.ora
exceptionhandlingabout/ExceptionhandlinginPL/SQLsystem-definedexceptions/System-definedexceptionsuser-definedexceptions/User-definedexceptionsexceptionpropagation/Exceptionpropagation
EXISTSfunction/EXISTSexplicitcursors/Cursors–anoverview,Cursorstructures
about/ExplicitcursorsEXTENDfunction/EXTENDexternalCprograms
executing,fromPL/SQL/ExecutingexternalCprogramsfromPL/SQLexternalLOB/ExternalLOBexternalprocedures
about/OverviewofExternalProcedures,ExternalProceduresexecutionflow,components/Componentsofexternalprocedureexecutionflowextprocagent/Theextprocagentlibraryobject/TheLibraryobjectcallout/CalloutandCallbackcallback/CalloutandCallbackcallspecification/CallSpecificationexecuting/HowanExternalProcedureexecutesenvironmentsetup/Environmentsetupsecuring,withOracledatabase12c/SecuringExternalProcedureswithOracleDatabase12c
extprocagent,externalprocedures/Theextprocagent
Ffeatures,SQLDeveloper
about/CorefeaturesofSQLDeveloperObjectBrowser/ObjectBrowserPL/SQLEditorandDebugger/PL/SQLEditorandDebuggerDataModeler/TheDataModelerSQLDeveloperreports/SQLDeveloperreportsversioncontrol/VersioncontrolSQLTranslationFramework/TheSQLTranslationFramework
FETCHFIRSTclause/RowlimitingusingFETCHFIRSTFine-grainedaccesscontrol(FGAC)
about/Fine-GrainedAccessControlworking/HowFGACworks
FineGrainedDependency(FGD)/DependencyissuesandenhancementsFIRSTfunction/FIRSTandLASTFORALL/FORALL
andexceptionhandling/FORALLandexceptionhandlingfunctionalities,SQLworksheet
SaveGridasReport/UsingtheSQLworksheetSingleRecordView/UsingtheSQLworksheetCountRows/UsingtheSQLworksheetFind/Highlight/UsingtheSQLworksheetPublishtoAPEX/UsingtheSQLworksheetExport/UsingtheSQLworksheet
functionsabout/Functionsfeatures/Functionsexecutionmethods/Functions–executionmethodscallingfromSQLexpressions,restrictions/RestrictionsoncallingfunctionsfromSQLexpressions
Iicons,SQLworksheet
RunStatement/UsingtheSQLworksheetidentifiertypes
determining/DeterminingidentifiertypesandusagesUSER_IDENTIFIERSview/USER_IDENTIFIERSPL/Scopetool/ThePL/ScopetoolPLSCOPE_SETTINGSparameter/ThePLSCOPE_SETTINGSparameter
implicitcursors/Cursors–anoverviewabout/Cursorstructures,Implicitcursors
implicitdatatypeconversionavoiding/Avoidinganimplicitdatatypeconversion
In-DatabaseArchiving/In-DatabaseArchivingIn-MemoryDatabaseCache(IMDB)
versusResultCache/ResultCacheversusIn-MemoryDatabaseCacheindex-organizedtable(IOT)/Nestedtableinanindex-organizedtableinjection/WhatisSQLinjection?interpretedcompilation
programunit,comparing/Compilingaprogramunitfornativeorinterpretedcompilation
IPC(InternetProcedureCalls)/TNSNAMES.ora
JJavaDevelopmentKit(JDK)/GettingstartedwithSQLDeveloperJavaprograms,executingfromPL/SQL
about/ExecutingJavaprogramsfromPL/SQLJavaclass,loadingintodatabase/LoadingaJavaclassintoadatabaseJavaclass,executingfromOraclePL/SQLunit/StepstoexecuteaJavaclassfromanOraclePL/SQLunit
JavaRuntimeEnvironment(JRE)/SQLcl–ThenewSQLcommandline
K32KVARCHAR2/Supportfor32KVARCHAR2keyfeaturesandcommands,SQLcl
databaseconnection/SQLcl–ThenewSQLcommandlineObject-name/Commandcompletion/SQLcl–ThenewSQLcommandlinemultilineedits/SQLcl–ThenewSQLcommandlineCD/SQLcl–ThenewSQLcommandlineCTAS/SQLcl–ThenewSQLcommandlineDDL/SQLcl–ThenewSQLcommandlineSQLFORMAT/SQLcl–ThenewSQLcommandlineSQLhistory/SQLcl–ThenewSQLcommandlineINFORMATION/SQLcl–ThenewSQLcommandline
LLASTfunction/FIRSTandLASTlibraryobject,externalprocedures/TheLibraryobjectLibunits/ExecutingJavaprogramsfromPL/SQLLIMITfunction/LIMITLOBs
about/IntroductiontoLargeObjectssecurity/IntroductiontoLargeObjectsdatatypes,classifying/ClassificationofLargeObjectdatatypesinternalLOB/InternalLOBtemporaryLOB/PersistentandTemporaryLOBpermanentLOB/PersistentandTemporaryLOBexternalLOB/ExternalLOBrestrictions/LOBrestrictionslocator/TheLOBlocatorinstanceinitialization/LOBinstanceinitializationDBMS_LOBpackage/TheDBMS_LOBpackageusagenotes/LOBusagenotesworkingwith/WorkingwithLOBsmetadata/LOBmetadataSecureFileadvancedfeatures,securing/EnablingtheadvancedfeaturesofaSecureFiledata,populating/PopulatingtheLOBdatatemporaryLOBoperations/TemporaryLOBoperations,ManagingtemporaryLOBsLONG,migratingto/MigratingLONGtoLOBs
LOBs,datatypesabout/LOBdatatypesinOracleBinaryLargeObject(BLOB)/BLOBandCLOBCharacterLargeObject(CLOB)/BLOBandCLOBNCLOB/BLOBandCLOBBFILE/BFILE
localuser/CommonusersandlocalusersLONG,migratingtoLOBs
ALTERTABLEcommand,using/UsetheALTERTABLEcommandTO_LOBfunction,using/UsingtheTO_LOBfunctionOnlineTableRedefinition/OnlineTableRedefinition
LRU(LeastRecentlyUsed)/WhatistheServerResultCache?
Nnativecompilation
about/Nativeandinterpretedcompilationtechniquesprogramunit,comparing/Compilingaprogramunitfornativeorinterpretedcompilation
nestedtableabout/Collectiontypes,Nestedtablesobjecttype,modifying/Modifyanddropanestedtableobjecttypeobjecttype,dropping/Modifyanddropanestedtableobjecttypedesignconsiderations/Designconsiderationsofanestedtablestorage/Nestedtablestorageinindexorganizedtable/Nestedtableinanindex-organizedtablelocators/Nestedtablelocatorsasschemaobject/Nestedtableastheschemaobjecttypecolumn,operations/Operationsonanestedtabletypecolumninstance,creating/Createanestedtableinstancecolumn,querying/Queryinganestedtablecolumncollectiontype,inPL/SQL/NestedtablecollectiontypeinPL/SQLcollection,initialization/Collectioninitializationmetadata,querying/Queryingthenestedtablemetadata
NEXTfunction/PRIORandNEXTNOTNULLconstraint
about/UnderstandingtheNOTNULLconstraint
OObjectBrowser
about/ObjectBrowserOCI(OracleCallInterface)/OCIClientresultscacheOCIClientresultscache
about/OCIClientresultscacheparameters/OCIClientresultscache
Oracle-suppliedpackagesreviewing/ReviewingOracle-suppliedpackagesDBMS_ALERT/ReviewingOracle-suppliedpackagesDBMS_LOCK/ReviewingOracle-suppliedpackagesDBMS_SESSION/ReviewingOracle-suppliedpackagesDBMS_OUTPUT/ReviewingOracle-suppliedpackagesDBMS_HTTP/ReviewingOracle-suppliedpackagesUTL_FILE/ReviewingOracle-suppliedpackagesUTL_MAIL/ReviewingOracle-suppliedpackagesDBMS_SCHEDULER/ReviewingOracle-suppliedpackagesDBMS_PARALLEL_EXECUTE/ReviewingOracle-suppliedpackagesDBMS_PRIVILEGE_CAPTURE/ReviewingOracle-suppliedpackagesDBMS_REDACT/ReviewingOracle-suppliedpackagesDBMS_RESOURCE_MANAGER/ReviewingOracle-suppliedpackagesDBMS_DATAPUMP/ReviewingOracle-suppliedpackagesDBMS_PDB/ReviewingOracle-suppliedpackagesDBMS_SQL/ReviewingOracle-suppliedpackagesDBMS_REDEFINITON/ReviewingOracle-suppliedpackagesDBMS_UTILITY/ReviewingOracle-suppliedpackagescategorizing/ReviewingOracle-suppliedpackages
Oracle11g/MultitenantforConsolidationOracle12ccontainerdatabase(CDB)
about/DatabaseconsolidationandthenewMultitenantarchitectureOracle12cSQLandPL/SQL,features
about/Oracle12cSQLandPL/SQLnewfeaturesIDENTITYcolumns/IDENTITYcolumnscolumnvalue,tosequenceinOracle12c/DefaultcolumnvaluetoasequenceinOracle12cDEFAULTONNULLclause/TheDEFAULTONNULLclause32KVARCHAR2,supportfor/Supportfor32KVARCHAR2Rowlimiting,FETCHFIRSTused/RowlimitingusingFETCHFIRSTinvisiblecolumns/Invisiblecolumnstemporaldatabases/TemporaldatabasesIn-DatabaseArchiving/In-DatabaseArchiving
OracleAdvancedSecurity/OracleDatabaseSecurityoverviewOracleAuditVaultandDatabaseFirewall(AVDF)
about/OracleDatabaseSecurityoverviewOracledatabase11gRealnativecompilation
about/OracleDatabase11gRealNativeCompilationOracleDatabase11gresultcache
about/OracleDatabase11gResultCacheServerResultCache/WhatistheServerResultCache?ServerResultCache,configuring/ConfiguringtheServerResultCacheResultCache,versusBufferCache/ResultCacheversusBufferCacheResultCache,versusDatabaseIn-Memory/ResultCacheversusOracle12cDatabaseIn-MemoryResultCache,versusIn-MemoryDatabaseCache(IMDB)/ResultCacheversusIn-MemoryDatabaseCache
OracleDatabase12cimplicitstatementresults/ImplicitstatementresultsinOracleDatabase12cenhancements,tocollections/Oracle12cenhancementstocollections
Oracledatabase12cexternalprocedures,securingwith/SecuringExternalProcedureswithOracleDatabase12c
OracleDatabase12c(12.1.0.2),In-Memoryoptionabout/TheOracleDatabase12c(12.1.0.2)In-Memoryoptionchallenge/Thechallengeandproblemstatement/TheproblemstatementandOracleDatabase12cIn-Memoryfeatures/OracleDatabase12cIn-Memoryoptionfeaturesarchitecture/TheOracleDatabase12cIn-MemoryArchitecturestore,controlling/ControllingtheIn-MemorycolumnstoreINMEMORYclause/TheINMEMORYclauseperformanceoptimizations/PerformanceoptimizationsIn-MemoryAdvisor/In-MemoryAdvisorOracleDatabaseIn-Memorybenefits/OracleDatabaseIn-Memorybenefits
Oracledatabase12cDataRedactionabout/OracleDatabase12cDataRedactionfeatures/DataRedactionexemptionsandmiscellaneousfeaturesfunctiontypes/DataRedactionfunctiontypesdemonstration/Demonstrationmetadata/TheDataRedactionmetadata
OracleDatabase12cenhancementstoPL/SQLsubprograms/OracleDatabase12cenhancementstoPL/SQLsubprograms
OracleDatabase12cmultitenantarchitecture,featuresabout/TheOracleDatabase12cMultitenantarchitecture–featuresmultitenantforconsolidation/MultitenantforConsolidationplug/unplug/Plug/unplugmanagemanyasone/ManageManyasOne
rapidprovisioning/RapidprovisioningCDBresourcemanagement/CDBResourceManagementcommonusers/Commonusersandlocalusers
Oracledatabase12csecurity,enhancementsabout/OracleDatabase12cSecurityenhancements,OracleDatabase12cDataRedaction
OracleDatabaseOnlineDocumentation12cRelease1(12.1)/DatabaseAdministration
URL/TheDBMS_LOBpackageOracledatabasesecurity
about/OracleDatabaseSecurityoverviewOracledatabaseVault
about/OracleDatabaseSecurityoverviewOracleKeyVault(OKV)
about/OracleDatabaseSecurityoverviewOracleSecureFiles
deduplication/Deduplicationandcompressioncompression/Deduplicationandcompressionfilesystemlogging/FileSystemLoggingWriteGatherCache(WGC)/WriteGatherCachefreespacemanagement/FreespacemanagementandBasicFiles/BasicFilesandSecureFilesdb_securefileparameter/Thedb_securefileparameter
OracleSQLDeveloperabout/OracleSQLDeveloperforDBA/OracleSQLDeveloperforDBA,Developers,andApplicationArchitectsfordevelopers/OracleSQLDeveloperforDBA,Developers,andApplicationArchitectsforapplicationarchitects/OracleSQLDeveloperforDBA,Developers,andApplicationArchitectsSQLDeveloper4.0/SQLDeveloper4.0
OracleSQLDeveloperExchangeprogramURL/Keydifferentiators
PPaymentCardIndustryDataSecurityStandard(PCI-DSS)/OracleDatabaseSecurityoverviewpersistentLOB/PersistentandTemporaryLOBPGA(ProcessGlobalArea)/DifferencesbetweenResultCacheandothercachingtechniquesPL/Scopetool
about/ThePL/ScopetoolPLSCOPE_SETTINGSparameter/ThePLSCOPE_SETTINGSparameter
PL/SQLabout/IntroductiontoPL/SQLadvantages/IntroductiontoPL/SQLaccomplishments/IntroductiontoPL/SQLprogram,fundamentals/PL/SQLprogramfundamentalsblock/PL/SQLprogramfundamentalsexceptionhandling/ExceptionhandlinginPL/SQLenhancements/MiscellaneousPL/SQLenhancementscollectionmethods/PL/SQLcollectionmethodsexternalCprograms,executing/ExecutingexternalCprogramsfromPL/SQLJavaprograms,executing/ExecutingJavaprogramsfromPL/SQLbulkprocessing/BulkprocessinginPL/SQL
PL/SQLblockanonymousPL/SQLblock/PL/SQLprogramfundamentalsnamed/PL/SQLprogramfundamentalsnested/PL/SQLprogramfundamentals
PL/SQLcodetuning/TuningPL/SQLcodesecureapplicationsbuilding,bindvariablesused/Buildsecureapplicationsusingbindvariablesparameters,callingbyreference/Callparametersbyreferenceimplicitdatatypeconversion,avoiding/AvoidinganimplicitdatatypeconversionNOTNULLconstraint/UnderstandingtheNOTNULLconstraintnumericdatatype,selecting/Selectionofanappropriatenumericdatatype
PL/SQLcode,designingcursorstructures/Cursorstructurescursorvariables/Cursorvariablessubtypes/Subtypes
PL/SQLcode,profilingabout/ProfilingPL/SQLcodeDBMS_HPROFpackage/TheDBMS_HPROFpackagerawprofiledata,collecting/Collectingrawprofiledataprofilerdata,analyzing/Analyzingprofilerdata
plshprofutility/TheplshprofutilityPL/SQLcodinginformation,tracking
about/TrackingPL/SQLcodinginformationUSER_ARGUMENTSview/USER_ARGUMENTSUSER_OBJECTSview/USER_OBJECTSUSER_OBJECT_SIZEview/USER_OBJECT_SIZEUSER_SOURCEview/USER_SOURCEUSER_PROCEDURESview/USER_PROCEDURESUSER_PLSQL_OBJECT_SETTINGSview/USER_PLSQL_OBJECT_SETTINGSandUSER_STORED_SETTINGSUSER_STORED_SETTINGSview/USER_PLSQL_OBJECT_SETTINGSandUSER_STORED_SETTINGSUSER_DEPENDENCIESview/USER_DEPENDENCIESDBMS_DESCRIBEpackage/TheDBMS_DESCRIBEpackageprogramexecutionsubprogramcallstack,tracking/TrackingtheprogramexecutionsubprogramcallstackpropagatingexceptionsinPL/SQLcode,tracking/TrackingpropagatingexceptionsinPL/SQLcode
PL/SQLcompilerabout/ThePL/SQLCompilersubprograminlining/SubprograminlininginPL/SQL
PL/SQLEditorandDebuggerabout/PL/SQLEditorandDebugger
PL/SQLfunctionresultcacheabout/PL/SQLFunctionResultCache,Doesitsoundsimilartodeterministicfunctions?andothercachingtechniques,differences/DifferencesbetweenResultCacheandothercachingtechniquesillustration/Illustrationmonitoring/MonitoringthePL/SQLResultCacheinvalidation/InvalidationofthePL/SQLResultCachelimitations/Limitation
PL/SQLinterpretedcompilationdatabase,recompiling/RecompilingadatabaseforaPL/SQLnativeorinterpretedcompilation
PL/SQLnativecompilationdatabase,recompiling/RecompilingadatabaseforaPL/SQLnativeorinterpretedcompilation
PL/SQLpackageabout/APL/SQLpackage
PL/SQLprogramunitwhitelisting/ThePL/SQLprogramunitwhitelisting
PL/SQLprogramssample/AsamplePL/SQLprogram
tracing,DBMS_TRACEused/TracingPL/SQLprogramsusingDBMS_TRACEDBMS_TRACEpackage,installing/InstallingtheDBMS_TRACEpackageDBMS_TRACEsubprograms/DBMS_TRACEsubprogramscompiling,fordebugging/CompilingaPL/SQLprogramfordebuggingPL/SQLtraceinformation,viewing/ViewingthePL/SQLtraceinformationexecution,tracing/StepstotracePL/SQLprogramexecutionprofiling/ProfilingPL/SQLcode
PL/SQLprogramunitsroles,granting/GrantingrolestoPL/SQLprogramunitstestsetup/Testsetup
PL/SQLsubprogramdefining,inSELECTquery/DefiningaPL/SQLsubprogramintheSELECTqueryandPRAGMAUDFdefining,inPRAGMAUDF/DefiningaPL/SQLsubprogramintheSELECTqueryandPRAGMAUDFtestsetup/Testsetupcomparativeanalysis/Comparativeanalysis
PL/SQLvirtualmachine(PVM)/Nativeandinterpretedcompilationtechniquesplshprofutility
about/Theplshprofutilityreports,exploring/Whatdothesereportsreveal?
PLSQL_OPTIMIZE_LEVELabout/PLSQL_OPTIMIZE_LEVELcases/Case1:WhenPLSQL_OPTIMIZE_LEVEL=0,Case2:WhenPLSQL_OPTIMIZE_LEVEL=1,Case3:WhenPLSQL_OPTIMIZE_LEVEL=2,Case4:WhenPLSQL_OPTIMIZE_LEVEL=3
pluggabledatabase(PDB)about/DatabaseconsolidationandthenewMultitenantarchitecture
/Rapidprovisioningpluggabledatabases
about/DatabaseconsolidationandthenewMultitenantarchitecturePRAGMAINLINE
about/PRAGMAINLINEPRIORfunction/PRIORandNEXTprofilerdata
analyzing/Analyzingprofilerdataprofilertables,creating/Creatingtheprofilertablesprofileroutput,analyzing/Analyzingtheprofileroutputprofilertables,querying/Queryingtheprofilertables
RRAC(RealApplicationClusters)
features/ResultcacheinRealApplicationClustersRAISE_APPLICATION_ERRORprocedure/TheRAISE_APPLICATION_ERRORprocedurerawprofiledata
collecting/Collectingrawprofiledatainterpreting/Interpretingtherawprofilerdata
RealApplicationCluster(RAC)/NativeandinterpretedcompilationtechniquesRealApplicationClusters(RAC)
resultcache/ResultcacheinRealApplicationClustersRealApplicationSecurity(RAS)
about/OracleDatabaseSecurityoverviewredologs/DatabaseconsolidationandthenewMultitenantarchitectureRemote-Ops(RO)/TNSNAMES.oraResultCache
SQLqueryresultcache/OracleDatabase11gResultCachePL/SQLfunctionresultcache/OracleDatabase11gResultCacheOCIresultcache/OracleDatabase11gResultCacheversusBufferCache/ResultCacheversusBufferCacheversusDatabaseIn-Memory/ResultCacheversusOracle12cDatabaseIn-MemoryversusIn-MemoryDatabaseCache(IMDB)/ResultCacheversusIn-MemoryDatabaseCache
SSCN(systemchangenumber)/ReadconsistencyoftheSQLResultCacheSDDM(SQLDeveloperDataModeler)/SQLDeveloperforDatabaseAdministratorsSDK(softwaredevelopmentkit)/AnoverviewofSQLDeveloperServerResultCache
about/OracleDatabase11gResultCache,WhatistheServerResultCache?configuring/ConfiguringtheServerResultCache
SharedGlobalArea(SGA)about/DatabaseconsolidationandthenewMultitenantarchitecture
SingleInstructionMultipleData(SIMD)/PerformanceoptimizationsSQLcl
about/SQLcl–ThenewSQLcommandlineURL,forYouTubevideo/SQLcl–ThenewSQLcommandlinecommands/SQLcl–ThenewSQLcommandlinekeyfeatures/SQLcl–ThenewSQLcommandline
SQLDeveloperoverview/AnoverviewofSQLDeveloperhistory/Historyandbackgroundbackground/Historyandbackgroundreleases/Historyandbackgroundfordevelopers/SQLDeveloperforDevelopersfordatabaseadministrators/SQLDeveloperforDatabaseAdministratorsworkingwith/GettingstartedwithSQLDeveloperdatabaseconnection,creating/Creatingadatabaseconnectionfeatures/CorefeaturesofSQLDeveloper
SQLDeveloper4.1enhancements/SQLDeveloper4.0and4.1NewFeatures
SQLDeveloperDataModeler(SDDM)/OracleSQLDeveloperforDBA,Developers,andApplicationArchitectsSQLDeveloperExtensionsExchange
URL/AnoverviewofSQLDeveloperSQLDeveloperreports
about/SQLDeveloperreportsSQLDevelopertool
keyfactors,fordifferentiatingfromothertools/KeydifferentiatorsSQLinjection
about/WhatisSQLinjection?targets/SQLinjectiontargetsPL/SQLcode,exploiting/HowtoexploitthePL/SQLcode?
SQLinjection,attackspreventing/PreventingSQLinjectionattacksinputssanitizing,DBMS_ASSERTused/Sanitizinginputsusing
DBMS_ASSERTrightsubprogram,selectingforrightidentifier/ChoosetherightsubprogramfortherightidentifierDBMS_ASSERT,limitatiions/DBMS_ASSERT–limitationspreventing,bindvariablesused/Useofbindvariablestopreventinjectionattackspreventing,bestpractices/BestpracticestoavoidSQLinjection
SQLinjection,codetestingstrategy/Teststrategyreview/Aneffectivecodereviewstaticcodeanalysis/Staticcodeanalysisfuzztools/Fuzztoolstestcases,generating/Generatingtestcases
SQLqueryresultcacheabout/SQLqueryResultCachemonitoring/MonitoringtheSQLResultCacheinvalidation/InvalidationoftheSQLResultCachereadconsistency/ReadconsistencyoftheSQLResultCachelimitations/Limitations
SQLTranslationFrameworkabout/TheSQLTranslationFramework
SQLworksheetusing/UsingtheSQLworksheeticons/UsingtheSQLworksheetfunctionalities/UsingtheSQLworksheet
storedprocedurescreating/Creatingstoredproceduresexecuting/Executingaprocedure
subprograminliningPRAGMAINLINE/PRAGMAINLINEPLSQL_OPTIMIZE_LEVEL/PLSQL_OPTIMIZE_LEVEL
subtypeabout/Subtypesclassifying/Subtypeclassificationtypecompatibility/Typecompatibilitywithsubtypes
SYSAUXtablespace/DatabaseconsolidationandthenewMultitenantarchitecturesystem-definedexceptions
about/System-definedexceptionssystemglobalarea(SGA)/CursorstructuresSYSTEMtablespace/DatabaseconsolidationandthenewMultitenantarchitecture
TtemporaryLOB/PersistentandTemporaryLOBTEMPtablespace/DatabaseconsolidationandthenewMultitenantarchitectureTotalRecallfeature/TemporaldatabasesTransparentDataEncryption(TDE)/OracleDatabaseSecurityoverview,EncryptionTRIMfunction/TRIM
UUNDOtablespace/DatabaseconsolidationandthenewMultitenantarchitectureuser-definedexceptions
RAISE_APPLICATION_ERRORprocedure/TheRAISE_APPLICATION_ERRORprocedure
userglobalarea(UGA)/CursorstructuresUserGlobalArea(UGA)/Cursors–anoverview,ApplicationContext
Vvarray
about/Collectiontypes,Varrayasschemaobject/VarrayasaschemaobjectinPL/SQL/VarrayinPL/SQL
varraytypecolumns,operationsabout/Operationsonvarraytypecolumnsvarraycollectiontypeinstance,inserting/Insertingvarraycollectiontypeinstancevarraycolumn,querying/Queryingvarraycolumnvarrayinstance,updating/Updatingthevarrayinstance
versioncontrol,SQLDeveloperabout/Versioncontrol
VirtualPrivateDatabase(VPD)about/OracleDatabaseSecurityoverview,VirtualPrivateDatabaseworking/HowdoesVirtualPrivateDatabasework?column-level/Column-levelVirtualPrivateDatabasewithOracledatabase12cmultitenant/VirtualPrivateDatabasewithOracleDatabase12cMultitenantcomponents/VirtualPrivateDatabasecomponentsdemonstration/Demonstrationfeatures/VirtualPrivateDatabasefeaturesandbestpracticesbestpractices/VirtualPrivateDatabasefeaturesandbestpracticesmetadata/VirtualPrivateDatabasemetadatapolicyutilityactivities/Policyutilities—refreshanddrop
VirtualPrivateDatabase(VPD),componentsapplicationcontext/ApplicationContextpolicyfunction/VirtualPrivateDatabasepolicyfunctionpolicytype/PolicytypesDBMS_RLSpackage/TheDBMS_RLSpackage