Tải bản đầy đủ
Lab 22.1: Gathering Information about Stored Code

Lab 22.1: Gathering Information about Stored Code

Tải bản đầy đủ

intheschemaofthecurrentuser.
ForExamplech22_1.sql
Clickheretoviewcodeimage
SELECTOBJECT_TYPE,OBJECT_NAME,STATUS
FROMUSER_OBJECTS
WHEREOBJECT_TYPEIN
(‘FUNCTION’,‘PROCEDURE’,‘PACKAGE’,
‘PACKAGE_BODY’)
ORDERBYOBJECT_TYPE;

Theuser_sourceviewinthedatadictionarycanbeusedtoextractthesourcecode
forprocedures,functions,andpackages.ThecolumnTEXTholdstheactualsourcecode
text,NAMEholdsthename,andTYPEindicatesifitisafunction,procedure,package,or
packagebody.Thetextislistedinorderbylinenumberinthecolumnline.
Thefollowingexamplecreatesafunctioncalledscode_at_linethatprovidesan
easymechanismforretrievingthetextfromastoredprogramforaspecifiedlinenumber.
ForExamplech22_2.sql
Clickheretoviewcodeimage
CREATEORREPLACEFUNCTIONscode_at_line
(i_name_inINVARCHAR2,
i_line_inININTEGER:=1,
i_type_inINVARCHAR2:=NULL)
RETURNVARCHAR2
IS
CURSORscode_curIS
SELECTtext
FROMuser_source
WHEREname=UPPER(i_name_in)
AND(type=UPPER(i_type_in)
ORi_type_inISNULL)
ANDline=i_line_in;
scode_recscode_cur%ROWTYPE;
BEGIN
OPENscode_cur;
FETCHscode_curINTOscode_rec;
IFscode_cur%NOTFOUND
THEN
CLOSEscode_cur;
RETURNNULL;
ELSE
CLOSEscode_cur;
RETURNscode_rec.text;
ENDIF;
END;

Thisfunctionisusefulifadeveloperreceivesacompilationerrormessagereferringtoa
particularlinenumberinanobject.Thedevelopercancallthisfunctiontofindoutwhich
textisthesourceoftheerror.
Thescode_at_linefunctionusesthreeparameters:
name_inThenameofthestoredobject.

line_inThelinenumberofthelineyouwishtoretrieve.Thedefaultvalueis1.
type_inThetypeofobjectyouwanttoview.Thedefaultfortype_inisNULL.
Thedefaultvaluesaredesignedtomakethisfunctionaseasyaspossibletouse.
BytheWay
TheoutputfromacalltoSHOWERRORSinSQL*Plusdisplaystheline
numberinwhichanerroroccurred,butthelinenumberdoesn’tcorrespondto
thelineinyourtextfile.Instead,itrelatesdirectlytothelinenumberstored
withthesourcecodeintheUSER_SOURCEview.
YoucanusetheUSER_ERRORSviewtogetmoredetailsaboutcompilationerrorsthat
occurwhenyouarewritingcode.Thisviewstorescurrenterrorsontheuser’sstored
objects.Thetextfilecontainsthetextoftheerror—ahandyfeaturewhenyouaretryingto
pindownthedetailsofacompilationerror.Followingarethecolumnsforthe
USER_ERRORSviewthatyouwouldseeifyouenteredthecommandDESC
USER_ERRORSinSQL*Plus.
Clickheretoviewcodeimage
NameNull?Type
––––––—––—–––—
NAMENOTNULLVARCHAR2(30)
TYPEVARCHAR2(12)
SEQUENCENOTNULLNUMBER
LINENOTNULLNUMBER
POSITIONNOTNULLNUMBER
TEXTNOTNULLVARCHAR2(2000)

Thefollowingcodefragmentproducesaforcederrorsothatwecandemonstratethe
variousmethodsusedtodebugaproblem:
Clickheretoviewcodeimage
CREATEORREPLACEPROCEDUREFORCE_ERROR
as
BEGIN
SELECTcourse_no
INTOv_temp
FROMcourse;
END;

InSQLDeveloper,theerrorswouldthenbeseeninthecompilerlogscreen.InSQL*Plus,
youneedtotypeSHOERRtoseethesameinformation.Ineithercase,theerrorswillbe
shownasfollows:
Clickheretoviewcodeimage
ErrorsforPROCEDUREFORCE_ERROR:
LINE/COLERROR
––—––––––––––––––—
4/4PL/SQL:SQLStatementignored
5/9PLS-00201:identifier‘V_TEMP’mustbedeclared
6/4PL/SQL:ORA-00904::invalididentifier

