Advanced Oracle PL/SQL Developer’s -...

609

Transcript of Advanced Oracle PL/SQL Developer’s -...

AdvancedOraclePL/SQLDeveloper’sGuideSecondEdition

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’sGuideSecondEdition

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

CoverWork

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.

www.PacktPub.com

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;

/*Returnthecalculatedvalue*/

RETURNL_NUM;

END;

/

Functioncreated.

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.

-------------------------------------------------

PL/SQLproceduresuccessfullycompleted.

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

UsetheDROPcommandtodropavarraytypefromthedatabase:DROPTYPE[varraytypename][FORCE]

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$

DWH_DATAONLINESYSTEM

FIN_DATAONLINESYSTEM

22rowsselected.

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

7654MARTINSALESMAN30

7521WARDSALESMAN30

7499ALLENSALESMAN30

14rowsselected.

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

--------------------------------------------------------

[email protected]

[email protected]

[email protected]

[email protected]

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

execution.

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

APEX_040200WWV_FLOW_ESCAPE

5rowsselected.

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

toptobottom,youcanloopthedynamicdepthinREVERSEorder.

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:

TheimpactofSQLinjection

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?

Mmachinecode(M-code)

about/ThePL/SQLCompiler

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

WWriteGatherCache(WGC)/WriteGatherCache