Está en la página 1de 61

ProgramandoconPL/SQLenunaBasede

DatosOracle

Instructor:Ing.FranciscoRiccio.
OCAOracleDatabaseAdministrator10g
OCPOracleDatabaseAdministrator10g
OCPOracleDatabaseAdministrator11g
OCAOracleApplicationServer10g
OracleDatabase10gRACAdministratorCertifiedExpert
ManagingOracleonLinuxCertifiedExpert
OracleDatabaseSQLCertifiedExpert
OracleDatabase11gEssentialsForImplementors
MCTSSQLServer2005

Email:francisco@friccio.com

Ing.FranciscoRiccio.

Pgina 1

Contenido
ConsideracionesenlainstalacindelOracleXEyconfiguracindelOracleSQLDeveloper ................ 3
IntroduccinaPL/SQL ....................................................................................................................... 7
Declaracindevariables.................................................................................................................... 9
ManejodeEstructurasdeControl(IF/CASE/LOOP/WHILE/FOR) ...................................................... 14
ManejodeEstructurasComplejas................................................................................................... 19
(Registros/IndexBy/NestedTable/VArray)...................................................................................... 19
ManejodeCursores ........................................................................................................................ 25
ManipulacindeExcepciones.......................................................................................................... 30
ManejodeArchivos......................................................................................................................... 33
CreacindeStoredProceduresyFunciones.................................................................................... 36
CreacinPaquetes........................................................................................................................... 40
CreacindeTriggers ........................................................................................................................ 44
ConsideracionesenelDiseodeCdigoPL/SQL .............................................................................. 51
ProgramacinOrientadaaObjetosenPL/SQL ................................................................................. 58

Ing.FranciscoRiccio.

Pgina 2

Consideracionesen lainstalacindelOracleXEy
configuracindelOracleSQLDeveloper
Descargas
OracleXE:
http://www.oracle.com/technetwork/database/express
edition/downloads/index.html
OracleSQLDeveloper:
http://www.oracle.com/technetwork/developertools/sql
developer/downloads/index.html

Descargadoslosproductoseinstalados,seindicalospasosparapodergenerar
unaconexinhaciaunabasededatosdesdeelOracleSQLDeveloper.

Ing.FranciscoRiccio.

Pgina 3

DondeenNombredeConexinsecolocaunnombredeidentificacindela
conexinquepudierasercualquiernombre.
Enusuarioycontraseadebeserunusuariovlidodelabasededatosconsu
contrasea,enestecasoestamosutilizandoelusuarioSYSTEMqueexisteenla
basededatos.
EnloscamposdeNombredeHost,PuertoyNombredelServicio,sondatosque
hacenreferenciaallistenerdelabasededatos.Ellisteneresuncomponentede
labasededatosqueserresponsablederealizarlaconexinalabasededatos.
Estosdatospuedenserextradosenelservidordebasededatospublicandoel
comando:lsnrctlstatus,ejemplo:

Ing.FranciscoRiccio.

Pgina 4

Dondelomarcadoconrojosonlosdatosdellistenerquesoncolocadosenel
OracleDeveloper.

LuegopodemosdarclickenProbarydebesalirEstado:Correctoy
posteriormenteguardamoslosdatos.

Ing.FranciscoRiccio.

Pgina 5

Ing.FranciscoRiccio.

Pgina 6

IntroduccinaPL/SQL
PLSQLesunaextensindeprogramacinaSQL.
Esellenguajedeprogramacinde4tageneracinparabasededatosOracle.

Respectoasuarquitectura
TodocdigoPLSQLsecomponedecdigoPLSQL+sentenciasSQL.
DondeelcdigoPLSQLesejecutadoenunenginellamadoPLSQLylassecciones
quesonsentenciasSQLsonejecutadasenelSQLStatementExecutor(Oracle
DatabaseServer).
TodabasededatosOracletieneunPLSQLenginedeformainherente.Existe
otrosproductosquecuentanconunPLSQLenginecomoelOracleApplication
Serverensusproductos(OracleForms,OracleReports).

EnelcasodeaplicacionesconOracleFormsyReports,elPLSQLEnginese
ejecutarenelladodelclienteylasseccionesconsentenciasSQLson
ejecutadasenlabasededatos.
AlgunosBeneficios

Permitecrearprogramasmodulares.

IntegracinconherramientasdeOracle.

Portabilidad.

Ing.FranciscoRiccio.

Pgina 7

ManejaExcepciones.

UncdigoenPLSQLpuedeserdedostipos:cdigoannimoysubprogramas.
Uncdigoannimoesbsicamenteaquelqueelcdigofuenteresideenellado
clienteyunsubprogramaresideelcdigofuenteenelservidor.Los
subprogramaspuedenser:storedprocedures,funciones,triggersypaquetes.

Semuestralasdiferentesseccionesquecomponenlosdiferentestiposdecdigo
PLSQL.

Ing.FranciscoRiccio.

Pgina 8

Declaracindevariables
LaseccindedeclaracindevariablessedefineenlaseccinDECLAREejemplo:
DECLARE
mivar<tipo_dato>
LostiposdedatosenOracleDatabase11genPLSQL:
CHAR,VARCHAR,NUMBER,BINARY_INTEGER:

PLSQL_INTEGER,BOOLEAN,BINARY_FLOAT,BINARY_DOUBLE

Ing.FranciscoRiccio.

Pgina 9

DATE,TIMESTAMP,TIMESTAMPWITHTIMEZONE.

TIMESTAMPWITHLOCALTIMEZONE,INTERVALYEARTOMONTH,INTERVAL
DAYTOSECOND

Ing.FranciscoRiccio.

Pgina 10

Ejemplo#1:
SETSERVEROUTPUTON
DECLARE
V_MIVARIABLEVARCHAR(20):='HOLAMUNDO'
BEGIN
DBMS_OUTPUT.PUT_LINE(V_MIVARIABLE)
DBMS_OUTPUT.PUT_LINE('FINDELPROGRAMA')
END
/

Ejemplo#2
SETSERVEROUTPUTON
DECLARE
V_NUM1NUMBER(4,2):=10.2
V_NUM2NUMBER(4,2):=20.1
BEGIN
DBMS_OUTPUT.PUT_LINE('LASUMAES:'||TO_CHAR(V_NUM1+V_NUM2))
END
/

Ing.FranciscoRiccio.

Pgina 11

Castingentretiposdedatos:

Lasfuncionesdeconversinbsicason:TO_NUMBER,TO_CHARyTO_DATE.
Ejemplo:
Sideseamosconvertirdenmeroacaracter:TO_CHAR(20)
Sideseamosconvertirdecaracteranmero:TO_NUMBER('20')
Sideseamosconvertirdefechaacaracter:TO_CHAR(v_fecha, 'DDMMYYYY
HH24:MI:SS')

Mapeandovariablesatiposdedatosdecolumnasdetablas
Paraindicarqueeltipodedatodeunavariableserelquetieneunacolumna
deunatablasehacemedianteeloperador%type.
Ejemplo#3:
SETSERVEROUTPUTON
DECLARE
V_FECHAV$DATABASE.CREATED%TYPE
BEGIN
SELECTCREATEDINTOV_FECHAFROMV$DATABASE
DBMS_OUTPUT.PUT_LINE('LAFECHADECREACIONDELABASEDEDATOS
FUE:'||TO_CHAR(V_FECHA,'DDMMYYYY'))
END

Ing.FranciscoRiccio.

Pgina 12

Consideraciones

Laasignacindeunvalorsobreunavariableserealizamedianteel
operador:=ejemplo:v_mivariable:=20

TodainstruccindePLSQLfinalizaconpuntoycoma().

Siunquerydevuelveunasolafilayconuncampopuedeserasignadoa
unavariable,ejemplo:
SELECTCOUNT(*)INTOMI_VARIABLEFROMHR.EMPLOYEES

Siunquerydevuelveunasolafilaycon2omscampostambinpuede
serasignadoavariasvariables,ejemplo:
SELECTNAME,CREATEDINTOMI_VAR1,MI_VAR2FROMV$DATABASE

Ing.FranciscoRiccio.

Pgina 13

ManejodeEstructurasdeControl
(IF/CASE/LOOP/WHILE/FOR)
IF
Sintaxis:
IF(OPERACINLOGICA)THEN
ELSIFTHEN
ELSE
ENDIF
Ejemplo#4:
SETSERVEROUTPUTON
DECLARE
V_FECHAV$DATABASE.CREATED%TYPE
BEGIN
SELECTCREATEDINTOV_FECHAFROMV$DATABASE
IF(SYSDATEV_FECHA>30)THEN
DBMS_OUTPUT.PUT_LINE('LABASEDEDATOSFUECREADAHACEMSDE30
DIAS.')
ELSE
DBMS_OUTPUT.PUT_LINE('LABASEDEDATOSFUECREADAHACEMENOSDE
30DIAS.')
ENDIF
END
/

Ejemplo#5
SETSERVEROUTPUTON

Ing.FranciscoRiccio.

Pgina 14

DECLARE
V_FECHAV$DATABASE.CREATED%TYPE
BEGIN
SELECTCREATEDINTOV_FECHAFROMV$DATABASE
IF(SYSDATEV_FECHA>30)THEN
DBMS_OUTPUT.PUT_LINE('LABASEDEDATOSFUECREADAHACEMSDE30
DIAS.')
ELSIF(SYSDATEV_FECHA>15)AND(SYSDATEV_FECHA<30)THEN
DBMS_OUTPUT.PUT_LINE('LABASEDEDATOSFUECREADAHACEMSDE15
DIASYMENOSDE30DIAS.')
ELSE
DBMS_OUTPUT.PUT_LINE('LABASEDEDATOSFUECREADAHACEMENOSDE
15DIAS.')
ENDIF
END
/

CASE
Sintaxis:
CASE
WHENCONDICION1THEN
WHENCONDICION2THEN
ELSE
ENDCASE

Ing.FranciscoRiccio.

Pgina 15

Ejemplo#6:
SETSERVEROUTPUTON
DECLARE
V_TOTALNUMBER:=0
BEGIN
SELECTCOUNT(*)INTOV_TOTALFROMDBA_OBJECTS
CASE
WHENV_TOTAL<2000THEN
DBMS_OUTPUT.PUT_LINE('LABASEDEDATOSTIENEMENOSDE2000
OBJETOS.')
WHEN(V_TOTAL<4000)AND(V_TOTAL>2000)THEN
DBMS_OUTPUT.PUT_LINE('LABASEDEDATOSTIENEENTRE4000A2000
OBJETOS.')
ELSE
DBMS_OUTPUT.PUT_LINE('LABASEDEDATOSTIENEMASDE4000
OBJETOS.')
ENDCASE
END
/

LOOP
Permitegenerarbucles.
Sintaxis:
LOOP
EXITWHENCONDICION_SALIDA
ENDLOOP

Ing.FranciscoRiccio.

Pgina 16

Ejemplo#7:
Imprimiendolosprimeros10nmeros:
SETSERVEROUTPUTON
DECLARE
V_NUMNUMBER:=0
BEGIN
LOOP
V_NUM:=V_NUM+1
DBMS_OUTPUT.PUT_LINE('NUMERO:'||TO_CHAR(V_NUM))
EXITWHENV_NUM>=10
ENDLOOP
END
/

WHILE
Sintaxis:
WHILECONDICIONLOOP
ENDLOOP

Ejemplo#8:
SETSERVEROUTPUTON
DECLARE
V_NUMNUMBER:=1
BEGIN
WHILEV_NUM<11LOOP
DBMS_OUTPUT.PUT_LINE('NUMERO:'||TO_CHAR(V_NUM))

Ing.FranciscoRiccio.

Pgina 17

V_NUM:=V_NUM+1
ENDLOOP
END
/

FOR
Sintaxis:
FORVARIABLEININICIO..FINALLOOP
ENDLOOP

Ejemplo#9:
SETSERVEROUTPUTON
BEGIN
FORV_NUMIN1..10LOOP
DBMS_OUTPUT.PUT_LINE('NUMERO:'||TO_CHAR(V_NUM))
ENDLOOP
END
/

Nota:LavariableutilizadacomocontadorenelFORnorequiereserespecificada
enelDECLARE.

Ing.FranciscoRiccio.

Pgina 18

ManejodeEstructurasComplejas
(Registros/IndexBy/NestedTable/VArray)
Registros
Permitecrearestructurasquealberganunconjuntodetiposdedatos.
Porejemplo,podemoscrearelregistroPERSONAconloscamposcdigo,
nombreyedad,cadaunodeestoscamposcondiferentestiposdedatos.
Sintaxis:
TYPE<NOMBRE_REGISTRO>ISRECORD(
CAMPO1TIPO_DATO,
CAMPO2TIPO_DATO

Ejemplo#10:
SETSERVEROUTPUTON
DECLARE
TYPETPERSONAISRECORD(
CODIGONUMBER,
NOMBREVARCHAR(100),
EDADNUMBER
)
V_VAR1TPERSONA
BEGIN
V_VAR1.CODIGO:=1
V_VAR1.NOMBRE:='FRANCISCO'

Ing.FranciscoRiccio.

Pgina 19

V_VAR1.EDAD:=30
DBMS_OUTPUT.PUT_LINE('CODIGO:'||TO_CHAR(V_VAR1.CODIGO)||'
PERSONA:'||V_VAR1.NOMBRE||'EDAD:'||TO_CHAR(V_VAR1.EDAD)||'.')
END
/

Adicional:
Tambinpodemoscrearregistrosquemantenganlosmismoscamposytiposde
datosqueunatabla.
DECLARE
MIVARIABLEDBA_OBJECTS%ROWTYPE

IndexBy
IndexBypermitecreararreglosenPLSQL.
Sintaxis:
TYPE<NOMBRE_TIPO_LISTA>ISTABLEOF<TIPO_DATO_NODO>INDEXBY
BINARY_INTEGER|PLS_INTEGER|VARCHAR2(#)
Ejemplo#11:
SETSERVEROUTPUTON
DECLARE
TYPET_LISTAISTABLEOFNUMBERINDEXBYBINARY_INTEGER
V_LISTAT_LISTA
BEGIN
FORIIN1..10LOOP
V_LISTA(I):=I
ENDLOOP
FORIIN1..10LOOP

Ing.FranciscoRiccio.

Pgina 20

DBMS_OUTPUT.PUT_LINE(I)
ENDLOOP
END
/

ConsideracionesconlosINDEXBY:

Nopuedenseruntipodedatodeunacolumnadeunatabla.

NorequierenserinicializadoslasvariablesdetipoINDEXBY.

Losnodosdelarreglonorequierenserinicializados.

NestedTable
LosNestedTabletambinpermitecreararreglosenPLSQL.
Sintaxis:
TYPE<NOMBRE_TIPO_LISTA>ISTABLEOF<TIPO_DATO_NODO>
Ejemplo#12:
SETSERVEROUTPUTON
DECLARE
TYPET_LISTAISTABLEOFNUMBER
V_LISTAT_LISTA:=T_LISTA()
BEGIN
FORIIN1..10LOOP
V_LISTA.EXTEND
V_LISTA(I):=I
ENDLOOP
FORIIN1..10LOOP
DBMS_OUTPUT.PUT_LINE(I)

Ing.FranciscoRiccio.

Pgina 21

ENDLOOP
END
/

Ejemplo#13:
CREATETYPET_TELEFONOSISTABLEOFCHAR(7)
/
CREATETABLEPERSONA(CODIGONUMBER,NOMBREVARCHAR(25),LISTA
T_TELEFONOS)
NESTEDTABLELISTASTOREASTAB_LISTA

INSERTINTOPERSONAVALUES
(1,'FRANCISCO',T_TELEFONOS('1234567','7654321'))
COMMIT

SELECT*FROMPERSONA

ConsideracionesconlosNESTEDTABLE:

Puedeseruntipodedatodeunacolumnadeunatabla,peroseguarda
enotrosegmento,esdecirnoseguardaenlamismatablafsicamente.

RequiereserinicializadoslasvariablesdetipoNESTEDTABLE.

Porcadanodonuevodelarreglodebepreviamenteelarregloauto
extenderse.

VARRAY
LosVARRAYtambinpermitencreararreglosenPLSQL,perotienenuntamao
limitadodesdesuespecificacin.
Sintaxis:
TYPE<NOMBRE_TIPO_LISTA>ISVARRAY(#NODOS)OF<TIPO_DATO_NODO>
Ing.FranciscoRiccio.

Pgina 22

Ejemplo#14:
SETSERVEROUTPUTON
DECLARE
TYPET_LISTAISVARRAY(10)OFNUMBER
V_LISTAT_LISTA:=T_LISTA()
BEGIN
FORIIN1..10LOOP
V_LISTA.EXTEND
V_LISTA(I):=I
ENDLOOP
FORIIN1..10LOOP
DBMS_OUTPUT.PUT_LINE(I)
ENDLOOP
END
/

Ejemplo#15:
CREATETYPET_TELEFONOSISVARRAY(2)OFCHAR(7)
/

CREATETABLEPERSONA(CODIGONUMBER,NOMBREVARCHAR(25),LISTA
T_TELEFONOS)

INSERTINTOPERSONAVALUES
(1,'FRANCISCO',T_TELEFONOS('1234567','7654321'))
COMMIT

Ing.FranciscoRiccio.

Pgina 23

SELECT*FROMPERSONA

ConsideracionesconlosVARRAY:

Puedeseruntipodedatodeunacolumnadeunatablaysiesguardado
enlamismatablafsicamente.

RequiereserinicializadoslasvariablesdetipoVARRAY.

Porcadanodonuevodelarreglodebepreviamenteelarregloauto
extenderse.

Los3tiposdearreglostienenmtodosquepodemosutilizarennuestros
cdigos.
Selistaalgunodelosmtodos:

Ing.FranciscoRiccio.

Pgina 24

ManejodeCursores
CadasentenciaSQLqueesejecutadaenlabasededatossiempretiene
asociadouncursor.LoscursoressondefinidosenelPGA(Memoriaprivadapor
cadaserverprocess).
LoscursorespuedenserdefinidiosporOracledeformaexplcitaoimplcita.
ImplcitasignificaqueOracleDatabaseesresponsabledecrearelcursor,abrirlo
recorrerloycerrarlo.Deformaexplcitanosotrossomosresponsablesdelas
actividadesmencionadas.
Elcontroldeuncursorsedefineenelsiguientegrfico:

Sintaxis:
DECLARE
CURSORMICURSORIS<QUERY>
BEGIN
OPENMICURSOR
FETCHMICURSORINTOVARIABLES_PLSQL
CLOSEMICURSOR
END
/

Ing.FranciscoRiccio.

Pgina 25

Ejemplo#16:
SETSERVEROUTPUTON
DECLARE
CURSORMICURSORISSELECTFIRST_NAME,LAST_NAMEFROM
HR.EMPLOYEES
V_NOMBREHR.EMPLOYEES.FIRST_NAME%TYPE
V_APELLIDOHR.EMPLOYEES.LAST_NAME%TYPE
BEGIN
OPENMICURSOR
LOOP
FETCHMICURSORINTOV_NOMBRE,V_APELLIDO
EXITWHENMICURSOR%NOTFOUND
DBMS_OUTPUT.PUT_LINE('NOMBRE:'||V_NOMBRE||',APELLIDO:
'||V_APELLIDO)
ENDLOOP
CLOSEMICURSOR
END
/

Ejemplo#17:
Otraformaderecorrerloscursors:
SETSERVEROUTPUTON
DECLARE
CURSORMICURSORISSELECTFIRST_NAME,LAST_NAMEFROM
HR.EMPLOYEES
BEGIN
FORCINMICURSORLOOP
DBMS_OUTPUT.PUT_LINE('NOMBRE:'||C.FIRST_NAME||',APELLIDO:
Ing.FranciscoRiccio.

Pgina 26

'||C.LAST_NAME)
ENDLOOP
END
/
Enestecaso,elFORautomticamenteaperturaelcursorylocierra.

Loscursorestienenatributosquepuedenayudarnosenelcontroldelmismo.

Trabajandoconcursoresconparmetros:
Permitecrearuncursorquepermitemanejarparmetros,demodoqueel
mismocursorpodemosutilizarloenvariasocasionesreemplazandoelvalordel
parmetro.
Sintaxis:CURSOR<NOMBRE_CURSOR>(PARAMETROTIPO_DATO)IS
<QUERY>
Ejemplo#17:
SETSERVEROUTPUTON
DECLARE
CURSORMICURSOR(COD_DEPNUMBER)ISSELECTFIRST_NAME,LAST_NAME
FROMHR.EMPLOYEESWHEREDEPARTMENT_ID=COD_DEP
BEGIN
FORCINMICURSOR(100)LOOP
DBMS_OUTPUT.PUT_LINE('NOMBRE:'||C.FIRST_NAME||',APELLIDO:

Ing.FranciscoRiccio.

Pgina 27

'||C.LAST_NAME)
ENDLOOP
END
/

WHERECURRENTOF
ElWHERECURRENTOFpermiteactualizarunafilaquelotenemosactualmente
apuntandoennuestrocursor.Comocondicinelcursordebeteneruna
sentenciaSELECTFORUPDATE.
Ejemplo#18:
SETSERVEROUTPUTON
DECLARE
CURSORMICURSOR(COD_DEPNUMBER)ISSELECTFIRST_NAME,LAST_NAME
FROMHR.EMPLOYEESWHEREDEPARTMENT_ID=COD_DEPFORUPDATE
BEGIN
FORCINMICURSOR(100)LOOP
DBMS_OUTPUT.PUT_LINE('NOMBRE:'||C.FIRST_NAME||',APELLIDO:
'||C.LAST_NAME)
UPDATEHR.EMPLOYEES
SETSALARY=1
WHERECURRENTOFMICURSOR
ENDLOOP
COMMIT
END
/

Ing.FranciscoRiccio.

Pgina 28

ManejodecursoresGenricos
Permitecrearuncursordondeentiempodeejecucinseasignarelqueryque
elcursordebemanejar.
Sintaxis:
TYPE<NOMBRE_TIPO>ISREFCURSOR
VARIABLE<NOMBRE_TIPO>

Ejemplo#19:
SETSERVEROUTPUTON
DECLARE
TYPET_CURSORISREFCURSOR
MICURSORT_CURSOR
V_APELLIDOHR.EMPLOYEES.LAST_NAME%TYPE
BEGIN
OPENMICURSORFOR'SELECTLAST_NAMEFROMHR.EMPLOYEES'
LOOP
FETCHMICURSORINTOV_APELLIDO
EXITWHENMICURSOR%NOTFOUND
DBMS_OUTPUT.PUT_LINE('APELLIDO='||V_APELLIDO)
ENDLOOP
CLOSEMICURSOR
END
/

Ing.FranciscoRiccio.

Pgina 29

ManipulacindeExcepciones
Frenteaerroresdeejecucinquenomanejadasautomticamentenuestro
cdigoterminarconerror.Podemosmanejarloserroresyhaceruntrabajo
respectivofrenteaunproblemaesperadoonoesperado.
Sintaxis:
EXCEPTION
WHENERRORTHEN
<ACCION>
LostiposdeerroresyaexistenalgunospreestablecidosporOracleDatabase(20
aproximadamente)peronocubrentodoslosescenarios.Lomejoresdefinir
nuestrospropioserrores.
Sintaxis:
DECLARE
E1EXCEPTION
PRAGMAEXCEPTION_INIT(E1,#_ERROR)
BEGIN
EXCEPTION
WHENE1THEN
<ACCION>
END

Nota:ElPRAGMAEXCEPTIONpermiteasociarlavariableexceptionconun
cdigodeerrordeOracleDatabase.

Ejemplo#20:
SETSERVEROUTPUTON
DECLARE

Ing.FranciscoRiccio.

Pgina 30

E1EXCEPTION
PRAGMAEXCEPTION_INIT(E1,1422)
V_NOMBREHR.EMPLOYEES.LAST_NAME%TYPE
BEGIN
SELECTLAST_NAMEINTOV_NOMBREFROMHR.EMPLOYEES
EXCEPTION
WHENE1THEN
DBMS_OUTPUT.PUT_LINE('ELQUERYDEVUELVEMASDEUNAFILA')
END
/

Siqueremosasegurarnosquesiempremanejaremosunerrorapesarquenolo
hayamosidentificadoeneldiseo,podemosusarlaconstanteOTHERS.
Sintaxis:
EXCEPTION
WHENOTHERSTHEN
<ACCION>

Sideseamosrecibirelmensajedeerrorquedisparlaexcepcinsepuede
utilizarlasfunciones:SQLERRMySQLCODE.

Ing.FranciscoRiccio.

Pgina 31

RAISE_APPLICATION_ERROR:
Permitedispararexcepcionespersonalizadosalasaplicaciones.
Sintaxis:
RAISE_APPLICATION_ERROR(#_ERROR,'MENSAJE',FALSE|TRUE)
DondeOracleDatabasenosreservaloscdigosqueseencuentranenunrango
de20000a20999.
Eltercerparmetroqueesuntipodedatoboolean,pordefaultesFALSEelcual
reemplazacualquiererrorquesevengaarrastrandoyesreemplazadoporel
textoqueseindica.SiencasosecolocaTRUE,seimprimirlacoladeerrores
arrastradosincluidoelmensajepersonalizado.

Ing.FranciscoRiccio.

Pgina 32

ManejodeArchivos
ConOracleDatabasetenemoslaposibilidaddecrearprogramasquecreen
archivosyasimismoleerlos.Estolopodemosrealizargraciasalpaquete
UTL_FILEquenosproporcionaOracle.
Semuestrauncuadrogeneraldelflujodetrabajoconelmanejodearchivos.

Comorequisitoobligatoriodebemoscrearunobjetodirectorioelcualapuntara
undirectoriodelsistemaoperativodondesealojarnuestroarchivo.
Estolorealizamosconelcomando:CREATEORREPLACEDIRECTORY
Ejemplo#21:
Enesteejercicioseguardaralalistadetodoslosempleadosdelatabla
HR.EMPLOYEES.
CREATEORREPLACEDIRECTORYMIDIRECTORIOAS'C:\'
SETSERVEROUTPUT ON
DECLARE
ARCHIVOUTL_FILE.FILE_TYPE
CURSORMICURSORISSELECTLAST_NAMEFROMHR.EMPLOYEES
Ing.FranciscoRiccio.

Pgina 33

BEGIN
ARCHIVO:=UTL_FILE.FOPEN('MIDIRECTORIO','MIARCHIVO.TXT','W')
FORCINMICURSORLOOP
UTL_FILE.PUT_LINE(ARCHIVO,C.LAST_NAME)
UTL_FILE.NEW_LINE(ARCHIVO)
ENDLOOP
UTL_FILE.FCLOSE(ARCHIVO)
END
/

Ejemplo#22:
Enesteejercicioleeremoselarchivoquehemoscreadoenelejercicioanterior.
SETSERVEROUTPUTON
DECLARE
ARCHIVOUTL_FILE.FILE_TYPE
V_LINEAVARCHAR(250)
BEGIN
ARCHIVO:=UTL_FILE.FOPEN('MIDIRECTORIO','MIARCHIVO.TXT','R')
BEGIN
LOOP
UTL_FILE.GET_LINE(ARCHIVO,V_LINEA)
IF(V_LINEAISNOTNULL)THEN
DBMS_OUTPUT.PUT_LINE(V_LINEA)
ENDIF
ENDLOOP
EXCEPTION

Ing.FranciscoRiccio.

Pgina 34

WHENNO_DATA_FOUNDTHEN
DBMS_OUTPUT.PUT_LINE('FINDELARCHIVO')
END
UTL_FILE.FCLOSE(ARCHIVO)
END
/

Ing.FranciscoRiccio.

Pgina 35

CreacindeStoredProceduresyFunciones
Unstoredprocedureesunprocedimientocuyocdigoseguardaenlabasede
datosytienecomoobjetorealizarunaaccinespecfica.
Susintaxiseslasiguiente:
CREATEORREPLACEPROCEDURE<NOMBRE_PROCEDURE>(PARAMETROS)IS
<DEFINICION_VARIABLES>
BEGIN
<CODIGO_PLSQL>
END

Ejemplo#23:
SETSERVEROUTPUTON
CREATEORREPLACEPROCEDURESPU_SUMAR(XINNUMBER,YINNUMBER)
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('LASUMAES:'||TO_CHAR(X+Y))
END
/
Probandoelstoredprocedure:
EXECUTESPU_SUMAR(2,3)

Losparmetrosquepuederecibirunstoredprocedurepuedenserde3tipos:

IN(Default):SiunparmetroesINnopuedesermodificadoenel
transcursodelcdigoPLSQL.

OUT:SiunparmetroesOUTsiemprellegaalcdigodelstoredprocedure
conelvalordeNULLycuandoterminaelcdigodePLSQLelparmetro
mantieneelvalordeformapersistente.

Ing.FranciscoRiccio.

Pgina 36

INOUT:Esunacombinacindeambos.

Ejemplo#24:
CREATEORREPLACEPROCEDURESPU_SUMAR(XINNUMBER,YINNUMBER,Z
OUTNUMBER)
IS
BEGIN
Z:=X+Y
END
/
Probandoelstoredprocedure:
SETSERVEROUTPUTON
DECLARE
V_SUMANUMBER:=0
BEGIN
SPU_SUMAR(1,3,V_SUMA)
DBMS_OUTPUT.PUT_LINE(V_SUMA)
END
/

Ejemplo#25:
CREATEORREPLACEPROCEDURESPU_SUMAR(XINOUTNUMBER,YINOUT
NUMBER,ZOUTNUMBER)
IS
BEGIN
Z:=X+Y
END

Ing.FranciscoRiccio.

Pgina 37

/
Probandoelstoredprocedure:
SETSERVEROUTPUTON
DECLARE
V_SUMANUMBER:=0
V_XNUMBER:=10
V_YNUMBER:=20
BEGIN
SPU_SUMAR(V_X,V_Y,V_SUMA)
DBMS_OUTPUT.PUT_LINE(V_SUMA)
END
/

Unafuncinaligualquelosstoredprocedures,sucdigoseguardaenlabase
dedatosytienecomofuncinrealizarunclculoydevolverunvalor.
Sintaxis:
CREATEORREPLACEFUNCTION<NOMBRE_FUNCTION>(PARAMETROS)
RETURN<TIPO_DATO>
IS
<DEFINICION_VARIABLES>
BEGIN
<CODIGO_PLSQL>
END

Ejemplo#26:
CREATEORREPLACEFUNCTIONGET_TOTAL_OBJ
RETURNNUMBER

Ing.FranciscoRiccio.

Pgina 38

IS
V_TOTALNUMBER:=0
BEGIN
SELECTCOUNT(*)INTOV_TOTALFROMDBA_OBJECTS
RETURNV_TOTAL
END
/
Probandolafuncin:
SELECTGET_TOTAL_OBJFROMDUAL

Restricciones

NopuedeserutilizadoenconstraintsdetipoCHECK.

Nopuedeserutilizadocomodefaultdeunacolumna.

EnsentenciasSQLquellamenafunciones,estasfuncionesestn
restringidasalosiguiente:
o EnsentenciasSELECT,lafuncinnopuedeejecutaruna
sentenciaDML.
o EnsentenciasDELETEoUPDATE,lafuncinnopuedeconsultar
omodificarlatablaqueestteniendoelDELETEoelUPDATE.
o EncualquiersentenciaSELECToDML,lafuncinnopueden
ejecutarunCOMMIToROLLBACK,niunaoperacinDDLniDCL
yaquegeneraunCOMMITimplcito.

Adicional,podemoscrearsubprogramas(funcionesystoredprocedures)que
inicienyfinalicenunatransaccinautnoma.
Sintaxis:
CREATEORREPLACEPROCEDURE<NOMBRE_PROCEDURE>
IS
PRAGMAAUTONOMOUS_TRANSACTION
Ing.FranciscoRiccio.

Pgina 39

CreacinPaquetes
Unpaqueteesunaagrupacinlgicadevariables,funcionesystored
procedures.
Sedividelgicamenteen2partescomosedetallaenelsiguientegrfico:

EspecificacinyBody.
Enlaespecificacinsedefinelasvariablesylossubprogramasquequeremos
publicaralaspersonasquedeseenutilizarnuestrosprogramas.
Enelbodyvalaimplementacindecadasubprogramadefinidoenla
especificacinyadicionalotrossubprogramasquequizsnonecesitamosquese
expongan.
Debemostenermuchocuidadosidefinimosvariablesgeneralesenla
especificacinoenbodyyaquesonpersistenteshastaquelasesinsalgadela
basededatos.
Unaventajadeutilizarpaquetesesquelaprimeravezqueunusuariollamaal
paquetetodalainformacindelpaquetesubeenmemoriaylainformacinde
losvaloresdelasvariablesqueutilizacadasesinseguardaenelUGAdecada
sesin.
Sintaxis:
CREATEORREPLACEPACKAGE<NOMBRE_PAQUETE>IS<CODIGO>END
CREATEORREPLACEPACKAGEBODY<NOMBRE_PAQUETE>IS<CODIGO>
END
Ing.FranciscoRiccio.

Pgina 40

Ejemplo#27:
Especificacin.
CREATEORREPLACEPACKAGEMIPAQUETE
IS
V_VARNUMBER:=0
FUNCTIONGET_SUMA(XNUMBER,YNUMBER)RETURNNUMBER
PROCEDURESPU_ACTUALIZA_STOCK
END
/
Body.
CREATEORREPLACEPACKAGEBODYMIPAQUETE
IS

V_VARNUMBER:=0

FUNCTIONGET_SUMA(XNUMBER,YNUMBER)RETURNNUMBER
IS
BEGIN
RETURNX+Y
END

PROCEDURESPU_ACTUALIZA_STOCK
IS
BEGIN
NULL
END

Ing.FranciscoRiccio.

Pgina 41

END
/

Paratrabajoslargosytemporalesdondeprobablementenorequerimostener
durantetodoelciclodevidadelasesinelvalordeunavariablepodemos
utilizarelPRAGMASERIALLY_REUSABLE.ConelPRAGMA,Oraclemudalas
variablesglobalesalSGA(LargePool)ylosmantieneah.Cadallamadadeun
subprogramaquedeseautilizarlavariable,Oraclerealizaunacopiadela
variablequeencuentraenelSGAalUGAdelusuarioymantieneelvalorenla
sesindelusuariohastaquesefinaliceelsubprogramaquellamalafuncin.
UnPRAGMAesunadirectivadecompilacin.
Ejemplo#28:
CREATEORREPLACEPACKAGEMIPAQUETEIS
PRAGMASERIALLY_REUSABLE
V_NUMNUMBER:=0
PROCEDUREINICIALIZAR(PNNUMBER)
PROCEDUREIMPRIMIR_VALOR
END
/

CREATEORREPLACEPACKAGEBODYMIPAQUETEIS
PRAGMASERIALLY_REUSABLE

PROCEDUREINICIALIZAR(PNNUMBER)IS
BEGIN
MIPAQUETE.V_NUM:=PN
DBMS_OUTPUT.PUT_LINE('NUMERO:'||TO_CHAR(MIPAQUETE.V_NUM))
END
Ing.FranciscoRiccio.

Pgina 42

PROCEDUREIMPRIMIR_VALORIS
BEGIN
DBMS_OUTPUT.PUT_LINE('NUMERO:'||TO_CHAR(MIPAQUETE.V_NUM))
END

END
/
Probando:
SETSERVEROUTPUTON
EXECUTEDBMS_OUTPUT.PUT_LINE('VALORVARIABLE:
'||TO_CHAR(MIPAQUETE.V_NUM))
EXECUTEMIPAQUETE.INICIALIZAR(20)
EXECUTEMIPAQUETE.IMPRIMIR_VALOR
EXECUTEDBMS_OUTPUT.PUT_LINE('VALORVARIABLE:
'||TO_CHAR(MIPAQUETE.V_NUM))

Ing.FranciscoRiccio.

Pgina 43

CreacindeTriggers
Lostriggerssonsubprogramasquesedisparanfrenteaeventosqueocurrenen
labasededatos.
Lostiposdetriggerson:

SimpleDMLtriggers(BEFORE,AFTERyINSTEADOF).

Compoundtriggers.

NonDMLtriggers(DDL&Databaseevents).

Lostriggersdetiposimpledmlserexplicadoacontinuacin.
Lostriggersdetiposimpledmlsonaquellosquesedisparancuandoocurreuna
operacinDMLydependiendodelmomentoquedeseemosquesedispareantes
odespusdelatransaccinoreemplazarlatransaccinporotrocdigo.

Sintaxis:
CREATEORREPLACETRIGGER<NOMBRE_TRIGGER>
INSTEADOF|BEFORE|AFTER
INSERT|DELETE|UPDATEOF<COLUMNAS>
ON<TABLA>
FOREACHROW
WHEN<CONDICION>
DECLARE
BEGIN
<CODIGO>
END

RespectoaFOREACHROW,significaqueeltriggersedispararporcadafila
queestsiendoafectadoporlatransaccin.

Ing.FranciscoRiccio.

Pgina 44

SedetallaunacomparacinentretenerynotenerhabilitadoelFOREACHROW.

Ejemplo#29:
SETSERVEROUTPUTON

CREATETABLETABLA_TG(CAMPO1NUMBER)

CREATEORREPLACETRIGGERTG_TABLA_01
BEFOREINSERTONTABLA_TG
DECLARE
BEGIN
DBMS_OUTPUT.PUT_LINE('CODIGOLIBERADOANTESDELINSERT.')
END
/

CREATEORREPLACETRIGGERTG_TABLA_02
AFTERINSERTONTABLA_TG
DECLARE
BEGIN
DBMS_OUTPUT.PUT_LINE('CODIGOLIBERADODESPUESDELINSERT.')
END
Ing.FranciscoRiccio.

Pgina 45

INSERTINTOTABLA_TGVALUES(1)

Ejemplo#30:
SETSERVEROUTPUTON

DELETEFROMTABLA_TG

ALTERTRIGGERTG_TABLA_01DISABLE
ALTERTRIGGERTG_TABLA_02DISABLE

CREATEORREPLACETRIGGERTG_TABLA_03
BEFOREINSERTONTABLA_TG
FOREACHROW
DECLARE
BEGIN
DBMS_OUTPUT.PUT_LINE('VALORINGRESADOANTESDELINSERT:
'||TO_CHAR(:NEW.CAMPO1))
:NEW.CAMPO1:=10
DBMS_OUTPUT.PUT_LINE('VALORMODIFICADOA10.')
END
/

CREATEORREPLACETRIGGERTG_TABLA_04
AFTERINSERTONTABLA_TG
Ing.FranciscoRiccio.

Pgina 46

FOREACHROW
DECLARE
BEGIN
DBMS_OUTPUT.PUT_LINE('VALORINGRESADODESPUESDELINSERT:
'||TO_CHAR(:NEW.CAMPO1))
END
/

INSERTINTOTABLA_TGVALUES(1)
SETSERVEROUTPUTON

DELETEFROMTABLA_TG

ALTERTRIGGERTG_TABLA_01DISABLE
ALTERTRIGGERTG_TABLA_02DISABLE

CREATETABLETABLA_TG(CAMPO1NUMBER)

CREATEORREPLACETRIGGERTG_TABLA_03
BEFOREINSERTONTABLA_TG
FOREACHROW
DECLARE
BEGIN
DBMS_OUTPUT.PUT_LINE('VALORINGRESADOANTESDELINSERT:
'||TO_CHAR(:NEW.CAMPO1))
:NEW.CAMPO1:=10

Ing.FranciscoRiccio.

Pgina 47

DBMS_OUTPUT.PUT_LINE('VALORMODIFICADOA10.')
END
/

CREATEORREPLACETRIGGERTG_TABLA_04
AFTERINSERTONTABLA_TG
FOREACHROW
DECLARE
BEGIN
DBMS_OUTPUT.PUT_LINE('VALORINGRESADODESPUESDELINSERT:
'||TO_CHAR(:NEW.CAMPO1))
END
/

INSERTINTOTABLA_TGVALUES(1)

Semuestraacontinuacinuncuadroquemuestracuandotenemosdisponibles
lasvariables:NEWy:OLD.

Lostriggersdetipo:INSTEADOFnospermitereemplazarunatransaccinpor
unaaccindiferente.

Ing.FranciscoRiccio.

Pgina 48

Ejemplo#31:
SETSERVEROUTPUTON

DELETEFROMTABLA_TG

ALTERTRIGGERTG_TABLA_01DISABLE
ALTERTRIGGERTG_TABLA_02DISABLE
ALTERTRIGGERTG_TABLA_03DISABLE
ALTERTRIGGERTG_TABLA_04DISABLE

CREATEVIEWVTABLA_TGASSELECTCOUNT(*)ASTOTALFROMTABLA_TG

CREATEORREPLACETRIGGERTG_TABLA_05
INSTEADOFINSERTONVTABLA_TG
BEGIN
DELETEFROMTABLA_TG

Ing.FranciscoRiccio.

Pgina 49

END
/

INSERTINTOVTABLA_TGVALUES(1)

COMMIT

SELECT*FROMTABLA_TG

Restricciones

LostriggersnopuedensercreadosenelesquemaSYS.

Lostriggersnopuedenconfirmaroanularunatransaccin

Ing.FranciscoRiccio.

Pgina 50

ConsideracionesenelDiseo deCdigoPL/SQL
EjecucindeOperacionesDDLyDCL
ConelcomandoEXECUTEIMMEDIATEpodemoscrearcdigodinmicoque
genereunatrasaccinDDLyDCL.
Sintaxis:
EXECUTEIMMEDIATE('<CODIGO_DDL_DCL')

Ejemplo#32:
SETSERVEROUTPUTON
BEGIN
EXECUTEIMMEDIATE('CREATETABLECODIGO_DDL(CAMPO1NUMBER)')
END
/

SELECT*FROMCODIGO_DDL

ConlamismainstruccinEXECUTEIMMEDIATEpodemosrealizarconsultasy
operacionesDMLdeformadinmica.
Sintaxis:
EXECUTEIMMEDAITE('<QUERY>')INTOVARIABLEUSINGVALOR_PARAMETRO

Ejemplo#33:
SETSERVEROUTPUTON
DECLARE
V_TOTALNUMBER:=0
BEGIN

Ing.FranciscoRiccio.

Pgina 51

EXECUTEIMMEDIATE('SELECTCOUNT(*)ASTOTALFROMHR.EMPLOYEES
WHEREDEPARTMENT_ID=:CODIGO')INTOV_TOTALUSING100
DBMS_OUTPUT.PUT_LINE('TOTALDEEMPLEADOSENELDEPARTAMENTO100:
'||TO_CHAR(V_TOTAL))
END
/

NOCOPY
PermitealcompiladorpasarparmetrosOUTyINOUTcomoreferenciaynopor
parmetroporvalorqueeseldefaultestoreduceeloverloadeneltiempode
copiadodelosparmetroscuandoseenvan.

Ejemplo#34:
CREATEORREPLACEPROCEDURESPU_SUMAR(XINOUTNOCOPYNUMBER,Y
INOUTNOCOPYNUMBER,ZOUTNOCOPYNUMBER)
IS
BEGIN
Z:=X+Y
END
/

Notieneefectoenlossiguientesescenarios:

ParmetrosquesonelementosdeunINDEXBY.

SobreparmetrosdefinidoscomoNOTNULL.

Sobreparmetrosquefuerondeclaradoscon%ROWTYPEo%TYPE.

Sielparmetrorequiereunaconversinimplcita.

Ing.FranciscoRiccio.

Pgina 52

BULKCOLLECT
ElBULKCOLLECTnospermitereducirenun50%eltiempodeaccesoalabase
dedatos.Sebasaenminimizarlacantidaddeswitchcontextqueocurrenal
utilizarcursores.UnswitchcontextesunviajedeidayvueltaentreelPLSQL
EngineyelOracleDatabaseServer.

Ejemplo#35:
Enesteejemplosehahechounsolocontextswitch,dondetodalainformacin
delatablaempleadoshasidocargadaenunarregloyhallegadoalPLSQL
Engine.SinohubiramosusadoBULKCOLLECTsehubierahechouncontext
switchporcadafetchqueserealizaenelcursor.

SETSERVEROUTPUTON
DECLARE
CURSORMICURSORISSELECT*FROMHR.EMPLOYEES
TYPETLISTAISTABLEOFHR.EMPLOYEES%ROWTYPE
LISTATLISTA
BEGIN
OPENMICURSOR
FETCHMICURSORBULKCOLLECTINTOLISTA
CLOSEMICURSOR
FORCIN1..LISTA.COUNTLOOP
DBMS_OUTPUT.PUT_LINE(LISTA(C).LAST_NAME)
ENDLOOP
END
/

Ing.FranciscoRiccio.

Pgina 53

Ejemplo#36:
Enesteejemploseesttrayendoencadacontextswitch25filas,elcualesuna
medidaoptimizasegnalgunosanlisisrealizados.Arribade25nodamayor
beneficiodeperformance.

SETSERVEROUTPUTON
DECLARE
CURSORMICURSORISSELECT*FROMHR.EMPLOYEES
TYPETLISTAISTABLEOFHR.EMPLOYEES%ROWTYPE
LISTATLISTA
BEGIN
OPENMICURSOR
LOOP
FETCHMICURSORBULKCOLLECTINTOLISTALIMIT25
FORCIN1..LISTA.COUNTLOOP
DBMS_OUTPUT.PUT_LINE(LISTA(C).LAST_NAME)
ENDLOOP
EXITWHENMICURSOR%NOTFOUND
ENDLOOP
CLOSEMICURSOR
END
/

Ing.FranciscoRiccio.

Pgina 54

FORALL
ConsisteigualqueelBULKCOLLECT,peroahoraestdireccionadopara
operacionesDMLqueseenvandesdeelPLSQLEnginehacialabasededatosen
unamenorcantidaddecontextswitch.

Ejemplo#37:
CREATETABLEEMPLEADO_BKASSELECT*FROMHR.EMPLOYEESWHERE1=2

SETSERVEROUTPUTON
DECLARE
CURSORMICURSORISSELECT*FROMHR.EMPLOYEES
TYPETLISTAISTABLEOFHR.EMPLOYEES%ROWTYPE
LISTATLISTA
BEGIN
OPENMICURSOR
LOOP
FETCHMICURSORBULKCOLLECTINTOLISTALIMIT25
FORALLIIN1..LISTA.COUNT
INSERTINTOEMPLEADO_BKVALUESLISTA(I)
EXITWHENMICURSOR%NOTFOUND
ENDLOOP
CLOSEMICURSOR
END
/

SELECT*FROMEMPLEADO_BK

Ing.FranciscoRiccio.

Pgina 55

Ejemplo#38:

SETSERVEROUTPUTON
DECLARE
CURSORMICURSORISSELECT*FROMHR.EMPLOYEES
TYPETLISTAISTABLEOFHR.EMPLOYEES%ROWTYPE
TYPETINDICEISTABLEOFNUMBERINDEXBYPLS_INTEGER
LISTA1TLISTA
LISTA2TINDICE
BEGIN
OPENMICURSOR
LOOP
FETCHMICURSORBULKCOLLECTINTOLISTA1LIMIT25
FORIIN1..LISTA1.COUNTLOOP
LISTA2(I):=LISTA1(I).EMPLOYEE_ID
ENDLOOP
FORALLIIN1..LISTA1.COUNT
UPDATEHR.EMPLOYEESSETSALARY=1000WHEREEMPLOYEE_ID=
LISTA2(I)
EXITWHENMICURSOR%NOTFOUND
ENDLOOP
CLOSEMICURSOR
END
/

SELECTLAST_NAME,SALARYFROMHR.EMPLOYEES

Ing.FranciscoRiccio.

Pgina 56

DERECHOSDEEJECUCIN
Cuandocreamosunsubprogramaeldueodelsubprogramaenelmomentode
sucreacinyejecucinelusuariopierdesusrolesysoloquedanpresentesus
privilegiosdeobjetoydesistema.

Asimismocuandocreamosunsubprogramapuedeserejecutadoconlos
derechosdelcreadoroporelejecutador.
Pordefaultseejecutaconlosderechosdelcreador.
Paracrearunsubprogramaqueseejecuteconlospermisosdelejecutadorse
debetenerpresentelasiguientesintaxis:

CREATEORREPLACEPROCEDURE<NOMBRE_PROCEDURE>(<PARAMETROS>)
AUTHIDCURRENT_USERIS <CODIGO>

Asimismotenerpresentealmomentodecrearunsubprogramaconlaopcinde
AUTHIDCURRENT_USER:

OperacionesDMLyprivilegiosdeobjetosobretablassonresueltaspor
losprivilegiosdelinvocadordelsubprograma.

Otrassentenciascomollamadasafunciones,procedures,paquetes
sonresueltosconlosderechosdelcreador.

Ing.FranciscoRiccio.

Pgina 57

ProgramacinOrientadaaObjetosenPL/SQL
PLSQLpermitetrabajarconprogramacinorientadaaobjetos,demodoque
podamosinclusoguardarobjetosentablasypoderloextraerconatributosy
mtodos.

Sintaxis:

Ejemplo#39:
CREATEORREPLACETYPEPERSONAASOBJECT
(
CODIGONUMBER,
NOMBREVARCHAR(20),
APELLIDOVARCHAR(25),
MEMBERFUNCTIONGET_NOMBRECOMPLETORETURNVARCHAR
)NOTFINAL
/

CREATEORREPLACETYPEBODYPERSONAIS

Ing.FranciscoRiccio.

Pgina 58

MEMBERFUNCTIONGET_NOMBRECOMPLETORETURNVARCHAR
IS
BEGIN
RETURNNOMBRE||''||APELLIDO
END

END
/

PordefaultlasclasessonFINAL,locualindicaquenopermiteusarseen
herencias.
Asimismopodemostrabajarconherencia.
Ejemplo#40:
EstamoscreandolaclaseEMPLEADOheredandoatributosymtodosdelaclase
PERSONA.
CREATEORREPLACETYPEEMPLEADOUNDERPERSONA
(
SUELDONUMBER,
OVERRIDINGMEMBERFUNCTIONGET_NOMBRECOMPLETORETURNVARCHAR,
MEMBERPROCEDURESPU_ACTUALIZAR_SUELDO(PSUELDONUMBER)
)NOTFINAL
/

CREATEORREPLACETYPEBODYEMPLEADOIS

OVERRIDINGMEMBERFUNCTIONGET_NOMBRECOMPLETORETURNVARCHAR

Ing.FranciscoRiccio.

Pgina 59

IS
BEGIN
RETURNLOWER(NOMBRE||''||APELLIDO)
END

MEMBERPROCEDURESPU_ACTUALIZAR_SUELDO(PSUELDONUMBER)IS
BEGIN
SUELDO:=PSUELDO
END

END
/

Overridingpermitelasobreescrituradeunsubprogramadelpadre.

Tambinestpermitidopolimorfismo.
Enlossiguientespasoscrearemosunatablabasadaennuestroobjeto
EMPLEADOylomanipularemos.

Ejemplo#41:
CREATETABLETEMPLEADOOFEMPLEADO

INSERTINTOTEMPLEADOVALUES(EMPLEADO(1,'FRANCISCO','RICCIO',8000))

SELECT*FROMTEMPLEADO

SELECTE.GET_NOMBRECOMPLETO(),E.*FROMTEMPLEADOE
Ing.FranciscoRiccio.

Pgina 60

SETSERVEROUTPUTON
DECLARE
V_OBJETOEMPLEADO
BEGIN
SELECTVALUE(E)INTOV_OBJETOFROMTEMPLEADOE
V_OBJETO.SPU_ACTUALIZAR_SUELDO(1000)
DBMS_OUTPUT.PUT_LINE('EMPLEADO:
'||V_OBJETO.GET_NOMBRECOMPLETO()||'SUELDO=
'||TO_CHAR(V_OBJETO.SUELDO))
END
/
SihubiramoscreadolavariableV_OBJETOcomoPERSONA,estaramos
trabajandoconpolimorfismo,demodoquelavariablesedeclaradeunaclase
baseysecreaconclasesderivadas.

Ing.FranciscoRiccio.

Pgina 61

También podría gustarte