YoucanuseaSELECTstatementtoretrieveinformationfromtheUSER_ERRORS

view:
Clickheretoviewcodeimage
SELECTline||’/’||position“LINE/COL”,TEXT“ERROR”
FROMuser_errors
WHEREname=‘FORCE_ERROR’

ItisimportanttoknowhowtoretrievethisinformationfromtheUSER_ERRORSview
becausetheSHOERRcommandsimplybringsupthemostrecenterrors.Ifyouruna
scriptcreatinganumberofobjects,thenyoumustrelyontheUSER_ERRORSviewto
identifyalloftheerrors.
TheUSER_DEPENDENCIESviewisusefulforanalyzinghowtablechangesor
changestootherstoredproceduresaffectotherpartsofthescript.Ifyouplantoredesign
tables,forexample,youmightwanttoassesstheirimpactbyexaminingtheinformation
inthisview.TheALL_DEPENDENCIESandDBA_DEPENDENCIESviewsshowall
dependenciesforprocedures,functions,packagespecifications,andpackagebodies.
EnteringthecommandDESCUSER_DEPENDENCIESinSQL&*Plusproducesthe
followingoutput:
Clickheretoviewcodeimage
NameNull?Type
––––––––––-––—–NAMENOTNULLVARCHAR2(30)
TYPEVARCHAR2(12)
REFERENCED_OWNERVARCHAR2(30)
REFERENCED_NAMENOTNULLVARCHAR2(30)
REFERENCED_TYPEVARCHAR2(12)
REFERENCED_LINK_NAMEVARCHAR2(30)

ThefollowingSELECTstatementdemonstratesthedependenciesforthe
school_apipackage:
SELECTreferenced_name
FROMuser_dependencies
WHEREname=‘SCHOOL_API’;

ThisistheresultofrunningtheSELECTstatement:
REFERENCED_NAME
–––––––––—
STANDARD
STANDARD
DUAL
DBMS_STANDARD
DBMS_OUTPUT
COURSE
ENROLLMENT
INSTRUCTOR
INSTRUCTOR
INSTRUCTOR_ID_SEQ
SCHOOL_API
SECTION

Thislistofdependenciesfortheschool_apipackagelistsallobjectsreferencedinthe
package.Itincludestables,sequences,andprocedures(evenOracle-suppliedpackages).
Thisinformationisveryusefulwhenyouareplanningachangetoadatabasestructure.

Youcaneasilypinpointwhattheramificationsareforanydatabasechanges.
TheDESCcommandinSQL*Plusisusedtodescribethecolumnsinatableaswellas
toidentifyprocedures,packages,andfunctions.Thiscommandshowsalltheparameters
withtheirdefaultvaluesandindicateswhethertheyareINorOUT.Iftheobjectisa
function,thenthereturndatatypeisdisplayed.Thisisverydifferentfromthe
USER_DEPENDENCIESview,whichprovidesinformationonalltheobjectsthatare
referencedinapackage,function,orprocedure.InSQLDeveloper,thesameinformation
canbeobtainedbyfindingthenameoftheobjectinthetreeandhoveringthecursorover
thename.

OverloadingModules
Whenyouoverloadmodules,yougivetwoormoremodulesthesamename.The
parameterlistsofthemodulesmustdifferinamannersignificantenoughforthecompiler
(andrun-timeengine)todistinguishbetweenthedifferentversions.
Youcanoverloadmodulesinthreecontexts:
1.InalocalmoduleinthesamePL/SQLblock
2.Inapackagespecification
3.Inapackagebody
Thefollowingchangestotheschool_apipackagedemonstratehowmodule
overloadingcanbeused.
ForExamplech22_3.sql
Clickheretoviewcodeimage
CREATEORREPLACEPACKAGEschool_apias
v_current_dateDATE;
PROCEDUREDiscount_Cost;
FUNCTIONnew_instructor_id
RETURNinstructor.instructor_id%TYPE;
FUNCTIONtotal_cost_for_student
(i_student_idINstudent.student_id%TYPE)
RETURNcourse.cost%TYPE;
PRAGMARESTRICT_REFERENCES
(total_cost_for_student,WNDS,WNPS,RNPS);
PROCEDUREget_student_info
(i_student_idINstudent.student_id%TYPE,
o_last_nameOUTstudent.last_name%TYPE,
o_first_nameOUTstudent.first_name%TYPE,
o_zipOUTstudent.zip%TYPE,
o_return_codeOUTNUMBER);
PROCEDUREget_student_info
(i_last_nameINstudent.last_name%TYPE,
i_first_nameINstudent.first_name%TYPE,
o_student_idOUTstudent.student_id%TYPE,
o_zipOUTstudent.zip%TYPE,
o_return_codeOUTNUMBER);
ENDschool_api;

