Académique Documents
Professionnel Documents
Culture Documents
WelcomeBOUBA
2016
OracleMagazineOnline
2015
2016 2014
TECHNOLOGY:AskTom AsPublishedIn
2015
2014
2013 OnOracleDatabase12c,Part1
2012
ByTomKyte
2011
September/October2013
Ourtechnologistimprovesdefaultvalues,handlesbiggerdatatypes,andFETCHesforthefirsttime.
2010
2009 UsuallyItakethreeorfourusersubmittedquestionsfromthepasttwomonthsandpresentthosequestionsandanswershereineachAskTom
column.Inthenextfourcolumns,however,IwilltakealookatsomekeyOracleDatabase12cfeatures.Thesefeaturesareallpartofthe12
ThingsAboutOracleDatabase12cpresentationIgaveatOracleOpenWorld2012inSanFrancisco.(Youcanfindtheslidesforthatpresentation
onasktom.oracle.comontheFilestab).ThefirstthreeOracleDatabase12cfeaturesIlltakealookatare
Improveddefaults
Biggerdatatypes
Topnqueries
ImprovedDefaults
TheabilitytocreateadefaultcolumnvaluehasexistedinSQLforawhile.Thefunctionalityhasbeensomewhatlimited,however,withvarious
restrictions.Forexample,youwererestrictedfromusingaSEQUENCEobjecttosupplyadefaultvalue.Additionally,ifadefaultvaluewastobe
insertedintoorupdatedinatable,youhadtoeitherusetheDEFAULTkeywordintheSQLstatementorleavethecolumnoutoftheINSERT
statemententirely.Furthermore,addinganewcolumnthatpermitsNULLvalueswithadefaultvaluewasanofflineoperation.InOracleDatabase
12c,however,theserestrictionsandfunctionalitylimitationshavebeenremoved.
RemovedRestriction:GeneratingaDefaultValuefromaSEQUENCE.InOracleDatabase12c,youcannowusethe.NEXTVALattributeofa
sequencetocreateadefaultcolumnvalue.Forexample,thiscode
SQL>createsequences;
Sequencecreated.
SQL>createtablet
2(xint
3defaults.nextval
4primarykey,
5yvarchar2(30)
6);
Tablecreated.
SQL>insertintot(x,y)
2values(default,'hello');
1rowcreated.
SQL>insertintot(y)
2values('world');
1rowcreated.
SQL>select*fromt;
XY
1hello
2world
demonstratesthatyoucancreateadefaultcolumnvaluefortheprimarykeyfromthesequencevaluewithoutusingatrigger,asyouwouldhave
inthepast.SoinOracleDatabase12c,DEFAULTS.NEXTVALintheCREATETABLEstatementwillreplacethefollowingproceduralcode:
SQL>createtriggert
2beforeinsertont
3foreachrow
4begin
5if(:new.xisnull)
6then
7:new.x:=s.nextval;
8endif;
9end;
10/
Triggercreated.
Inadditiontousingareferencetoasequencetocreateadefaultcolumnvalue,youcanalternativelyuseanIDENTITYtype,whichwillgeneratea
sequenceandassociatethatsequencewiththetable.Forexample,thisCREATETABLEstatement
SQL>createtablet
2(xint
3generatedasidentity
4primarykey,
5yvarchar2(30)
6)
7/
Tablecreated.
willresultinthesamedatasbeingloadedintotableTwithoutyourhavingtoexplicitlycreateasequence(asyoudidintheCREATETABLE
statementthatexplicitlycalledDEFAULTS.NEXTVAL).Youcanseethissequenceifyoulookattheschema:
SQL>selectobject_name,object_type
2fromuser_objects
3/
http://www.oracle.com/technetwork/issuearchive/2013/13sep/o53asktom1999186.html 1/5
14/3/2016 AskTom:OnOracleDatabase12c,Part1
OBJECT_NAMEOBJECT_TYPE
TTABLE
ISEQ$$_90241SEQUENCE
SYS_C0010233INDEX
Butnotethatifyoudropthetableandpurgeitfromtherecyclebin,thesequencewillberemovedaswell:
SQL>droptabletpurge;
Tabledropped.
SQL>selectobject_name,object_type
2fromuser_objects
3/
norowsselected
Becauseidentityisusingasequenceunderthecovers,youcanalsocontrolallthesettingsoftheunderlyingsequence.Forexample,this
CREATETABLEstatement
SQL>createtablet
2(xint
3generatedbydefault
4asidentity
5(startwith42
6incrementby1000)
7primarykey,
8yvarchar2(30)
9)
10/
Tablecreated.
showsthatyoucancontroltheSTARTWITHandINCREMENTBYvalues.Additionally,byusingtheGENERATEDBYDEFAULTstatementinstead
ofjustGENERATED,youcanoverridethedefaultidentityvalue.HereIdemonstratethisbyinsertingthevalue1andthentwomorerows,enabling
identitytogeneratethedefaultvalues:
SQL>insertintot(x,y)
2values(1,'override');
1rowcreated.
SQL>insertintot(x,y)
2values(default,'hello');
1rowcreated.
SQL>insertintot(y)
2values('world');
1rowcreated.
SQL>select*fromt;
XY
1override
42hello
1042world
ImprovedFunctionality:CreateaDefaultValueforaNULLColumn.InOracleDatabase12c,youcannowcreateadefaultcolumnvaluenot
onlywhenyouusetheDEFAULTkeywordorleavethecolumnentirelyoutoftheINSERTstatementbutalsowhenyousetthecolumnvalue
explicitlytoNULL.
Inthepast,ifacolumnusedadefaultvalue,youeitherhadtousetheDEFAULTkeywordintheINSERT/UPDATEstatementorleavethecolumn
entirelyoutoftheINSERT/UPDATEstatement.Thatmeantthatinordertouseadefaultvalueatcertaintimesandnotothers,youneededatleast
twoINSERT/UPDATEstatementswithcomplicatedif/then/elseconstructs.Forexample,ifcolumnXhadadefaultvalueandyousometimeswanted
toinsertanoverridingvalueandsometimesnot,youwouldneedcoderesemblingthefollowing:
if(xis_to_be_defaulted)
then
insertintot(x,)
values(DEFAULT,);
else
insertintot(x,)
values(:x,);
endif;
Now,thatmightbeOKifyousometimeshadtocreateadefaultvalueforonecolumn,butwhatifyouhavetwoorthreeormorecolumns?Thinkof
howmanycombinationsofINSERTsorUPDATEsyouwouldneedwithcomplexif/then/elseblockstosupportthat.InOracleDatabase12c,you
cannowcreateadefaultcolumnvaluewhenyouexplicitlyputaNULLvalueintothatcolumn.Heresanexample:
SQL>createtablet
2(xnumber
3generatedasidentity
4primarykey,
5yvarchar2(30),
6znumberdefaultONNULL42
7)
8/
Tablecreated.
ByusingznumberdefaultONNULL42,IvespecifiedthatcolumnZwillreceivethedefaultvaluenotonlywhenIexplicitlysetittoDEFAULT
orleaveitoutoftheINSERTstatementbutalsowhenIexplicitlyinsertNULLintoit,asin
SQL>insertintot(y)
2values('justy');
1rowcreated.
SQL>insertintot(y,z)
2values('ywithzsettonull',
null);
1rowcreated.
SQL>insertintot(y,z)
2values('yandz',100);
1rowcreated.
http://www.oracle.com/technetwork/issuearchive/2013/13sep/o53asktom1999186.html 2/5
14/3/2016 AskTom:OnOracleDatabase12c,Part1
SQL>select*fromt;
XYZ
1justy42
2ywithzsettonull42
3yandz100
Asyoucansee,theZcolumnvalueiscreatedwiththedefaultvalue42inbothcasesnow.Also,thedeclarationforZhadtheeffectofdefiningitas
NOTNULL,eventhoughIdidnotexplicitlystatethat:
SQL>selectcolumn_name,nullable
2fromuser_tab_columns
3wheretable_name='T'
4orderbycolumn_id
5/
COLUMN_NAMEN
XN
YY
ZN
MoreOnlineOperations:BetterColumnAddition.InOracleDatabase11gyouwereabletoperformafastaddofacolumntoatableifithada
defaultvalueandwasdefinedasNOTNULL.(ArupNandahaswrittenaboutthisatbit.ly/16tQNCh.)However,ifyouattemptedtoaddacolumn
withadefaultvalueandthatcolumnpermittednullvalues,theADDCOLUMNoperationcouldtakeasignificantamountoftime,generatealarge
amountofundoandredo,andlocktheentiretableforthedurationoftheoperation.InOracleDatabase12c,thattime,volume,andlockingareno
longerpartoftheprocess.
Todemonstratethis,IcopyALL_OBJECTSintoatableandmeasureitsspaceinblocksandbytesusingtheshow_spaceutility,postedon
asktom.oracle.com:
SQL>createtablet
2as
3select*
4fromall_objects;
Tablecreated.
SQL>execshow_space('T')
FullBlocks....1,437
TotalBlocks...........1,536
TotalBytes............12,582,912
TotalMBytes...........12
PL/SQLproceduresuccessfullycompleted.
NowIaddacolumntotableT,andthiscolumnwillhavealargedefaultvalue.BecausethecolumnImaddingisaCHAR(2000),itwillalways
consumethefull2,000bytes,giventhattheCHARtypeisalwaysblankpaddedandfixedwidth.TableThasmorethan87,000records,soadding
acolumnwouldtypicallytakeasignificantamountoftime,butasyoucansee,theadditionispracticallyinstantaneousinOracleDatabase12c:
SQL>settimingon
SQL>altertablet
add(datachar(2000)default'x');
Tablealtered.
Elapsed:00:00:00.07
IperformtheidenticaloperationinOracleDatabase11gandobservethefollowingtiming:
SQL>settimingon
SQL>altertablet
add(datachar(2000)default'x');
Tablealtered.
Elapsed:00:00:28.59
Clearly,thatsasignificantdifferenceinruntimes.Plus,whenIlookatthesizeofthetablewiththeadditionalcolumninOracleDatabase12c
SQL>execshow_space('T')
FullBlocks....1,437
TotalBlocks...........1,536
TotalBytes............12,582,912
TotalMBytes...........12
PL/SQLproceduresuccessfullycompleted.
Iseethatthetabledidnotgrowatall.However,runningthesametestinOracleDatabase
11gshowsthatthetablewillgrowfromabout9MBto192MB.Additionally,inOracle
Database11g,almosteveryrowinthetablewasamigratedrow,becausetherowgrewby NextSteps
ordersofmagnitude.Thattableprobablywouldbedueforareorganizationintheprior
releasesbutnotinOracleDatabase12c. ASKTom
TomKyteanswersyourmostdifficulttechnology
BiggerDatatypes questions.Highlightsfromthatforumappearinthis
column.
Oracle8DatabaseprovidedabigincreaseinthesizeofVARCHARtypesfrom255bytes
(inOracle7)to4,000bytes.NowtheOracleDatabase12creleaseincreasesthesizefrom FOLLOWTomonTwitter
4,000bytesto32K,bringingtheSQLVARCHAR2,NVARCHAR2,andRAWdatatypesin
linewiththeirPL/SQLcounterparts. READmoreTom
DOWNLOADOracleDatabase12c
Bydefault,thisnewcapabilityisnotenabledandwouldhavetobeenabledbytheDBAs
settingthenewMAX_STRING_SIZEinit.oraparametertoEXTENDED.Oncethatsdone, FOLLOWOracleDatabase
youllbeabletoissuestatementssuchas onTwitter
SQL>createtablet(xvarchar(32767)); onFacebook
Tablecreated.
andthenusestringfunctionssuchasRPAD,LPAD,andTRIM:
SQL>insertinto
tvalues(rpad('*',32000,'*'));
1rowcreated.
http://www.oracle.com/technetwork/issuearchive/2013/13sep/o53asktom1999186.html 3/5
14/3/2016 AskTom:OnOracleDatabase12c,Part1
SQL>selectlength(x)fromt;
LENGTH(X)
32000
Inthepast,RPADandotherstringbuiltinfunctionswouldhavebeenabletoreturnonly4,000bytes,butnowtheycanreturnupto32Kfora
VARCHAR2returntype.
Underthecovers,OracleDatabase12cisusingalargeobject(LOB)tostoretheselargerstringsandrawtypes.Iftheinsertedstringisupto4,000
bytes,thedatabasewillstorethedatainthetabledatabaseblockjustasitdoeswithalegacyVARCHAR2typeifthestringexceeds4,000bytes,
however,thedatabasewilltransparentlystoreitoutoflineinaLOBsegmentandindex.
TopNQueriesandPagination
OutofthemanythousandsofquestionsonAskTom(asktom.oracle.com),acoupleofthemostpopularare,HowdoIgetrowsNthroughMofa
resultset(howtopaginatethrougharesultset)andHowdoIgetthefirstNrecordsofaresultset.Infact,Ivewrittenmorethanonearticlein
OracleMagazineovertheyearstoaddressthesequestions(OnTopnandPaginationQueriesandOnROWNUMandLimitingResults).These
articlesdemonstratedhowtoaccomplishthesefeats,butthemethodsdemonstratedarecumbersome,nonintuitive,andnotnecessarilyportable.
OracleDatabase12cincludessupportfortheANSIstandardFETCHFIRST/NEXTandOFFSETclausestogethercalledtherowlimitingclause.
ThisclauseenablesyoutoeasilyretrievethefirstNrecordsfromaresultsetor,alternatively,thefirstNrecordsafterskippingoverasetofrecords,
soyoucaneasilypaginatethrougharesultset.ThediagraminFigure1showsthesyntaxfortherowlimitingclause.
Figure1:Rowlimitingclausesyntax
TherowlimitingclauseissimplyaddedtotheendofanySQLSELECTstatementtofetchaspecificsetofrecordsthereisnoneedformultiple
layersofinlineviewsandWHEREclausesthathavetobecarefullypositioned,astherewaswithROWNUMandROW_NUMBER().
Forexample,ifIhaveatableT
SQL>createtablet
2as
3select*fromall_objects;
Tablecreated.
SQL>createindext_idx
ont(owner,object_name);
Indexcreated.
andIwanttoretrievethefirstfiverowsaftersortingbyOWNERandOBJECT_NAME,IonlyneedtoaddaFETCHFIRSTNROWStotheSQL
query,asshowninListing1.
CodeListing1:SimpleSELECTquerywithFETCHFIRST
SQL>selectowner,object_name,object_id
2fromt
3orderbyowner,object_name
4FETCHFIRST5ROWSONLY;
|Id|Operation|Name|Rows|Bytes|Cost(%CPU)|Time|
|0|SELECTSTATEMENT||5|1450|7(0)|00:00:01|
|*1|VIEW||5|1450|7(0)|00:00:01|
|*2|WINDOWNOSORTSTOPKEY||5|180|7(0)|00:00:01|
|3|TABLEACCESSBYINDEXROWID|T|87310|3069K|7(0)|00:00:01|
|4|INDEXFULLSCAN|T_IDX|5||3(0)|00:00:01|
PredicateInformation(identifiedbyoperationid):
1filter("from$_subquery$_003"."rowlimit_$$_rownumber"<=5)
2filter(ROW_NUMBER()OVER(ORDERBY"OWNER","OBJECT_NAME")<=5)
AsyoucantellbythepredicateinformationinListing1,therowlimitingclauseisusingROW_NUMBER()transparentlyunderthecovers,rewriting
thequerytouseanalytics.Therowlimitingclause,inshort,ismakingitmucheasiertodosomethingyouwouldhavedonemanuallyinthepast.
TopaginatethrougharesultsettogetNrowsatatimefromaspecificpageintheresultsetIaddtheOFFSETclause.InListing2,Iskipthefirst
fiverowsandgetthenextfiverowsfromaresultset.
CodeListing2:SimpleSELECTquerywithOFFSETFETCH
SQL>selectowner,object_name,object_id
2fromt
3orderbyowner,object_name
4OFFSET5ROWSFETCHNEXT5ROWSONLY;
|Id|Operation|Name|Rows|Bytes|Cost(%CPU)|Time|
|0|SELECTSTATEMENT||5|1450|7(0)|00:00:01|
|*1|VIEW||5|1450|7(0)|00:00:01|
|*2|WINDOWNOSORTSTOPKEY||5|180|7(0)|00:00:01|
|3|TABLEACCESSBYINDEXROWID|T|87310|3069K|7(0)|00:00:01|
|4|INDEXFULLSCAN|T_IDX|5||3(0)|00:00:01|
http://www.oracle.com/technetwork/issuearchive/2013/13sep/o53asktom1999186.html 4/5
14/3/2016 AskTom:OnOracleDatabase12c,Part1
PredicateInformation(identifiedbyoperationid):
1filter("from$_subquery$_003"."rowlimit_$$_rownumber"<=CASEWHEN(5>=0)
THEN5ELSE0END+5AND"from$_subquery$_003"."rowlimit_$$_rownumber">5)
2filter(ROW_NUMBER()OVER(ORDERBY"OWNER","OBJECT_NAME")<=CASEWHEN
(5>=0)THEN5ELSE0END+5)
AsyoucanseeinListing2,thedatabase,underthecovers,isrewritingthequerytouseinlineviewsandanalyticsonceagainautomating
somethingthatwaspreviouslynonintuitiveandcomplex.
Notethatinreallife,youwouldusebindvariablesinsteadofhardcodedliterals,soinsteadofusingthenumber5asIdid,youwouldhavebound
inthenumber5.
TomKyteisadatabaseevangelistinOraclesServerTechnologiesdivisionandhasworkedforOraclesince1993.Heis
theauthorofExpertOracleDatabaseArchitecture(Apress,2005,2010)andEffectiveOraclebyDesign(OraclePress,
2003),amongotherbooks.
Sendusyourcomments
Emailthispage PrinterView
http://www.oracle.com/technetwork/issuearchive/2013/13sep/o53asktom1999186.html 5/5