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