Inthisexampleofanoverloadedprocedure,thespecificationhastwoprocedureswith

thesamenameanddifferentINparameters(differentbothinnumberandindatatype).
TheOUTparametersarealsodifferentinnumberanddatatype.Thisoverloadedfunction
acceptseitherofthetwosetsofINparametersandperformstheversionofthefunction
correspondingtothedatatypepassedin.Thenextexamplecontainsthepackagebody.
ForExamplech22_4.sql
Clickheretoviewcodeimage
CREATEORREPLACEPACKAGEBODYschool_apiAS
PROCEDUREdiscount_cost
IS
CURSORc_group_discount
IS
SELECTdistincts.course_no,c.description
FROMsections,enrollmente,coursec
WHEREs.section_id=e.section_id
GROUPBYs.course_no,c.description,
e.section_id,s.section_id
HAVINGCOUNT(*)>=8;
BEGIN
FORr_group_discountINc_group_discount
LOOP
UPDATEcourse
SETcost=cost*.95
WHEREcourse_no=r_group_discount.course_no;
DBMS_OUTPUT.PUT_LINE
(‘A5%discounthasbeengivento’
||r_group_discount.course_no||’
’||r_group_discount.description);
ENDLOOP;
ENDdiscount_cost;
FUNCTIONnew_instructor_id
RETURNinstructor.instructor_id%TYPE
IS
v_new_instidinstructor.instructor_id%TYPE;
BEGIN
SELECTINSTRUCTOR_ID_SEQ.NEXTVAL
INTOv_new_instid
FROMdual;
RETURNv_new_instid;
EXCEPTION
WHENOTHERS
THEN
DECLARE
v_sqlerrmVARCHAR2(250):=
SUBSTR(SQLERRM,1,250);
BEGIN
RAISE_APPLICATION_ERROR(-20003,
‘Errorininstructor_id:‘||v_sqlerrm);
END;
ENDnew_instructor_id;
FUNCTIONtotal_cost_for_student
(i_student_idINstudent.student_id%TYPE)
RETURNcourse.cost%TYPE
IS
v_costcourse.cost%TYPE;
BEGIN
SELECTsum(cost)

INTOv_cost
FROMcoursec,sections,enrollmente
WHEREc.course_no=s.course_no
ANDe.section_id=s.section_id
ANDe.student_id=i_student_id;
RETURNv_cost;
EXCEPTION
WHENOTHERSTHEN
RETURNNULL;
ENDtotal_cost_for_student;
PROCEDUREget_student_info
(i_student_idINstudent.student_id%TYPE,
o_last_nameOUTstudent.last_name%TYPE,
o_first_nameOUTstudent.first_name%TYPE,
o_zipOUTstudent.zip%TYPE,
o_return_codeOUTNUMBER)
IS
BEGIN
SELECTlast_name,first_name,zip
INTOo_last_name,o_first_name,o_zip
FROMstudent
WHEREstudent.student_id=i_student_id;
o_return_code:=0;
EXCEPTION
WHENNO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE
(‘StudentIDisnotvalid.’);
o_return_code:=-100;
o_last_name:=NULL;
o_first_name:=NULL;
o_zip:=NULL;
WHENOTHERS
THEN
DBMS_OUTPUT.PUT_LINE
(‘Errorinprocedureget_student_info’);
ENDget_student_info;
PROCEDUREget_student_info
(i_last_nameINstudent.last_name%TYPE,
i_first_nameINstudent.first_name%TYPE,
o_student_idOUTstudent.student_id%TYPE,
o_zipOUTstudent.zip%TYPE,
o_return_codeOUTNUMBER)
IS
BEGIN
SELECTstudent_id,zip
INTOo_student_id,o_zip
FROMstudent
WHEREUPPER(last_name)=UPPER(i_last_name)
ANDUPPER(first_name)=UPPER(i_first_name);
o_return_code:=0;
EXCEPTION
WHENNO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE
(‘Studentnameisnotvalid.’);
o_return_code:=-100;
o_student_id:=NULL;

o_zip:=NULL;
WHENOTHERS
THEN
DBMS_OUTPUT.PUT_LINE
(‘Errorinprocedureget_student_info’);
ENDget_student_info;
BEGIN
SELECTTRUNC(sysdate,‘DD’)
INTOv_current_date
FROMdual;
ENDschool_api;

Inthisversionoftheschool_api,asinglefunctionname,get_student_info,
acceptseitherasingleINparameterofstudent_idortwoparametersconsistingofa
student’slast_nameandfirst_name.Ifanumberispassedin,thentheprocedure
looksforthenameandZIPcodeofthestudent.Ifitfindsthem,theyarereturnedalong
withareturncodeof0.Iftheycannotbefound,thennullvaluesarereturnedalongwitha
returncodeof100.IftwoVARCHAR2parametersarepassedin,thentheprocedure
searchesforthestudent_idcorrespondingtothenamespassedin.Aswiththeother
versionofthisprocedure,ifamatchisfound,theprocedurereturnsastudent_id,the
student’sZIPcode,andareturncodeof0.Ifamatchisnotfound,thenthevaluesreturned
arenullandtheexitcodeis100.
PL/SQLusesoverloadinginmanycommonfunctionsandbuilt-inpackages.For
example,TO_CHARconvertsbothnumbersanddatestostrings.Overloadingmakesit
easyforotherprogrammerstouseyourcodeinanAPI.
Themainbenefitsofoverloadingarethreefold.First,overloadingsimplifiesthecall
interfaceofpackagesandreducesmanyprogramnamestoone.Second,modulesare
easiertouseandhencemorelikelytobeused.Thesoftwaredeterminesthecontext.
Third,thevolumeofcodeisreducedbecausethecoderequiredfordifferentdatatypesis
oftenthesame.
WatchOut!
Therulesforoverloadingareasfollows:(1)Thecompilermustbeableto
distinguishbetweenthetwocallsatruntime.Distinguishingbetweentheuses
oftheoverloadedmoduleiswhatisimportant—notsolelythedifferencesin
thespecificationorheader.(2)Theformalparametersmustdifferinnumber,
order,ordatatypefamily.(3)Youcannotoverloadthenamesofstand-alone
modules.(4)FunctionsdifferingonlyinRETURNdatatypescannotbe
overloaded.
ThefollowingPL/SQLblockshowshowthisoverloadedfunctioncanbeused:
Clickheretoviewcodeimage
DECLARE
v_student_IDstudent.student_id%TYPE;
v_last_namestudent.last_name%TYPE;
v_first_namestudent.first_name%TYPE;
v_zipstudent.zip%TYPE;
v_return_codeNUMBER;

BEGIN
school_api.get_student_info
(&&p_id,v_last_name,v_first_name,
v_zip,v_return_code);
IFv_return_code=0
THEN
DBMS_OUTPUT.PUT_LINE
(‘StudentwithID‘||&&p_id||’is‘||v_first_name
||’‘||v_last_name
);
ELSE
DBMS_OUTPUT.PUT_LINE
(‘TheID‘||&&p_id||‘isnotinthedatabase’
);
ENDIF;
school_api.get_student_info
(&&p_last_name,&&p_first_name,v_student_id,
v_zip,v_return_code);
IFv_return_code=0
THEN
DBMS_OUTPUT.PUT_LINE
(&&p_first_name||’‘||&&p_last_name||
’hasanIDof‘||v_student_id);
ELSE
DBMS_OUTPUT.PUT_LINE
(&&p_first_name||’‘||&&p_last_name||
‘isnotinthedatabase’
);
ENDIF;
END;

Whenyourunthisscript,youwillbepromptedforthesethreevalues.Hereisan
exampleofavalidvaluetoenterastheinput:
Clickheretoviewcodeimage
Entervalueforp_id:149
Entervalueforp_last_name:‘Prochaska’
Entervalueforp_first_name:‘Judith’

Thisexampledemonstratesthebenefitsofusinga&&variable.Thevalueforthe
variableneedbeenteredonlyonce,butifyourunthecodeasecondtime,youwillnotbe
promptedtoenterthevalueagainbecauseitisnowinmemory.
Hereareafewpointstokeepinmindwhenyouoverloadfunctionsorprocedures.
Thesetwoprocedurescannotbeoverloaded:
Clickheretoviewcodeimage
PROCEDUREcalc_total(reg_inINCHAR);
PROCEDUREcalc_total(reg_inINVARCHAR2).

Inthesetwoversionsofcalc_total,thetwodifferentINvariablescannotbe
distinguishedfromeachother.Inthefollowingexample,ananchoredtype(%TYPE)is
reliedontoestablishthedatatypeofthesecondcalc’sparameter.
Clickheretoviewcodeimage
DECLARE
PROCEDUREcalc(comp_id_ININNUMBER)
IS

BEGIN…END;
PROCEDUREcalc
(comp_id_ININcompany.comp_id%TYPE)
IS
BEGIN…END;

PL/SQLdoesnotfindaconflictatcompiletimewithoverloadingeventhoughcomp_id
isanumericcolumn.Instead,youwillseethefollowingmessageatruntime:
Clickheretoviewcodeimage
PLS-00307:toomanydeclarationsof‘’matchthiscall

Summary
Inthischapter,youlearnedaboutthevariousdatadictionaryviewsthatcanbeusedto
gatherinformationaboutstoredcode.Theseviewsenableyoutoobtaininformationabout
theparametersanddependenciesofthefunctions,procedures,andpackages.Youalso
learnedabouthowtooverloadfunctionsandproceduressothatthesameobjectcanbe
usedindifferentwaysdependingonhowmanyandwhichtypeofvaluesarepassedtothe
callingfunctionorprocedure.
BytheWay
Thecompanionwebsiteprovidesadditionalexercisesandsuggestedanswers
forthischapter,withdiscussionrelatedtohowthoseanswersresulted.The
mainpurposeoftheseexercisesistohelpyoutestthedepthofyour
understandingbyutilizingalloftheskillsthatyouhaveacquiredthroughout
thischapter.

23.ObjectTypesinOracle
Inthischapter,youwilllearnabout
ObjectTypes
ObjectTypeMethods
InOracle,objecttypesarethemainingredientofobject-orientedprogramming.Theyare
usedtomodelreal-worldtangibleentities,suchasstudents,instructors,andbank
accounts,aswellasabstractentities,suchasZIPcodes,geometricalshapes,andchemical
reactions.
Inthischapter,youwilllearnhowtocreateobjecttypes,andhowtonestobjecttypes
withincollectiontypes.Inaddition,youwilllearnaboutdifferentkindsofobjecttype
methodsandtheirusage.
Thischapterisintroductoryinnatureanddoesnotcovermoreadvancedtopicssuchas
objecttypeinheritanceandevolution,REFmodifiers,andobjecttypetables(nottobe
confusedwithcollections).Thesetopics,alongwithmanyothers,arecoveredinOracle’s
documentation—specifically,Oracle’sDatabaseObject-RelationalDeveloper’sGuide.

Lab23.1:ObjectTypes
Afterthislab,youwillbeableto
CreateObjectTypes
UseObjectTypeswithCollections
Objecttypesgenerallyconsistoftwoparts:attributes(data)andmethods(functionsand
procedures).Attributesareessentialcharacteristicsthatdescribetheobjecttype.For
example,someattributesofthestudentobjecttypemaybefirstandlastnames,contact
information,andenrollmentinformation.Methodsarefunctionsandproceduresdefinedin
anobjecttype;theyareoptional.Theyrepresentactionsthatarelikelytobeperformedon
theobjectattributes.Forexample,methodsofthestudentobjecttypemightupdatethe
studentcontactinformation,getthestudent’sname,ordisplaythestudent’sinformation.
Bycombiningattributesandmethods,objecttypesfacilitateencapsulationofdatawith
theoperationsthatmaybeperformedonthatdata.Asanexample,Figure23.1showsthe
objecttypeStudent.SomeoftheattributesoftheStudentobjecttypeareStudent
ID,FirstName,Zip,andEmployer,andsomeofthemethodsareUpdate
ContactInfo,GetStudentID,andGetStudentName.Figure23.1also
showstwoinstancesoftheobjecttype,Student1andStudent2.Anobject
instanceisavalueofanobjecttype.Inotherwords,theinstancesStudent1and
Student2oftheStudentobjecttypecontainactualstudentdatasothattheGet
StudentIDmethodreturnsstudentID102forinstanceStudent1and103for

instanceStudent2.

Figure23.1ObjectTypeStudent
DidYouKnow?
Anobjectinstanceisoftenreferredtosimplyasanobject.
InOracle,anobjecttypeiscreatedwiththeCREATEORREPLACETYPEclauseand
isstoredinthedatabaseschema.Asaconsequence,objecttypescannotbecreatedwithin
aPL/SQLblockorstoredsubprogram.Onceanobjecttypehasbeencreatedandstoredin
thedatabaseschema,aPL/SQLblockorsubprogrammayreferencethatobjecttype.

CreatingObjectTypes
ThegeneralsyntaxforcreatinganobjecttypeisshowninListing23.1(thereserved
wordsandphrasessurroundedbybracketsareoptional):
Listing23.1CreateObjectType
Clickheretoviewcodeimage
CREATE[ORREPLACE]TYPEtype_nameASOBJECT
(attribute_name1attribute_type,
attribute_name2attribute_type,