Sunteți pe pagina 1din 82

SQL

SQL.(Structure Query Language)


SQL es el lenguaje de consulta universal para bases de datos.
Desde esta opcin vamos a tratar los temas relacionados con SQL ANSI 92, que es el standar SQL , ya que
luego extinten variantes como T-SQL (TransactSQL! y PL/SQL ("rocedure Language # SQL! que ser$n
tratados en sus propias opciones.
SQL propociona metodos para de%inir la base datos, para manipular la in%ormacin y para gestionar los permisos
de acceso a dic&a in%ormacin.
"ara que un gestor de bases de datos sea consisderado como relacional, debe soportar SQL,
independientemente de las caracteristicas particulares que dic&o gestor pueda aportar.
'onocer SQL es conocer las bases de datos, y todo su potencial.
Introucci!n a SQL
SQL es el lenguaje de consulta universal para bases de datos.
Los mandatos de SQL se dividen en tres grandes grupos di%erenciados, los cuales ser$n tratados por separado
y que unicamente se presentan aqui a modo introductorio.
""L(Data De%inition Language!, es el encargado de la de%inicin de (ases de Datos, tablas, vistas e
)ndices entre otros.
Son comandos propios de este lenguaje*
'+,-T, T-(L,
'+,-T, ./D,0
'+,-T, 1.,2
'+,-T, S3/4/35
"#L(Data 5anipulation Language!, cuya misin es la manipulacin de datos. - trav6s de 6l podemos
seleccionar, insertar, eliminar y actuali7ar datos. ,s la parte que m$s %recuentemente utili7aremos, y que con
ella se construyen las consultas.
Son comandos propios de este lenguaje*
S,L,'T
8"D-T,
./S,+T
./S,+T ./T4
D,L,T, 9+45
"$L (Data 'ontrol Laguage!, encargado de la seguridad de la base de datos, en todo lo re%erente al
control de accesos y privilegios entre los usuarios.
Son comandos propios de este lenguaje*
:+-/T
+,14;,
$o%&onentes el lengua'e SQL.
Tipos de datos.
SQL admite una variada gama de tipos de datos para el tratamiento de la in%ormacin contenida en las tablas,
los tipos de datos pueden ser n<mericos (con o sin decimales!, al%anum6ricos, de %ec&a o booleanos(si o
no!.Seg<n el gestor de base de datos que estemos utili7ando los tipos de datos varian, pero se reducen
basicamente a los expuestos anteriormente, aunque en la actualidad casi todos los gestores de bases de datos
soportan un nuevo tipo, el (L4( ((inary Large 4bject!, que es un tipo de datos especial destinado a almacenar
arc&ivos, im$genes ...
Dependiendo de cada gestor de bases de datos el nombre que se da a cada uno de estos tipos puede
variar.($sicamente tenemos los siguientes tipos de datos.
N(%ericos Al)an(%ericos *ec+a L!gico ,L-,
Integer char(n) Date Bit Image
Numeric(n.m) varchar(n,m) DateTime Text
Decimal(n,m)
Float
5as detalladamente tenemos*
Ti&os e atos n(%ericos
Ti&o "e)inci!n ,ytes
Integer 1alores enteros con signo. =
Numeric(n,m)
/<meros reales de &asta >? digitos (con decimales!, donde n representa el
total de d)gitos admitidos (normalmente denominado precisin! y m el n<mero
de posiciones decimales (escala!.
@>A
Decimal(n,m)
.gual que el tipo numeric. @>A
Float
/<mero de coma %lotante, este tipo de datos se suele utili7ar para los valores
en notacin cienti%ica.
=?
Ti&os e atos al)an(%ericos
Ti&o "e)inci!n ,ytes
char(n)
-lmacena de > a B@@ caracteres al%an<mericos. ,ste valor viene dado por n, y
es el tamaCo utili7ado en disco para almacenar dato. ,s decir si de%ino un
campo como c&ar(B@@!, el tamaCo real del campo ser$ de B@@, aunque el
valor solo contenga >DD.
DB@@
varchar(n)
.gual que el tipo c&ar, con la salvedad que varc&ar almacena <nicamente los
bytes que contenga el valor del campo.
DB@@
/ota*,l tamaCo del campo varia en %uncin de cada base de datos, siendo B@@ el valor standart.
,n realidad el tamaCo viene delimitado por el tamaCo de las p$ginas de datos, para SQL Server el
l)mite esta en ?DDD bytes (?DDD caracteres!, siempre y cuando tengamos de%inido el tamaCo de la
p$gina de datos a ?;
Ti&os e atos )ec+a
Ti&o "e)inci!n ,ytes
Date
-lmacena %ec&as, con d)a, mes y aCo. ?
Datetime
-lmacena %ec&as con %ec&a y &ora =
/ota*La aparicin de los tipos de datos de %ec&a supuso una atentica revolucin el mundo de la
bases de datos, en realidad, la base de datos almacena internamente n<meros enteros, de &ay
que el tamaCo sea de = bytes y ? bytes (B enteros!, pero aporta la validacin del dato introducido.
Ti&os e atos l!gicos
Ti&o "e)inici!n ,ytes
Bit
Tipo bit. -lmacena un D no cero, seg<n las bases de datos ser$ > >. Se
aplica la lgica booleana, D es %also y no cero verdadero.
> bit
Ti&os e atos ,L-,
Ti&o "e)inici!n ,ytes
Image
-lmacena im$genes en %ormato binario, &asta un m$ximo de B :b de tamaCo.
0-2Gb
Text
-lmacena texto en %ormato binario, &asta un m$ximo de B :b de tamaCo.
0-2Gb
arriba
4peradores
Los operadores se pueden de%inir como combinaciones de caracteres que se utili7an tanto para reali7ar
asignaciones como comparaciones entre datos.
Los operadores se dividen en aritm6ticos, relacionales, lgicos, y concatenacin .
-&eraores SQL
Aritmticos
.
Suma
-
+esta
/
"roducto
/
Divisin
// 0
,xponenciacin
Relacionales
1
5enor que
12
5enor o igual que
3
5ayor que
32
5ayor o igual que
13 42
Distinto
41
/o menor que
43
/o mayor que
Lgicos
AN"
Los operadores lgicos permiten comparar expresiones lgicas
devolviendo siempre un valor verdadero o %also.Los operadores lgicos
se evaluan de i7quierda a derec&a.
-5
N-T
Concatenacin
. Se emplea para unir datos de tipo al%an<merico.
arriba
"alabras 'lave
Las palabras clave son identi%icadores con un signi%icado especial para SQL, por lo que no pueden ser utili7adas
para otro proposito distinto al que &an sido pensadas.
SQL dispone de muy pocas rdenes, pero de multiples p$labras clave, lo que le convierten en un lenguaje
sencillo pero tremendamente potente para llevar a cabo su %uncin.
Pala6ras $lave
!! ND N" #$
%G B&GIN B" $'(
$'&$) $!*#& $*+NT $*,,IT
$(&T& $+(#*( D&$I,! D&$!(&
D&!&T& D&#$ DI#TIN$T D&F+!T
&-I#T# F&T$' F!*T F*(
F(*, G(NT G(*+. '%ING
IN IND&- IN#&(T INT&G&(
INT* !I)& ,- ,IN
N*T N+,&(I$ *N *.&N
*( *(D&( (&%*)& (*!!B$)
#&!&$T #&T #+, TB!&
+NI*N +NI/+& +.DT& +#&(
%!+&# %I&0 0'&(& 0IT'
arriba
9unciones -gregadas
Las %unciones agregadas proporcionan a SQL utilidades de c$lculo sobre los datos de las tablas.
,stas %unciones se incorporan en las consultas S7L7$T y retornan un (nico valor al operar sobre un grupo de
registros.
Las %unciones agregadas son.
*unciones Agregaas
#A8() Devuelve el valor m$ximo.
#IN() Devuelve el valor m)nimo.
S9#() Devuelve el valor de la suma de los valores del campo.
$-9NT() Devuelve el n<mero de %ilas que cumplen la condicin
A:;() Devuelve el promedia de los valores del campo
arriba
"redicados
Los predicados son condiciones que se indican en cla<sula <=757 de una consulta SQL.
La siguiente tabla ilustra los predicados de SQL.
Preicaos SQL
BETWEEN...AND
'omprueba que al valor esta dentro de un intervalo
LIKE
'ompara un campo con una cadena al%anum6rica. L.;, admite el uso de
caracteres comodines
ALL
SeCala a todos los elementos de la seleccin de la consulta
ANY
.ndica que la condicin se cumplir$ si la comparacin es cierta para al menos un
elemento del conjunto.
EXISTS
Devuelve un valor verdadero si el resultado de una subconsulta devuelve
resultados.
IN
'omprueba si un campo se encuentra dentro de un determinado rango. ,l rango
puede ser una sentencia S,L,'T.
/o se preocupe si no entiende el signi%icado de alguno de los terminos que &emos presentado aqu), pronto
veremos ejemplos que nos aclarar$n las cosas, de momento nos vale con saber que existen.
Lengua'e e "e)inici!n e atos (I)
Ta6las
,l lenguaje de de%inicin de datos (DDL, Data De%inition Language! es el encargado de permitir la descripcion de
los objetos que %orman una base de datos.
,l lenguaje de de%inicin de datos le va a permitir llevar a cabo las siguientes acciones*
'reacin de tablas, )ndices y vistas.
5odi%icacin de las estructura de tablas, )ndices y vistas.
Supresin de tablas, )ndices y vistas.
"ero antes de continuar vamos a comentar la nomenclatura que emplearemos, si tiene alg<n conocimiento de
programacin le resultar$ %amiliar.
arriba
/omenclatura
La sintaxis empleada para la sentencias en las di%erentes p$ginas esta basada en la notacin ,(/9. 1amos a
ver el signi%icado de algunos simbolos.
S>%6olo Signi)icao
E F
,ncierran par$metros de una orden que el usuario debe sustituir al escribir dic&a orden por los
valores que queramos dar a los par$metros.
G H .ndica que su contenido es opcional.
I J .ndica que su contenido puede repetirse una o mas veces.
K
Separa expresiones. .ndica que pueden emplearse una u otra expresin pero no m$s de una a
la ve7.
-dem$s las palabras clave aparecen en may<scula negrita y los argumentos en min<scula cursiva.
La sintaxis de una sentencia tendr$ un aspecto como este*
CREATE TABLE <nombre_tabla>
(
<nombre_campo> <tipo_datos(tamao)>,
{
<nombre_campo> <tipo_datos(tamao)>}
) ;
arriba
'reacin de tablas
,n el modelo relacional la in%ormacin de una base de datos se almacena en tablas. "ara saber m$s sobre las
tablas y como se almacena la in%ormacin el ellas vea la introduccin a bases de datos.
La creacin de la base de datos debe comen7ar por con la creacin de una o m$s tablas. "ara ello utili7aremos
la sentencia $57AT7 TA,L7.
La sintaxis de la sentencia es la siguiente*
$57AT7 TA,L7 Enombre_tablaF
(
Enombre_campoF Etipo_datos(tamao)F
Gnull K not nullH Gde%ault Evalor_por_defectoFH
I
,Enombre_campoF Etipo_datos(tamao)F
Gnull K not nullH Gde%ault Evalor_por_defectoFHJ
G
, constraint EnombreF &ri%ary ?ey (Enombre_campoFG ,...n H!H
G
, constraint EnombreF )oreign ?ey (Enombre_campoFG ,...n H!
re)erences EtablaLre%erenciadaF ( Enombre_campoF G ,...n H ! H
! M
,jemplo* 1amos a simular una base de datos para un negocio de alquiler de coc&es, por lo que vamos a
empe7ar creando una tabla para almacenar los coc&es que tenemos.
$57AT7 TA,L7 t'oc&es
(
matricula c&ar(?! not null,
marca varc&ar(B@@! null,
modelo varc&ar(B@@! null,
color varc&ar(B@@! null,
numeroLNilometros numeric(>=,B! null e)ault D,
constraint ";L'oc&es &ri%ary ?ey (matricula!
! M
,n este ejemplo creamos una tabla llamada t'oc&es con cinco campos (matricula, marca, modelo, color,
numeroLNilometros!.
/otese que se &an omitido las tildes y los espacios a proposito. /unca cree campos que contengan
caracteres especi%icos de un idioma (tildes, eCes, ...! ni espacios.
Las claves primarias y externas (o %oraneas! se pueden implementar directamente a trav6s de la
instruccin$57AT7 TA,L7, o bien se pueden agregar a trav6s de sentencias ALT75 TA,L7.
'ada gestor de bases de datos implementa distintas opciones para la instruccin $57AT7 TA,L7, pudiendo
especi%icarse gran cantidad de par$metros y pudiendo variar el nombre que damos a los tipos de datos, pero la
sintaxis standart es la que &emos mostrado aqu). Si queremos conocer m$s acerca de las opciones de $57AT7
TA,L7 lo mejor es recurrir a la documentacin de nuestro gestor de base de datos.
arriba
5odi%icacin de tablas
,n ocasiones puede ser necesario modi%icar la estructura de una tabla, com<nmente para aCadir un campo o
reestriccin. "ara ello disponemos de la instrucccin ALT75 TA,L7.
ALT75 TA,L7 nos va a permitir*
-Cadir campos a la estructura incial de una tabla.
-Cadir reestriciones y re%erencias.
"ara aCadir un campo a una tabla existente*
ALT75 TA,L7 Enombre_tablaF
A"" EnombreLcampoF Etipo_datos(tamao)F
Gnull Knot nullH Ge)ault EvalorLporLde%ectoFH
I
, Enombre_campoF Etipo_datos(tamao)F
Gnull Knot nullH Ge)ault EvalorLporLde%ectoFHJ M
,jemplo*
ALT75 TA,L7 t'oc&es
A"" numLpla7as integer null e)ault @M
,n este ejemplo aCadimos el campo numLpla7as a la tabla t'oc&es que &abiamos creado en el apartado
anterior.
"ara aCadir una clave primaria vamos a crear una tabla de cliente y le aCadiremos la clave primaria
ejecutando una sentencia alter table*
CREATE TABLE tClientes
(
codigo integer not null,
nombre varchar(255) not null,
apellidos varchar(255) null,
nif varchar(!) null,
telefono varchar(") null,
movil varchar(") null
);
ALTER TABLE tClientes ADD
CONSTRAINT #$%tClientes primary key (codigo);
'reamos la tabla clientes y le aCadimos una reestriccin primary Ney a la que damos el nombre ";Lt'lientes
en el campo codigo.
Solo podemos modi%icar una <nica tabla a la ve7 con -LT,+ T-(L,, para modi%icar m$s de una tabla
debemos ejecutar una sentencia -LT,+ T-(L, por tabla.
"ara aCadir una clave externa (o %oranea! necesitamos una tercera tabla en nuestra estructura. "or un lado
tenemos la tabla t'oc&es y la tabla t'lientes, a&ora vamos a crear la tabla t-lquileres que ser$ la encargada de
OdecirnosO que clientes &an alquilado un coc&e.
$57AT7 TA,L7 t-lquileres
(
codigo integer not null,
codigoLcliente integer not null,
matricula c&ar(?! not null,
%xLalquiler datetime not null,
%xLdevolucion datetime null
!M

ALT75 TA,L7 t-lquileres A""
$-NST5AINT ";Lt-lquileres &ri%ary ?ey (codigo!,
$-NST5AINT 9;L'lientes )oreign ?ey (codigoLcliente!
re)erences t'lientes ('odigo!,
$-NST5AINT 9;L'oc&es )oreign ?ey (matricula!
re)erences t'oc&es (matricula!M
(ien, en este cdigo creamos la tabla t-lquileres, y luego mediante una sentencia -LT,+ T-(L, aCadimos una
clave primaria llamada ";Lt-lquileres en el campo codigo, una clave externa llamada 9;L'lientes re%erenciada
al codigo de la tabla t'lientes, y por <ltimo otra clave externa llamada 9;L'oc&es re%erenciada al campo
matricula de la tabla t'oc&es.
/ota*'uando creamos una clave externa el campo re%erenciado y el que sirve de re%erencia deben ser del
mismo tipo de datos.
Si somos observadores nos daremos cuenta que los campos que sirven de re%erencia a las claves %oraneas son
las claves primarias de sus tablas. Slo podemos crear claves externas que re%erencien claves primarias.
-l igual que ocurria con la sentencia $57AT7 TA,L7 cada gestor de bases de datos implementa sus mejoras,
siendo la mejor %orma de conocerlas recurrir a la documentacin del gestor de bases de datos.
,n principio, para borrar columnas de una tabla debemos*
>. 'rear una tabla con la nueva estructura.
B. Trans%erir los datos
P. (orrar la tabla original.
y digo en principio, porque como ya &emos comentado seg<n el gestor de bases de datos con el que trabajemos
podremos reali7ar esta tarea a trav6s de una sentencia ALT75 TA,L7.
arriba
,liminacin de tablas.
"odemos eliminar una tabla de una base de datos mediante la instruccion "5-P TA,L7.
"5-P TA,L7 Enombre_tablaFM
La instruccin "5-P TA,L7 elimina de %orma permanente la tabla y los datos en ella contenida.
Si intentamos eliminar una tabla que tenga registros relacionados a trav6s de una clave externa la
instruccin"5-P TA,L7 %allar$ por integridad re%erencial.
'uando eliminamos una tabla eliminamos tambi6n sus )ndices.
Lengua'e e e)inici!n e atos (II)
"e)inici!n e @nices
8n )ndice es una estructura de datos que permite acceder a di%erentes %ilas de una misma tabla a trav6s de un
campo (o campos clave!.
8n )ndice permite un acceso muc&o m$s r$pido a los datos.
[arriba]
.ntroduccin a los )ndices.
"ara entender lo que es un )ndice debemos saber primero como se almacena la in%ormacin internamente en
las tablas de una base de datos. 'ada tabla se divide en p$ginas de datos, imaginemos un libro, podriamos
escribirlo en Ouna sola &oja enormeO al estilo pergamino egipcio, o bien en p$ginas a las que podemos acceder
r$pidamente a traves de un )ndice. ,st$ idea es la que se aplica en el mundo de las bases de datos, la
in%ormacin esta guardada en una tabla (el libro! que tiene muc&as &ojas de datos (las p$ginas del libro!, con un
)ndice en el que podemos buscar la in%ormacin que nos interesa.
Si queremos buscar la palabra 7apato en un diccionario , Qqu6 &acemosR
Leemos todo el diccionario &asta encontrar la palabra, con lo que nos &abremos leido el diccionario
enterito (Sseguro que aprenderiamos un montnT!
(uscamos en el )ndice en que p$gina est$ la letra 7, y es en esa p$gina donde buscamos.
/i que decir tiene que la opcin dos es la correcta, y es de este modo como se utili7a un )ndice en las bases de
datos, se de%ine el )nidice a trav6s de un campo (o campos! y es a partir de este punto desde donde de busca.
Los )ndices se actuali7an autom$ticamente cuando reali7amos operaciones de escritura en la base de datos.
,ste es un aspecto muy importante de cara al rendimiento de las operaciones de escritura, ya que adem$s de
escribir los datos en la tabla se escribiran tambi6n en el indice. 8n n<mero elevado de )ndices &ar$ m$s lentas
estas operaciones. Sin embargo, salvo casos excepcionales, el bene%icio que aportan los indices compensa (de
largo! esta penali7acin.
arriba
'reacin de )ndices
La creacin de )ndices, como ya &emos visto, permite acelerar las consultas que se reali7an en la base de
datos.
Las sentencias de SQL para manipular )ndices son*
$57AT7 IN"78M

"5-P IN"78M

La sintaxis para la creacin de indices es la siguiente*
CREATE &UNIQUE' INDEX <nombre%indice>
ON <nombre%tabla>(
<nombre%campo> &ASC ( DESC'
{,<nombre%campo> &ASC ( DESC'})
);
La p$labra clave 9NIQ97 especi%ica que que no pueden existir claves duplicadas en el )ndice.
AS$ K "7S$ especi%ican el criterio de ordenacin elegido, ascendente o descendente, por de%ecto es
ascendente.
,jemplo* ,n el apartado dedicado a la de%inicin de tablas creamos la tabla t'lientes, este ejmplo crea un )ndice
<nico en el campo /.9. ,sto nos permitir$ buscar muc&o mas r$pido por el campo /.9 y nos asegurar$ que no
tengamos dos /.9 iguales.
CREATE UNIQUE INDEX )*+%C,*-./-0%.*1
ON tC,*-./-0 (.*1);
Las claves &ri%arias son >nices.
Los nombres de los )ndices deben ser <nicos.
"ara eliminar un )ndice debemos emplear la sentencia "5-P IN"78.
DROP INDEX <nombre%tabla>2<nombre%indice>;
,jemplo*"ara eliminar el )ndice creado anteriormente.
DROP INDEX tC,*-./-02)*+%C,*-./-0%.*1;
Lengua'e e e)inici!n e atos (III)
:istas
,n el modelo de datos relacional la %orma de guardar la in%ormacin no es la mejor para ver los datos
8na vista es una consulta, que re%leja el contenido de una o m$s tablas, desde la que se puede acceder a los
datos como si %uera una tabla.
Dos son las principales ra7ones por las que podemos crear vistas.
Seguridad, nos pueden interesar que los usuarios tengan acceso a una parte de la in%ormacin que
&ay en una tabla, pero no a toda la tabla.
'omodidad, como &emos dic&o el modelo relacional no es el m$s comodo para visuali7ar los datos, lo
que nos puede llevar a tener que escribir complejas sentencias SQL, tener una vista nos simpli%ica esta tarea.
Las vistas no tienen una copia %)sica de los datos, son consultas a los datos que &ay en las tablas, por lo que si
actuali7amos los datos de una vista, estamos actuali7ando realmente la tabla, y si actuali7amos la tabla estos
cambios ser$n visibles desde la vista.
NotaA No sie%&re &ore%os actualiBar los atos e una vista, e&enerC e la co%&le'ia e la %is%a
(e&enerC e si el co'unto e resultaos tiene acceso a la clave &rinci&al e la ta6la o no), y el gestor
e 6ase e atos. No toos los gestores e 6ases e atos &er%iten actualiBar vistas, -5A$L7, &or
e'e%&lo, no lo &er%ite, %ientrar Due SQL Server si.
arriba
$reaci!n e vistas.
"ara crear una vista debemos utili7ar la sentencia $57AT7 :I7<, debiendo proporcionar un nombre a la vista y
una sentencia SQL S7L7$T v$lida.
CREATE VIEW <nombre%vista>
AS
(<sentencia%select>);
7'e%&loA$rear una vista so6re nuestra ta6la alDuileres, en la Due se nos %uestre el no%6re y a&ellios
el cliente en lugar e su c!igo.
CREATE VIEW vAlquilere
AS
(
SELECT nombre,
apellidos,
matricula
!RO" t3l4uileres,
tClientes
W#ERE ( t3l4uileres2codigo%cliente 5 tClientes2codigo )
)
Si Duere%os, %oi)icar la e)inici!n e nuestra vista &oe%os utiliBar la sentencia ALT75 :I7<, e
)or%a %uy &arecia a co%o lo +acia%os con las ta6las. 7n este caso Duere%os aEair los
ca%&os )FGalDuiler y )FGevolucion a la vista.
ALTER VIEW v3l4uileres
AS
(
SELECT nombre,
apellidos,
matricula,
f6%al4uiler,
f6%devolucion
!RO" t3l4uileres,
tClientes
W#ERE ( t3l4uileres2codigo%cliente 5 tClientes2codigo )
)
Por (lti%o &oe%os eli%inar la vista a travHs e la sentencia "5-P :I7<. Para eli%inar la vista Due
+e%os creao anterior%ente se uitliBar>aA
"5-P :I7< v-lquileresM
8na vista se consulta como si %uese una tabla.
arriba
Sin!ni%os
8n sinnimo es un nombre alternativo que identi%ica un tabla en la base de datos. 'on un sinnimo se pretende
normalmente simplicar el nombre original de la tabla, aunque tambien se suelen utili7ar para evitar tener que
escribir el nombre del propietario de la tabla.
No toas las 6ases e atos so&ortan los sin!ni%os.
"ara crear un sinnimo &ay uque utili7ar la sentencia $57AT7 SIN-NI# especi%icando el nombre que
deseamos utili7ar como sinnimo y la tabla para la que estamos creando el sinnimo.
CREATE S$NON$" <nombre%sinonimo>
!OR <nombre%tabla>;
7'e%&loA 7l siguente e'e%&lo crea el sin!ni%o $oc+es &ara la ta6la t$oc+es.
CREATE S$NON$" Coches
!OR tCoches;
Para eli%inar el sin!ni%o creao e6e%os e%&lear la sentencia "5-P SIN-NI#.
DROP S$NON$" Coches;
Lengua'e e %ani&ulaci!n e atos (I)
'onsulta de datos.
,l proceso m$s importate que podemos llevar a cabo en una base de datos es la consulta de los datos. De
nada servir)a una base de datos si no puedieramos consultarla. ,s adem$s la operacin que e%ectuaremos con
mayor %recuencia.
"ara consultar la in%ormacin SQL pone a nuestra disposicin la sentencia S7L7$T.
[arriba]
La sentencia S,L,'T
La sentencia S7L7$T nos permite consultar los datos almacenados en una tabla de la base de datos.
,l %ormato de la sentencia select es*
S7L7$T GALL J "ISTIN$T H
Enombre_campoF GI,Enombre_campoFJH
*5-# Enombre_tablaFKEnombre_vistaF
GI,Enombre_tablaFKEnombre_vistaFJH
G<=757 EcondicionF GI AN"K-5 EcondicionFJHH
G;5-9P ,I Enombre_campoF GI,Enombre_campo FJHH
G=A:IN; EcondicionFGI AN"K-5 EcondicionFJHH
G-5"75 ,I Enombre_campoFKEindiceLcampoF GAS$ K "7S$H
GI,Enombre_campoFKEindiceLcampoF GAS$ K "7S$ HJHH

1eamos por partes que quiere decir cada una de las partes que con%orman la sentecia.
Signi)icao
S7L7$T
"alabra clave que indica que la sentencia de SQL que queremos ejecutar es de
seleccin.
ALL
.ndica que queremos seleccionar todos los valores.,s el valor por de%ecto y no suele
especi%icarse casi nunca.
"ISTIN$T .ndica que queremos seleccionar slo los valores distintos.
*5-#
.ndica la tabla (o tablas! desde la que queremos recuperar los datos. ,n el caso de que
exista m$s de una tabla se denomina a la consulta Oconsulta combinadaO o OjoinO. ,n las
consultas combinadas es necesario aplicar una condicin de combinacin a trav6s de
una cl$usula <=757.
<=757
,speci%ica una condicin que debe cumplirse para que los datos sean devueltos por la
consulta. -dmite los operadores lgicos AN" y -5.
GR!" BY
,speci%ica la agrupacin que se da a los datos. Se usa siempre en combinacin con
%unciones agregadas.
$A%ING
,speci%ica una condicin que debe cumplirse para los datos,speci%ica una condicin que
debe cumplirse para que los datos sean devueltos por la consulta. Su %uncionamiento es
similar al de <=757 pero aplicado al conjunto de resultados devueltos por la consulta.
Debe aplicarse siempre junto a ;5-9P ,I y la condicion debe estar re%erida a los
campos contenidos en ella.
RDER BY
"resenta el resultado ordenado por las columnas indicadas. ,l orden puede expresarse
conAS$ (orden ascendente! y "7S$ (orden descendente!. ,l valor predeterminado
es AS$.
"ara %ormular una consulta a la tabla t'oc&es (creada en el cap)tulo de tablas! y recuperar los campos
matricula, marca, modelo, color, numeroLNilometros, numLpla7as debemos ejecutar la siguiente consulta. Los
datos seran devueltos ordenados por marca y por modelo en orden ascendente, de menor a mayor.
S7L7$T matricula,
marca,
modelo,
color,
numeroLNilometros,
numLpla7as
*5-# t'oc&es
-5"75 ,I marca,modeloM
La palabra clave *5-# indica que los datos ser$n recuperados de la tabla t'oc&es. "odriamos &aber
especi%icado mas de una tabla, pero esto se ver$ en el apartado de consultas combinadas.
Tambien podr)amos &aber simplicado la consulta a trav6s del uso del comodin de campos, el asterisco OUO.
S7L7$T U
*5-# t'oc&es
-5"75 ,I marca,modeloM
,l uso del asterisco indica que queremos que la consulta devuelva todos los campos que existen en la tabla.
[arriba]
La clCusula <=757
La cl$usula <=757 es la instruccin que nos permite %iltrar el resultado de una sentencia S7L7$T.
Vabitualmente no deseamos obtener toda la in%ormacin existente en la tabla, sino que queremos obtener slo
la in%ormacin que nos resulte util es ese momento. La cl$usula <=757 %iltra los datos antes de ser devueltos
por la consulta.
,n nuestro ejemplo, si queremos consultar un coc&e en concreto debemos agregar una cl$usula <=757.
,sta cl$usula especi%ica una o varias condiciones que deben cumplirse para que la sentencia S7L7$T devuelva
los datos. "or ejemplo, para que la consulta devuelva slo los datos del coc&e con maricula 5>@B@W-
debemos ejecutar la siguiente sentencia*
S7L7$T matricula,
marca,
modelo,
color,
numeroLNilometros,
numLpla7as
*5-# t'oc&es
<=757 matricula X Y5>@B@W-YM
'uando en una cl$usula Z&ere queremos incluir un tipo texto, debemos incluir el valor entre
comillas simples.
-dem$s, podemos utili7ar tantas condiciones como queramos, utili7ando los operadores lgicos AN" y -5 .
,l siguiente ejemplo muestra una consulta que devolver$ los coc&es cuyas matriculas sean 5>@B@W- o bien
5B@[[--.
S7L7$T matricula,
marca,
modelo,
color,
numeroLNilometros,
numLpla7as
*5-# t'oc&es
<=757 matricula X Y5>@B@W-Y
-5 matricula X Y5B@[[--Y M
-dem$s una condicin <=757 puede ser negada a trav6s del operador lgico N-T. La siguiente consulta
devolver$ todos los datos de la tabla t'o&es menos el que tenga matricula 5>@B@W-.
S7L7$T matricula,
marca,
modelo,
color,
numeroLNilometros,
numLpla7as
*5-# t'oc&es
<=757 N-T matricula X Y5>@B@W-Y M
"odemos tambien obtener las di%erentes marcas y modelos de coc&es ejecutando la consulta.
S7L7$T "ISTIN$T marca,
modelo
*5-# t'oc&esK
La ver los valores distintos. ,n el caso anterior se devolveran lpalabra clave "ISTIN$T indica que slo
queremos os valores distintos del par %ormado por los campos marca y modelo.
[arriba]
La clCusula -5"75 ,I
'omo ya &emos visto en los ejemplos anteriores podemos especi%icar el orden en el que ser$n devueltos los
datos a trav6s de la cl$usula -5"75 ,I.
S7L7$T matricula,
marca,
modelo,
color,
numeroLNilometros,
numLpla7as
*5-# t'oc&es
-5"75 ,I marca AS$,modelo "7S$M
'omo podemos ver en el ejemplo podemos especi%icar la ordenacin ascendente o descendente a trav6s de
las palabras clave AS$ y "7S$. La ordenacin depende del tipo de datos que este de%inido en la columna, de
%orma que un campo n<merico ser$ ordenado como tal, y un al%an<merico se ordenar$ de la - a la W, aunque su
contenido sea n<merico. De esta %orma el valor >DD se devuelve antes que el >>.
Tambi6n podemos especi%icar el en la cl$usula -5"75 ,I el )ndice n<merico del campo dentro del la
sentencia S7L7$T para la ordenacin, el siguiente ejemplo ordenar)a los datos por el campo marca, ya que
aparece en segundo lugar dentro de la lista de campos que componen la S7L7$T.
S7L7$T matricula,
marca,
modelo,
color,
numeroLNilometros,
numLpla7as
*5-# t'oc&es
-5"75 ,I BM
,l resto de opciones que podemos especi%icar al construir sentencias S7L7$T se ir$n presentando en los
siguientes capitulos de este tutorial.
Lengua'e e %ani&ulaci!n e atos (II)
Insertar atos.
Vasta a&ora &emos visto como se almacenan los datos en una base de datos y como consultar esos datos
almacenados, pero no &emos visto como almacenar dic&os datos.
"ara almacenar datos en una base de datos debemos insertar %ilas en las tablas. "ara ellos SQL pone a
nuestra disposicin la sentencia INS75T.
[arriba]
Inserci!n e )ilas
,l proceso de insercin de %ilas consiste en aCadir a una tabla una o m$s %ilas y en cada %ila todos o parte de
sus campos.
"odemos distinguir dos %ormas de insertar %ilas*
.nsercin individual de %ilas.
.nsercin multiple de %ilas.
La sintaxis de la sentencia INS75T es di%erente seg<n cual sea nuestro proposito.
Slo podremos omitir un campo al e%ectuar una insercin cuando este acZepte valores nulos.
[arriba]
Inserci!n iniviual e )ilas
"ara reali7ar la inserccin individual de %ilas SQL posee la instruccin INS75T INT-.La inserccin individual
de %ilas es la que m$s comunmente utili7aremos. Su sintaxis es la siguiente*
INSERT INTO <nombre_tabla>
&(<campo1>&,<campo2>,222')'
value
(<valor1>,<valor2>,222);
'omo se puede observar la sentencia tiene dos partes claramente di%erenciadas, por un lado la
propiaINS75T INT- seguida de la lista de campos en los que queremos insertar los datos, y por otro la lista de
valores que queremos insertar en los campos. La mejor %orma de ver esto es a trav6s de un ejemplo.
INSERT INTO t'oc&es
(matricula,
marca ,
modelo ,
color ,
numeroLNilometros)
value
(78C37,
79-.3),/7,
78-:3.- /9!!7,
7.-:9; <*383./-7,
=>!!!);
.ota?@emos utiliAado el color roBo para los datos de tipo
te6to, entrecomillados con la comilla simple, C el aAul para
los numericos2
'on esta sentencia INS75T creamos un registro en la tabla t'oc&es con los valores especi%icados, es decir,
la matricula tendr$ el valor 5>>>>'-, la marca ser$ +,/-8LT y as) sucesivamente.
QQue ocurrir)a si ya existiera un coc&e con la matricula 5>>>>'-R Se producir$ un error, porque &emos
de%inido la clave primaria en el campo matricula, y como &emos visto la clave primaria debe ser <nica.
Si omitimos alg<n par O campovalor O en la sentencia INS75T, pueden ocurrir varias cosas*
Que se produ7ca un error , si el campo no acepta valores nulos.
Que se grave el registro y se deje nulo el campo, cuando el campo acepte valores nulos.
Que se grave el registro y se tome el valor por de%ecto, cuando el campo tenga de%inido un valor por
de%ecto.
Que &acer en cada cada momento depender$ del programa.
"or ejemplo, la siguiente sentencia crear$ un registro en la tabla t'oc&es con el campo numeroLNilometros
cero, ya que este es su valor por de%ecto.
INSERT INTO t'oc&es
(matricula,
marca ,
modelo ,
color)
value
(78C37,
79-.3),/7,
78-:3.- /9!!7,
7.-:9; <*383./-7);
[arriba]
Inserci!n %ulti&le e )ilas
La sentencia INS75T permite tambien insertar varios registros en una tabla. "are ello se utili7a una combinacin
de la sentencia INS75T junto a una sentencia S7L7$T. ,l resultado es que se insertan todos los registros
devueltos por la consulta.
INSERT INTO <nombre_tabla>
&(<campo1>&,<campo2>,222')'
SELECT
&(<campo1>&,<campo2>,222')'
!RO"
<nombre_tabla_origen>;
"ara poder utili7ar la insercin multiple de %ilas se deben cumplir las siguientes normas*
La lista de campos de las sentencias insert y select deben coincidir en n<mero y tipo de datos.
/inguna de las %ilas devueltas por la consulta debe in%ringir las reglas de integridad de la tabla en la
que vayamos a reali7ar la insercin.
"ongamos un ejemplo, vamos a crear una tabla con las di%erentes marcas que tenemos en la base de datos. La
sentencia SQL para crear la tabla es la siguiente*
CREATE TABLE t8arcas
(
codigo integer not null i%e&'i'y(,),
marca varchar(255),
()&'rai&' #$%8arcas primary key (codigo)
);
.ota? @emos incluido la funciDn identitC para el campo codigo,
esta funciDn es propia de 0E, 0erver e indica 4ue
el cDdigo se genera automFticamente cada veA 4ue se inserta un
registro con un valor autonumGrico2 #raticamente
todos los gestores de bases de datos dan la opciDn del campo
autonumerico o incremental, si bien el modo varias2
#ara 0E, 0erver utiliAaremos la funcion identitC, para ;93C,-
las secuencias 222
8na ve7 que tenemos creada la tabla de marcas vamos a insetar otro par de registros en la tabla de coc&es,
para ello utili7amos una sentencia insert into para una <nica %ila.
INSERT INTO t'oc&es
(matricula,
marca ,
modelo ,
color)
value
(7822HH1@7,
70-3/7,
7,-;. 197,
79;I;7);

INSERT INTO t'oc&es
(matricula,
marca ,
modelo ,
color)
value
(78HH21J7,
71;9<7,
71*-0/37,
7:9*0 #,3/37);
-&ora tenemos tres marcas di%erentes en la tabla t'oc&es, y queremos insertarlas en la tabla de marcas, para
ello podemos reali7ar tres inserciones individuales, pero Qque pasaria si no supieramos de antemano el n<mero
de marcasRQy si %ueran unas cincuenta marcasR. /os podriamos pasar el d)a entero escribiendo
sentencias insert into.
-%ortunadamente podemos reali7ar una insercin multiple del siguiente modo*
INSERT INTO t5arcas
(marca!
S7L7$T "ISTIN$T marca *5-# t'oc&esM
'omo resultado obtenemos un registro en la tabla t5arcas por cada marca de la tabla t'oc&es. ,l campo
codigo se &a generado autom$ticamente ya que est$ de%inido como identidad.
$*DIG* &ARCA
1 F*(D
2 (&N+!T
2 S,-T
Demonos cuenta de que el orden de generacin no &a sido el mismo que el de insercin, sino que se &a
aplicado el orden en el que &an sido devueltos los datos por la sentencia S,L,'T.
-&ora deberiamos cambiar los datos de la tabla t'oc&es, para guardar el cdigo de la marca en lugar de su
descripcin, pero para ello necesitamos saber como modi%icar un dato grabado ... ,s momento de pasar al
siguiente punto, la actualizacin de datos.
,orrao e atos.
La sentencia "7L7T7.
"ara borrar datos de una tabla, debemos utili7ar la sentencia "7L7T7.
La sintaxis de la sentencia "7L7T7 es la siguiente*
DELETE !RO" <nombre_tabla>
& W#ERE <condicion>';
,l siguiente ejemplo ilustra el uso de la sentencia "7L7T7. ,s buena idea especi%icar en la
sentencia <=757los campos que %orman la clave primaria de la tabla para evitar borrar datos que no queramos
eliminar.
DELETE !RO" tCoches
W#ERE marca 5 70-3/7;
La sintaxis de D,L,T, varia en -ccess, siendo necesario el uso del comod)n U. D,L,T, U 9+45
Et'oc&esF
'uando trabajemos con la sentencia "7L7T7 debemos tener en cuenta las siguientes consideraciones*
Solo podemos borrar datos de una <nica tabla.
'uando borramos datos de una vista, los estamos borrando tambi6n de la tabla. Las vistas son solo
una %orma de ver los datos, no una copia.
Si intentamos borrar un registro de una tabla re%erenciada por una *-57IN; L7I como tabla maestra,
si la tabla dependiente tiene registros relacionados la sentencia "7L7T7 %allar$.
La sentencia T59N$AT7
"ara reali7ar un borrado completo de tabla debemos considerar la posibilidad de utili7ar la
sentenciaT59N$AT7, muc&o m$s r$pida que "7L7T7.
La sintaxis de la sentencia T59N$AT7 es la siguiente*
TRUNCATE TABLE <nombre_tabla>;
,l siguiente ejemplo muestra el uso de la sentencia T59N$AT7.
TRUNCATE TABLE tCoches;
'uando trabajemos con la sentencia T59N$AT7 debemos tener en cuenta las siguientes consideraciones.
La sentencia T59N$AT7 no es transaccional. /o se puede des&acer.
La sentencia T59N$AT7 no admite clausula <=757. (orra toda la tabla.
/o todos los gestores de bases de datos admiten la sentencia T59N$AT7.
ActualiBaci!n e atos.
La sentencia 9P"AT7.
"ara la actuali7acin de datos SQL dispone de la sentencia 9P"AT7. La sentencia 9P"AT7 permite la
actuali7acin de uno o varios registros de una <nica tabla. La sintaxis de la sentencia 9P"AT7 es la siguiente
UPDATE <nombre_tabla>
SET <campo1> 5 <valor1>
{&,<campo2> 5 <valor2>,222,<campoN> 5 <valorN>'}
& W#ERE <condicion>';
Las siguientes sentencias actuali7an los datos de la tabla t'oc&es con los valores de la tabla t5arca
obtenidos anteriormente en la p$gina dedicada a la insercin de datos.
UPDATE tCoches
SET marca 5 77
W#ERE marca 5 71;9<7;

UPDATE tCoches
SET marca 5 727
W#ERE marca 5 79-.3),/7;

UPDATE tCoches
SET marca 5 7H7
W#ERE marca 5 70-3/7;
/otese que los valores para el campo marca aparecen entrecomillados, ya que es un campo de tipovarc+ar.
Los valores con los que actualicemos los datos deben ser del tipo del campo.
8n aspecto a tener en cuenta es que los campos que %orman la &ri%ary ?ey de una tabla slo se podr$n
modi%icar si los registros no est$n re%erenciados en ninguna otra tabla. ,n nuestro caso slo podremos modi%icar
la matr)cula de un coc&e si no tiene registros asociados en la tabla t-lquileres.
,sto puede causar poblemas, ya que podr)amos &abernos equivocado al dar de alta el coc&e en la tabla
t'oc&es y detectar el error despues de alquilar el coc&e. ,n tal caso tendr)amos dar de alta un nuevo coc&e con
la matr)cula correcta, actuali7ar los registros de la tabla alquileres y por <ltimo borrar el registro erroneo de la
tabla t'oc&es. ,ste proceso puede ser bastante complicado en el caso de que existiran m$s relaciones con la
tabla. Se podr)a considerar que la clave primaria de la tabla esta mal de%inida y que la matr)cula no debe ser el
elemento que identi%ique el coc&e. 8na alternativa seria crear un cdigo autonum6rico para la tabla t'oc&es que
reali7ar$ las veces de clave primaria y crear un )ndice <nico para la matr)cula, este diseCo tambien tiene sus
OpegasO, por lo que debemos decidir que modelo utili7ar, y seleccionar las claves primarias con sumo cuidado.
[arriba]
9so e su6consultas con 9P"AT7
,l uso de subconsultas es una t6cnica avan7ada de consulta que veremos con detalle m$s adelante, pero
que tratamos aqu) de %orma introductoria.
Vasta a&ora &emos actuali7ado los datos con valores que conocemos de antemano, Qpero qu6 ocurre
cuando esos datos deben tomarse de otra tabla de la base de datosR."odr)amos diseCar un programa que
recorriera toda la tabla y buscar$ el valor adecuado para cada registro y lo actuali7ase. Sin duda es una
solucin, y en ocasiones cas) la <nica, pero es una solucin cara y compleja que adem$s exige que
cono7camos alg<n otro lenguaje de programacin. "ara estos casos podemos utili7ar subconsultas con la
sentencia 9P"AT7.
La sintaxis es la siguiente*
UPDATE <nombre%tabla>
SET <campo> 5 <valor> ( <subconsulta>
{&,<campo2> 5 <valor2> ( <subconsulta2>
,222
, <campo.> 5 <valor.> ( <subconsulta.>'}
& W#ERE <condicion>';
'omo puede verse la sintaxis es practicamente igual a la sintaxis del la sentencia 9P"AT7, con la salvedad
de que podemos utili7ar subconsultas en lugar de valores al asignar los campos. De %orma generica podemos
decir que las subconsultas son consultas S7L7$T incluidas dentro de otra sentencia SQL.
Las siguientes sentencias 9P"AT7 son equivalentes*
8tili7ando sentencias 8"D-T, normales*
UPDATE tCoches
SET marca 5 77
W#ERE marca 5 71;9<7;
UPDATE tCoches
SET marca 5 727
W#ERE marca 5 79-.3),/7;
UPDATE tCoches
SET marca 5 7H7
W#ERE marca 5 70-3/7;
8tili7ando sentencias 8"D-T, combinadas con subconsultas*
UPDATE tCoches
SET marca 5 (SELECT C;<*:; !RO" t8arcas
W#ERE t8arcas28arca 5 tCoches28arca )
W#ERE marca IN (71;9<7,79-.3),/7,70-3/7);
"or cada registro de la tabla t'oc&es se ejecutar$ la subconsulta, actuali7ando el campo marca a el valor del
cdigo de la marca en la tabla t5arcas.
,l uso de subconsultas para actuali7ar datos tiene algunas limitaciones*
La subconsulta slo puede devover un <nico campo.
La subconsulta slo puede devolver un slo registro.
,l tipo de datos devuelto por la subconsulta debe ser del mismo tipo que el campo al que estamos
asignando el valor.
/o todos los sistemas de bases de datos permiten usar subconsultas para actuali7ar datos (-ccess!
aunque si una buena parte de ellos (4+-'L,, SQL Server, Sybase ...!
"ero en nuestro ejemplo el campo codigo de la tabla t5arcas es num6rico y el campo marca de la tabla
t'oc&es es texto. Q"or qu6 %uncionaR 5uy %acil, el motor de la base de datos es capa7 de convertir el valor
num6rico a un valor texto de %orma autom$tica, si bien esta es una excepcin.
-&ora que ya tenemos modi%icado el valor de la marca de los registros, es conveniente modi%icar su tipo de
datos y crear una %oreign Ney contra la tabla t5arcas. "ara ello ejecutaremos las siguientes sentencias.
ALT75 TA,L7 t'oc&es
alter colu%n marca int not nullK
La opcion alter column es propia de SQL Server. "ara modi%icar el tipo de datos de una tabla debemos
consultar la ayuda del gestor de bases de datos.
ALT75 TA,L7 t'oc&es
a constraint 9;L'oc&esL5arcas )oreign ?ey (marca!
re)erences t5arcas (codigo!M
Si no recuerda como modi%icar tablas o crear %oreing Ney pulse AQU .
$onsultas co%6inaas. M-INS
$onsultas co%6inaas.
Vabitualmente cuando necesitamos recuperar la in%ormacin de una base de datos nos encontramos con que
dic&a in%ormacin se encuentra repartida en varias tablas, re%erenciadas a trav6s de varios cdigos. De este
modo si tuvieramos una tabla de ventas con un campo cliente, dic&o campo contendr)a el cdigo del cliente de
la tabla de cliente.
Sin embargo est$ %orma de almacenar la in%ormacin no resulta muy util a la &ora de consultar los
datos.SQL nos proporciona una %orma %acil de mostrar la in%ormacin repartida en varias tablas, las consultas
co%6inaas o M-INS.
Las consultas combinadas pueden ser de tres tipos*
'ombinacin interna
'ombinacin externa
8niones
[arriba]
$o%6inaci!n interna.
La combinacin interna nos permite mostrar los datos de dos o m$s tablas a trav6s de una condicin<=757.
Si recordamos los ejemplos de los capitulos anteriores tenemos una tabla de coc&es, en la que tenemos
re%erenciada la marca a trav6s del cdigo de marca. "ara reali7ar la consulta combinada entre estas dos tablas
debemos escribir una consulta S7L7$T en cuya cla<sula *5-# escribiremos el nombre de las dos tablas,
separados por comas, y una condicin <=757 que obligue a que el cdigo de marca de la tabla de coc&es sea
igual al cdigo de la tabla de marcas.
Lo m$s sencillo es ver un ejemplo directamente*
0-,-C/ tCoches2matricula,
t8arcas2marca,
tCoches2modelo,
tCoches2color,
tCoches2numero%Kilometros,
tCoches2num%plaAas
19;8 tCoches, t8arcas
L@-9- tCoches2marca 5 t8arcas2codigo
La misma consulta de %orma OvisualO ...
Demonos cuenta que &emos antepuesto el nombre de cada tabla a el nombre del campo, esto no es
obligatorio si los nombres de campos no se repiten en las tablas, pero es acondajable para evitar con%lictos de
nombres entre campos. "or ejemplo, si para re%erirnos al campo marca no anteponemos el nombre del campo la
base de datos no sabe si queremos el campo marca de la tabla t'oc&es, que contiene el cdigo de la marca, o
el campo marca de la tabla t5arcas, que contiene el nombre de la marca.
4tra opcin es utili7ar la cl$usula INN75 M-IN. Su sintaxis es identica a la de una consulta S7L7$T &abitual,
con la particularidad de que 6n la cl$usula *5-# slo aparece una tabla o vista, aCadiendose el resto de tablas
a trav6s de cl$usulas INN75 M-IN .
SELECT &ALL * DISTINCT '
<nombre_campo> &{,<nombre_campo>}'
!RO" <nombre_tabla>
&{INNER +OIN <nombre_tabla> ON <condicion_combinacion>}]
&W#ERE <condicion> &{ AND(OR <condicion>}''
&,ROUP B$ <nombre_campo> &{,<nombre_campo >}''
&#AVIN, <condicion>&{ AND(OR <condicion>}''
&ORDER B$ <nombre_campo>(<indice%campo> &ASC ( DESC'
&{,<nombre_campo>(<indice%campo> &ASC (
DESC '}''
,l ejemplo anterior escrito utili7ando la clausula INN75 M-IN quedaria de la siguiente manera*
0-,-C/ tCoches2matricula,
t8arcas2marca,
tCoches2modelo,
tCoches2color,
tCoches2numero%Kilometros,
tCoches2num%plaAas
19;8 tCoches
*..-9 I;*. t8arcas ;. tCoches2marca 5 t8arcas2codigo
La cl$usula INN75 M-IN permite separar completamente las condiciones de combinacin con otros criterios,
cuando tenemos consultas que combinan nueve o die7 tablas esto realmente se agradece. Sin embargo muc&os
programadores no son amigos de la cl$usula INN75 M-IN, la ra7n es que uno de los principales gestores de
bases de datos, -5A$L7, no la soportaba. Si nuestro porgrama debia trabajar sobre bases de
datos -5A$L7no podiamos utili7ar INN75 M-IN. A &artir e la version -5A$L7 9i oracle so&orta la
clCusula INN75 M-IN.
[arriba]
$o%6inaci!n 7Fterna
La combinacin interna es excluyente. ,sto quiere decir que si un registro no cumple la condicin de
combinacin no se incluye en los resultados. De este modo en el ejemplo anterior si un coc&e no tiene grabada
la marca no se devuelve en mi consulta.
Seg<n la naturale7a de nuestra consulta esto puede ser una ventaja , pero en otros casos signi%ica un serio
problema. "ara modi%icar este comportamiento SQL pone a nuestra disposicin la combinacin externa. La
combinacin externa no es excluyente.
La sintaxis es muy parecida a la combinacin interna,
SELECT &ALL * DISTINCT '
<nombre_campo> &{,<nombre_campo>}'
!RO" <nombre_tabla>
&{LE!T*RI,#T OUTER +OIN <nombre_tabla> ON
<condicion_combinacion>}]
&W#ERE <condicion> &{ AND(OR <condicion>}''
&,ROUP B$ <nombre_campo> &{,<nombre_campo >}''
&#AVIN, <condicion>&{ AND(OR <condicion>}''
&ORDER B$ <nombre_campo>(<indice%campo> &ASC ( DESC'
&{,<nombre_campo>(<indice%campo> &ASC (
DESC '}''
La combinacin externa puede ser diestra o siniestra, L7*T -9T75 M-IN o 5I;=T -9T75
M-IN. 'on L7*T -9T75 M-IN obtenemos todos los registros de en la tabla que situemos a la i7quierda de la
clausula M-IN,mientras que con 5I;=T -9T75 M-IN obtenmos el e%ecto contrario.
'omo mejor se ve la combinacin externa es con un ejemplo.
0-,-C/ tCoches2matricula,
t8arcas2marca,
tCoches2modelo,
tCoches2color,
tCoches2numero%Kilometros,
tCoches2num%plaAas
19;8 tCoches
LE!T OUTER +OIN t8arcas ;. tCoches2marca 5 t8arcas2codigo
,sta consulta devolver$ todos los registros de la tabla t'oc&es, independientemente de que tengan marca o
no. ,n el caso de que el coc&e no tenga marca se devolver$ el valor null para los campos de la tabla t5arcas.
1isualmente (la consulta devuelve los datos en a7ul! ...

,l mismo ejemplo con +.:VT 48T,+ \4./.
0-,-C/ tCoches2matricula,
t8arcas2marca,
tCoches2modelo,
tCoches2color,
tCoches2numero%Kilometros,
tCoches2num%plaAas
19;8 tCoches
RI,#T OUTER +OIN t8arcas ;. tCoches2marca 5 t8arcas2codigo
,sta consulta devolver$ los registros de la tabla t'oc&es que tengan marca relacionada y todos los registros
de la tabla t5arcas, tengan alg<n registro en t'oc&es o no.
1isualmente (la consulta devuelve los datos en a7ul! ...
[arriba]
9nion
La cl$usula 9NI-N permite unir dos o m$s conjuntos de resultados en uno detras del otro como si se tratase
de una <nica tabla. De este modo podemos obtener los registros de mas de una tabla OunidosO.
La sintaxis corresponde a la de varias S7L7$T unidas a trav6s de 9NI-N, como se muestra a continuacin*
SELECT &ALL * DISTINCT '
<nombre_campo> &{,<nombre_campo>}'
!RO" <nombre_tabla>
&{LE!T*RI,#T OUTER +OIN <nombre_tabla> ON
<condicion_combinacion>}]
&W#ERE <condicion> &{ AND(OR <condicion>}''
&,ROUP B$ <nombre_campo> &{,<nombre_campo >}''
&#AVIN, <condicion>&{ AND(OR <condicion>}''
{
UNION -ALL * DISTINCT .
SELECT &ALL * DISTINCT '
<nombre_campo> &{,<nombre_campo>}'
!RO" <nombre_tabla>
&{LE!T*RI,#T OUTER +OIN <nombre_tabla> ON
<condicion_combinacion>}]
&W#ERE <condicion> &{ AND(OR <condicion>}''
&,ROUP B$ <nombre_campo> &{,<nombre_campo >}''
&#AVIN, <condicion>&{ AND(OR <condicion>}''
}
&ORDER B$ <nombre_campo>(<indice%campo> &ASC ( DESC'
&{,<nombre_campo>(<indice%campo> &ASC (
DESC '}''
"ara utili7ar la clausula 9NI-N debemos cumplir una serie de normas.
Las consultas a unir deben tener el mismo n<mero campos, y adem$s los campos deben ser del
mismo tipo.
Slo puede &aber una <nica clausula -5"75 ,I al %inal de la sentencia S7L7$T.
,l siguiente ejemplo muestra el uso de 9NI-N
0-,-C/ tCoches2matricula,
t8arcas2marca,
tCoches2modelo,
tCoches2color,
tCoches2numero%Kilometros,
tCoches2num%plaAas
19;8 tCoches
INNER +OIN t8arcas ;. tCoches2marca 5 t8arcas2codigo
).*;.
0-,-C/ t8otos2matricula,
t8arcas2marca,
t8otos2modelo,
t8otos2color,
t8otos2numero%Kilometros,
!
19;8 t8otos
INNER +OIN t8arcas ;. t8otos2marca 5 t8arcas2codigo;
"uede observarse el uso de la constante cero en la segunda lista de seleccin para &acer coincidir
el n<mero y tipo de
campos que devuelve la consulta 8/.4/.

$onsultas agregaas
La clCusula ;5-9P ,I
La clausula ;5-9P ,I combina los registros con valores id6nticos en un <nico registro. "ara cada registro
se puede crear un valor agregado si se incluye una %uncin SQL agregada, como por ejemplo Sum o 'ount, en
la instruccin S7L7$T. Su sintaxis es*
SELECT &ALL * DISTINCT '
<nombre_campo> &{,<nombre_campo>}'
&{,<funcion_agregado>}'
!RO" <nombre_tabla>(<nombre_vista>
&{,<nombre_tabla>(<nombre_vista>}'
&W#ERE <condicion> &{ AND(OR <condicion>}''
&,ROUP B$ <nombre_campo> &{,<nombre_campo >}''
&#AVIN, <condicion>&{ AND(OR <condicion>}''
&ORDER B$ <nombre_campo>(<indice%campo> &ASC ( DESC'
&{,<nombre_campo>(<indice%campo> &ASC ( DESC '}''
;5-9P ,I es opcional. Si se utili7a ;5-9P ,I pero no existe una %uncin SQL agregada en la
instruccinS7L7$T se obtiene el mismo resultado que con una consulta S7L7$T "ISTIN$T. Los valores /ull
en los campos;5-9P ,I se agrupan y no se omiten. /o obstante, los valores /ull no se eval<an en ninguna
de las %unciones SQL agregadas.
Todos los campos de la lista de campos de S7L7$T deben incluirse en la cl$usula ;5-9P ,I o como
argumentos de una %uncin SQL agregada.
SELECT marca, modelo, SU"(numero%Kilometros)
!RO" tCoches
,ROUP B$ marca, modelo
La clCusula =A:IN;
8na ve7 que ;5-9P ,I &a combinado los registros, =A:IN; muestra cualquier registro agrupado por la
cl$usula ;5-9P ,I que satis%aga las condiciones de la cl$usula =A:IN;. Se utili7a la cl$usula <=757 para
excluir aquellas %ilas que no desea agrupar, y la cl$usula =A:IN; para %iltrar los registros una ve7 agrupados.
=A:IN; es similar a <=757, determina qu6 registros se seleccionan. 8na ve7 que los registros se &an
agrupado utili7ando ;5-9P ,I, =A:IN; determina cuales de ellos se van a mostrar. =A:IN; permite el uso
de %unciones agregadas.
SELECT marca, modelo, SU"(numero%Kilometros)
!RO" tCoches
W#ERE marca <> 7M8L7
,ROUP B$ marca, modelo
#AVIN, SU"(numero%Kilometros)>!!!!!
,n el ejemplo anterior, no se cuentan los datos para todas las marcas menos O(52O, una ve7 que se &an
contado, se evalua =A:IN;, y el conjunto de resultados devuelve solo aquellos modelos con m$s de >DD.DDD
Nm.
A:;
'alcula la media aritm6tica de un conjunto de valores contenidos en un campo especi%icado de una consulta.
Su sintaxis es la siguiente
AV,(<expr>)

,n donde expr representa el campo que contiene los datos num6ricos para los que se desea calcular la media
o una expresin que reali7a un c$lculo utili7ando los datos de dic&o campo. La media calculada por -vg es la
media aritm6tica (la suma de los valores dividido por el n<mero de valores!. La %uncin -vg no incluye ning<n
campo /ull en el c$lculo.
SELECT marca, modelo, AV,(numero%Kilometros)
!RO" tCoches
,ROUP B$ marca, modelo


$ount
'alcula el n<mero de registros devueltos por una consulta. Su sintaxis es la siguiente*
COUNT(<expr>)
,n donde expr contiene el nombre del campo que desea contar. Los operandos de expr pueden incluir el
nombre de un campo de una tabla, una constante o una %uncin (la cual puede ser intr)nseca o de%inida por el
usuario pero no otras de las %unciones agregadas de SQL!. "uede contar cualquier tipo de datos incluso texto.
-unque expr puede reali7ar un c$lculo sobre un campo, 'ount simplemente cuenta el n<mero de registros sin
tener en cuenta qu6 valores se almacenan en los registros. La %uncin 'ount no cuenta los registros que tienen
campos null a menos que expr sea el car$cter comod)n asterisco (U!. Si utili7a un asterisco, 'ount calcula el
n<mero total de registros, incluyendo aquellos que contienen campos null. 'ount(U! es considerablemente m$s
r$pida que 'ount('ampo!. /o se debe poner el asterisco entre dobles comillas (YUY!.
SELECT COUNT(N) !RO" tCoches;
SELECT marca, COUNT(modelo)
!RO" tCoches
,ROUP B$ marca;
SELECT marca, COUNT(DISTINCT modelo)
!RO" tCoches
,ROUP B$ marca;

#aF, #in
Devuelven el m)nimo o el m$ximo de un conjunto de valores contenidos en un campo especi%ico de una
consulta. Su sintaxis es*
"IN(<expr>)
"AX(<expr>)
,n donde expr es el campo sobre el que se desea reali7ar el c$lculo. ,xpr pueden incluir el nombre de un
campo de una tabla, una constante o una %uncin (la cual puede ser intr)nseca o de%inida por el usuario pero no
otras de las %unciones agregadas de SQL!.
SELECT marca, modelo, "IN(numero%Kilometros)
, "AX(numero%Kilometros)
!RO" tCoches
,ROUP B$ marca, modelo
Su%
Devuelve la suma del conjunto de valores contenido en un campo especi%ico de una consulta. Su sintaxis es*
SU"(<expr>)
,n donde expr respresenta el nombre del campo que contiene los datos que desean sumarse o una
expresin que reali7a un c$lculo utili7ando los datos de dic&os campos. Los operandos de expr pueden incluir el
nombre de un campo de una tabla, una constante o una %uncin (la cual puede ser intr)nseca o de%inida por el
usuario pero no otras de las %unciones agregadas de SQL!.
SELECT marca, modelo, SU"(numero%Kilometros)
!RO" tCoches
,ROUP B$ marca, modelo

PL SQL
SQL es un lenguaje de consulta para los sistemas de bases de datos relacinales, pero que
no posee la potencia de los lenguajes de programacin.
"ara abordar el presente tutorial con m)nimo de garantias es necesario conocer previamente
SQL.
"odemos acceder a un completo tutorial de SQL desde -Q8..
"L#SQL amplia SQL con los elementos caracteristicos de los lenguajes de programacin,
variables, sentencias de control de %lujo, bucles ...
'uando se desea reali7ar una aplicacin completa para el manejo de una base de datos
relacional, resulta necesario utili7ar alguna &erramienta que soporte la capacidad de consulta
del SQL y la versatilidad de los lenguajes de programacin tradicionales. "L#SQL es el lenguaje
de programacin que proporciona -racle para extender el SQL est$ndar con otro tipo de
instrucciones.
QQue vamos a necesitarR
"ara poder seguir este tutorial correctamente necesitaremos tener los siguientes elementos*
8na instancia de 4+-'L, ?i o superior %uncionando correctamente.
Verramientas cliente de 4+-'L,, en particular SQLU"lus para poder ejecutar los
ejemplo.
Vaber con%igurado correctamente una conexin a 4+-'L,.
"rogramacin con "L#SQL
.ntroduccin
SQL es un lenguaje de consulta para los sistemas de bases de datos relacinales, pero que
no posee la potencia de los lenguajes de programacin. /o permite el uso de
variables, estructuras de control de %lujo, bucles ... y dem$s elementos caracteristicos de la
programacin. /o es de extraCar, SQL es un lengua'e e consulta, no un lengua'e e
&rogra%aci!n.
Sin embargo, SQL es la &erramienta ideal para trabajar con bases de datos. 'uando se
desea reali7ar una aplicacin completa para el manejo de una base de datos relacional, resulta
necesario utili7ar alguna &erramienta que soporte la capacidad de consulta del SQL y la
versatilidad de los lenguajes de programacin tradicionales. "L#SQL es el lenguaje de
programacin que proporciona 4racle para extender el SQL est$ndar con otro tipo de
instrucciones y elementos propios de los lenguajes de programacin .
'on "L#SQL vamos a poder programar las unidades de programa de la base de datos
4+-'L,, est$n son*
"rocedimientos almacenados
9unciones
Triggers
Scripts
"ero adem$s "L#SQL nos permite reali7ar programas sobre las siguientes &erramientas de
4+-'L,*
4racle 9orms
4racle +eports
4racle :rap&ics
4racle -plication Server
*una%entos e PL/SQL
Pri%eros &asos con PL/SQL
"ara programar en "L#SQL es necesario conocer sus %undamentos.
'omo introduccin vamos a ver algunos elementos y conceptos b$sicos del lenguaje.
"L#SQL no es '-S,S,/S.T.1,, es decir, no di%erencia may<sculas de min<sculas
como otros lenguajes de programacin como ' o \ava. Sin e%6argo e6e%os
recorar Due -5A$L7 es $AS7-S7NSITI:7 en la 6(sDueas e teFto.
8na linea en "L#SQL contiene grupos de caracteres conocidos como 8/.D-D,S
L,0.'-S, que pueden ser clasi%icadas como*
o D,L.5.T-D4+,S
o .D,/T.9.'-D4+,S
o L.T,+-L,S
o '45,/T-+.4S
o ,0"+,S.4/,S
D,L.5.T-D4+* ,s un s)mbolo simple o compuesto que tiene una %uncin especial en
"L#SQL. ,stos pueden ser*
o 4peradores -ritmeticos
o 4peradores Logicos
o 4peradores +elacionales
.D,/T.9.'-D4+* Son empleados para nombrar objetos de programas en "L#SQL asi
como a unidades dentro del mismo, estas unidades y objetos incluyen*
o 'onstantes
o 'ursores
o 1ariables
o Subprogramas
o ,xcepciones
o "aquetes
L.T,+-L* ,s un valor de tipo num6rico, caracter, cadena o lgico no representado por
un identi%icador (es un valor expl)cito!.
'45,/T-+.4* ,s una aclaracin que el programador incluye en el cdigo. Son
soportados B estilos de comentarios, el de l)nea simple y de multil)nea, para lo cual son
empleados ciertos caracters especiales como son*
Linea simple
#U
'onjunto de Lineas
U#
Tipos de datos en "L#SQL
'ada constante y variable tien un tipo de dato en el cual se especi%ica el %ormato de
almacenamiento, restricciones y rango de valores validos.
"L#SQL proporciona una variedad prede%inida de tipos de datos . 'asi todos los tipos de
datos manejados por "L#SQL son similares a los soportados por SQL. - continuacin se
muestran los T."4S de D-T4S m$s comunes*
N9#,75 (Numrico!* -lmacena n<meros enteros o de punto %lotante, virtualmente de
cualquier longitud, aunque puede ser especi%icada la precisin (/<mero de digitos! y la
escala que es la que determina el n<mero de decimales.
/85(,+ G(precision, escala!H
saldo N9#,75(>[,B!M
#U .ndica que puede almacenar un valor num6rico de >[
posiciones, B de ellas decimales. ,s decir, >= enteros
y dos decimales U#
$=A5 (Caracter!* -lmacena datos de tipo caracter con una longitud maxima de PBA[A
y cuyo valor de longitud por de%ault es >
'V-+ G(longitudLmaxima!H
nombre $=A5(BD!M
#U .ndica que puede almacenar valores al%anum6ricos de BD
posiciones U#
:A5$=A52 (Caracter de longitud variable!* -lmacena datos de tipo caracter
empleando slo la cantidad necesaria a<n cuando la longitud m$xima sea mayor.
1-+'V-+B (longitudLmaxima!
nombre :A5$=A52(BD!M
#U .ndica que puede almacenar valores al%anum6ricos de &asta BD
posicones U#
#U 'uando la longitud de los datos sea menor de BD no se
rellena con blancos U#
,--L7AN (lgico!* Se emplea para almacenar valores T+8, o 9-LS,.
&ayLerror ,--L7ANM
"AT7 (Fecha!* -lmacena datos de tipo %ec&a. Las %ec&as se almacenan internamente
como datos num6ricos, por lo que es posible reali7ar operaciones aritmeticas con ellas.
-tributos de tipo. 8n atributo de tipo "L#SQL es un modi%icador que puede ser usado
para obtener in%ormacin de un objeto de la base de datos. ,l atributoNTIP7 permite
conocer el tipo de una variable, constante o campo de la base de datos. ,l
atributo N5-<TIP7 permite obtener los tipos de todos los campos de una tabla de la
base de datos, de una vista o de un cursor.
"L#SQL tambi6n permite la creacin de tipos personali7ados (registros! y
colecciones(tablas de "L#SQL!, que veremos en sus apartados correspondientes.
,xisten por supuesto m$s tipos de datos, la siguiente tabla los muestra*
Ti&o e
ato /
SintCFis
-racle Oi -racle 9i "escri&ci!n
ec(&, e)
La precisin m$xima es de
P? d)gitos.
La precisin m$xima es de
P? d)gitos.
Donde & es la precisin
y e la escala.
Por e'e%&loAdec(P,>!
es un n<mero que tiene
B d)gitos antes del
decimal y un d)gito
despu6s del decimal.
eci%al(&,
e)
La precisin m$xima es de
P? d)gitos.
La precisin m$xima es de
P? d)gitos.
Donde & es la precisin
y e la escala.
Por
e'e%&loAdecimal(P,>!
es un n<mero que tiene
B d)gitos antes del
decimal y un d)gito
despu6s del decimal.
ou6le
&recision
)loat
int
integer
nu%eric(&,
e)
La precisin m$xima es de
P? d)gitos.
La precisin m$xima es de
P? d)gitos.
Donde & es la precisin
y e la escala.
Por
e'e%&loAnumeric(A,B!
es un n<mero que tiene
@ d)gitos antes del
decimal y B d)gitos
despu6s del decimal.
nu%6er(&,
e)
La precisin m$xima es de
P? d)gitos.
La precisin m$xima es de
P? d)gitos.
Donde & es la precisin
y e la escala.
Por
e'e%&loAnumber(A,B!
es un n<mero que tiene
@ d)gitos antes del
decimal y B d)gitos
despu6s del decimal.
real
s%allint
c+ar
(ta%aEo)
Vasta PBA[A bytes en
"LSQL.
Vasta BDDD bytes en
4racle ?i.
Vasta PBA[A bytes en
"LSQL.
Vasta BDDD bytes en
4racle ]i.
Donde ta%aEo es el
n<mero de caracteres a
almacenar. Son
cadenas de anc&o %ijo.
Se rellena con
espacios.
varc+ar2
(ta%aEo)
Vasta PBA[A bytes en
"LSQL.
Vasta =DDD bytes en
4racle ?i.
Vasta PBA[A bytes en
"LSQL.
Vasta =DDD bytes en
4racle ]i.
Donde ta%aEo es el
n<mero de caracteres a
almacenar. Son
cadenas de anc&o
variable.
long Vasta B gigabytes. Vasta B gigabytes.
Son cadenas de anc&o
variable.
raP
Vasta PBA[A bytes en
"LSQL.
Vasta BDDD bytes en
4racle ?i.
Vasta PBA[A bytes en
"LSQL.
Vasta BDDD bytes en
4racle ]i.
Son cadenas binarias
de anc&o variable.
long raP Vasta B gigabytes. Vasta B gigabytes.
Son cadenas binarias
de anc&o variable.
ate
8na %ec&a entre el > de
,nero de =A>B -.'. y el P>
de Diciembre de ]]]] D.'.
8na %ec&a entre el > de
,nero de =A>B -.'. y el P>
de Diciembre de ]]]] D.'.
ti%esta%&
(fractional
seconds
precision)
/o soportado por 4racle ?i.
)ractional secons
&recision debe ser un
n<mero entre D y ]. (,l
valor por de%ecto es [!
.ncluye aCo, mes d)a,
&ora, minutos y
segundos.
Por
e'e%&loAtimestamp([!
ti%esta%&
(fractional
seconds
precision)
Pit+ ti%e
Bone
/o soportado por 4racle ?i.
)ractional secons
&recision debe ser un
n<mero entre D y ]. (,l
valor por de%ecto es [!
.ncluye aCo, mes d)a,
&ora, minutos y
segundosM con un valor
de despla7amiento de
7ona &oraria.
Por
e'e%&loAtimestamp(@!
Zit& time 7one
ti%esta%&
(fractional
seconds
precision)
/o soportado por 4racle ?i. )ractional secons
&recision debe ser un
n<mero entre D y ]. (,l
valor por de%ecto es [!
.ncluye aCo, mes d)a,
&ora, minutos y
segundosM con una
7ona &oraria expresada
Pit+ local
ti%e Bone
como la 7ona &oraria
actual.
Por
e'e%&loAtimestamp(=!
Zit& local time 7one
interval
year (year
precision)
to %ont+
/o soportado por 4racle ?i.
year &recision debe ser un
n<mero entre D y ]. (,l
valor por de%ecto es B!
"er)odo de tiempo
almacenado en aCos y
meses.
Por e'e%&loA interval
year(=! to mont&
interval
ay (day
precision)
to secon
(fractional
seconds
precision)
/o soportado por 4racle ?i.
ay &recision debe ser un
n<mero entre D y ]. (,l
valor por de%ecto es B!
)ractional secons
&recision debe ser un
n<mero entre D y ]. (,l
valor por de%ecto es [!
.ncluye aCo, mes d)a,
&ora, minutos y
segundos.
Por e'e%&loA interval
day(B! to second([!
roPi
,l %ormato del campo roZid
es*
(((((((.++++.99999
donde ((((((( es el
bloque en el %ic&ero de la
base de datosM ++++ es la
%ila del bloqueM 99999 es el
%ic&ero de la base de datos.
,l %ormato del campo roZid
es*
(((((((.++++.99999
donde ((((((( es el
bloque en el %ic&ero de la
base de datosM ++++ es la
%ila del bloqueM 99999 es el
%ic&ero de la base de datos.
Datos binarios de
anc&o %ijo. 'ada
registro de la base de
datos tiene una
direccin %)sica o roZid.
uroPi
Qta%aEoR
Vasta BDDD bytes. Vasta BDDD bytes.
+oZid universal.
Donde ta%aEo es
opcional.
6oolean
1$lido en "LSQL, este tipo
de datos no existe en
4racle ?i.
1$lido en "LSQL, este tipo
de datos no existe en
4racle ]i.
nc+ar
(ta%aEo)
Vasta PBA[A bytes en
"LSQL. Vasta BDDD bytes
en 4racle ?i.
Vasta PBA[A bytes en
"LSQL. Vasta BDDD bytes
en 4racle ]i.
Donde ta%aEo es el
n<mero de caracteres a
almacenar. 'adena
/LS de anc&o %ijo.
nvarc+ar2
(ta%aEo)
Vasta PBA[A bytes en
"LSQL. Vasta =DDD bytes
en 4racle ?i.
Vasta PBA[A bytes en
"LSQL. Vasta =DDD bytes
en 4racle ]i.
Donde ta%aEo es el
n<mero de caracteres a
almacenar. 'adena
/LS de anc&o variable.
6)ile Vasta = gigabytes. Vasta = gigabytes.
Locali7adores de
arc&ivo apuntan a un
objeto binario de slo
lectura %uera de la base
de datos.
6lo6 Vasta = gigabytes. Vasta = gigabytes.
Locali7adores L4(
apuntan a un gran
objeto binario dentro de
la base de datos.
clo6 Vasta = gigabytes. Vasta = gigabytes.
Locali7adores L4(
apuntan a un gran
objeto de caracteres
dentro de la base de
datos.
nclo6 Vasta = gigabytes. Vasta = gigabytes. Locali7adores L4(
apuntan a un gran
objeto /LS de
caracteres dentro de la
base de datos.
-&eraores en PL/SQL
La siguiente tabla ilustra los operadores de "L#SQL.
Ti&o e o&eraor -&eraores
-&eraor e
asignaci!n
*X (dos puntos ^ igual!
-&eraores
arit%Hticos
^ (suma!
(resta!
U (multiplicacin!
# (divisin!
UU (exponente!
-&eraores
relacionales o e
co%&araci!n
X (igual a!
EF (distinto de!
E (menor que!
F (mayor que!
FX (mayor o igual a!
EX (menor o igual a!
-&eraores l!gicos -/D (y lgico!
/4T (negacion!
4+ (o lgico!
-&eraor e
concatenaci!n
KK
7structuras e control en PL/SQL
7strcuturas e control e )lu'o
,n "L#SQL solo disponemos de la estructura condicional .9. Su sintaxis se muestra a
continuacin*
I* (expresion! T=7N
.nstrucciones
7LSI* (expresion! T=7N
.nstrucciones
7LS7
.nstrucciones
7N" I*M
8n aspecto a tener en cuenta es que la instruccin condicional anidada es ELSIF y
no "!"E#F"$
Sentencia ;-T-
"L#SQL dispone de la sentencia :4T4. La sentencia :4T4 desvia el %lujo de ejecuci a una
determinada etiqueta.
,n "L#SQL las etiquetas se indican del siguiente modo* EE eti%ueta FF
,l siguiente ejemplo ilustra el uso de :4T4.
"7$LA57
%lag N9#,75M
,7;IN
%lag *X> M
I* (%lag X >! T=7N
;-T- pasoBM
7N" I*M
EEpaso>FF
dbmsLoutput.putLline(Y,jecucion de paso >Y!M
EEpasoBFF
dbmsLoutput.putLline(Y,jecucion de paso BY!M
7N"M
,ucles
,n "L#SQL tenemos a nuestra disposicin los siguientes iteradores o bucles*
L44"
2V.L,
94+
,l bucle L--P, se repite tantas veces como sea necesario &asta que se %uer7a su salida con
la instruccin78IT. Su sintaxis es la siguiente
L--P
.nstrucciones
I* (expresion! T=7N
.nstrucciones
78ITM
7N" I*M
7N" L--PM
,l bucle <=IL7, se repite mientras que se cumpla expresion.
<=IL7 (expresion! L--P
.nstrucciones
7N" L--PM
,l bucle *-5, se repite tanta veces como le indiquemos en los identi%icadores inicio y final$
*-5 contador IN G57:75S7H inicio..%inal L--P
.nstrucciones

7N" L--PM
,n el caso de especi%icar 57:75S7 el bucle se recorre en sentido inverso.
,loDues PL/SQL
8n programa de "L#SQL est$ compuesto por bloques. 8n programa est$ compuesto como
m)nimo de un bloque.
Los bloques de "L#SQL pueden ser de los siguientes tipos*
(loques annimos
Subprogramas
7structura e un ,loDue
Los bloques "L#SQL presentan una estructura espec)%ica compuesta de tres partes bien
di%erenciadas*
La seccin declarativa en donde se declaran todas las constantes y variables que se
van a utili7ar en la ejecucin del bloque.
La seccin de ejecucin que incluye las instrucciones a ejecutar en el bloque "L#SQL.
La seccin de excepciones en donde se de%inen los manejadores de errores que
soportar$ el bloque "L#SQL.
'ada una de las partes anteriores se delimita por una palabra reservada, de modo que un
bloque "L#SQL se puede representar como sigue*

Q eclare J is J as R
#U"arte declarativaU#
6egin
#U"arte de ejecucionU#
Q eFce&tion R
#U"arte de excepcionesU#
enK
De las anteriores partes, <nicamente la seccin de ejecucin es obligatoria, que quedar)a
delimitada entre las cl$usulas ,7;IN y 7N". 1eamos un ejemplo de bloque "L#SQL muy
gen6rico. Se trata de un bloque annimos, es decir no lo identi%ica ning<n nombre. Los bloques
annimos identi%ican su parte declarativa con la palabra reservada "7$LA57.
"7$LA57
#U"arte declarativaU#
nombreLvariable "AT7M
,7;IN
#U"arte de ejecucion
U ,ste cdigo asigna el valor de la columna OnombreLcolumnaO
U a la variable identi%icada por OnombreLvariableO
U#
S7L7$T S3SD-T,
INT- nombreLvariable
*5-# D8-LM
78$7PTI-N
#U"arte de excepcionesU#
<=7N -T=75S T=7N
6%sGout&ut.&utGline(SSe +a &roucio un errorS)M
7N"K
- continuacin vamos a ver cada una de estas secciones
Secci!n e "eclaraci!n e :aria6les
,n esta parte se declaran las variables que va a necesitar nuestro programa. 8na variable se
declara asignandole un nombre o Oidenti%icadorO seguido del tipo de valor que puede contener.
Tambi6n se declaran cursores, de gran utilidad para la consulta de datos, y excepciones
de%inidas por el usuario. Tambi6n podemos especi%icar si se trata de una constante, si puede
contener valor nulo y asignar un valor inicial.
La sintaxis generica para la declaracion de constantes y variables es*
nombreLvariable G$-NSTANTH &tipo_dato' GN-T N9LLHG*XvalorLinicialH
donde*
tipoLdato* es el tipo de dato que va a poder almacenar la variable, este puede ser
cualquiera de los tipos soportandos por 4+-'L,, es
decir N9#,75 , "AT7 , $=A5 , :A5$=A5, :A5$=A52, ,--L7AN ... -dem$s para
algunos tipos de datos (/85(,+ y 1-+'V-+! podemos especi%icar la longitud.
La cl$usula '4/ST-/T indica la de%inicin de una constante cuyo valor no puede ser
modi%icado. Se debe incluir la iniciali7acin de la constante en su declaracin.
La cl$usula /4T /8LL impide que a una variable se le asigne el valor nulo, y por tanto
debe iniciali7arse a un valor di%erente de /8LL.
Las variables que no son iniciali7adas toman el valor inicial /8LL.
La iniciali7acin puede incluir cualquier expresin legal de "L#SQL, que lgicamente
debe corresponder con el tipo del identi%icador de%inido.
Los tipos escalares incluyen los de%inidos en SQL m$s los tipos 1-+'V-+ y
(44L,-/. ,ste <ltimo puede tomar los valores T+8,, 9-LS, y /8LL, y se suele utili7ar para
almacenar el resultado de alguna operacin lgica. 1-+'V-+ es un sinnimo de 'V-+.
Tambi6n es posible de%inir el tipo de una variable o constante, dependiendo del tipo de
otro identi%icador, mediante la utili7acin de las cl$usulas NTIP7 y N5-<TIP7. 5ediante la
primera opcin se de%ine una variable o constante escalar, y con la segunda se de%ine una
variable %ila, donde identi%icador puede ser otra variable %ila o una tabla. Vabitualmente se
utili7a NTIP7 para de%inir la variable del mismo tipo que tenga de%inido un campo en una tabla
de la base de datos, mientras que N5-<TIP7 se utili7a para declarar varibales utili7ando
cursores.
,jemplos*
,structura de un bloque annimo.

"7$LA57
#U Se declara la variable de tipo 1-+'V-+B(>@! identi%icada por vLlocation
y se le asigna
el valor O:ranadaOU#
vLlocation :A5$=A52(>@! *X _:ranada_M
#USe declara la constante de tipo /85(,+ identi%icada por ". y se le
asigna
el valor P.>=>[U#
". $-NSTANT N9#,75 *X P.>=>[M
#USe declara la variable del mismo tipo que tenga el campo nombre de la
tabla tablaLempleados
identi%icada por vLnombre y no se le asigna ning<n valor U#
vLnombre tablaLempleados.nombreNTIP7M
#USe declara la variable del tipo registro correspondiente a un supuesto
cursor, llamado
micursor, identi%icada por regLdatosU#
regLdatos micursorN5-<TIP7M
,7;IN
#U"arte de ejecucionU#
78$7PTI-N
#U"arte de excepcionesU#
7N"K
,structura de un subprograma*

$57AT7 P5-$7"957 si%&leG&roceure IS
#U Se declara la variable de tipo 1-+'V-+B(>@! identi%icada por vLlocation
y se le asigna
el valor O:ranadaOU#
vLlocation :A5$=A52(>@! *X _:ranada_M
#USe declara la constante de tipo /85(,+ identi%icada por ". y se le
asigna
el valor P.>=>[U#
". $-NSTANT N9#,75 *X P.>=>[M
#USe declara la variable del mismo tipo que tenga el campo nombre de la
tabla tablaLempleados
identi%icada por vLnombre y no se le asigna ning<n valor U#
vLnombre tablaLempleados.nombreNTIP7M
#USe declara la variable del tipo registro correspondiente a un supuesto
cursor, llamado
micursor, identi%icada por regLdatosU#
regLdatos micursorN5-<TIP7M
,7;IN
#U"arte de ejecucionU#
78$7PTI-N
#U"arte de excepcionesU#
7N"K

$ursores en PL/SQL
Introucci!n a cursores PL/SQL
"L#SQL utili7a cursores para gestionar las instrucciones S7L7$T. 8n cursor es un conjunto
de registros devuelto por una instruccin SQL. T6cnicamente los cursores son %ragmentos de
memoria que reservados para procesar los resultados de una consulta S7L7$T.
"odemos distinguir dos tipos de cursores*
$ursores i%&licitos. ,ste tipo de cursores se utili7a para operaciones S7L7$T
INT-. Se usan cuando la consulta devuelve un <nico registro.
$ursores eF&licitos. Son los cursores que son declarados y controlados por el
programador. Se utili7an cuando la consulta devuelve un conjunto de registros. 4casionalmente
tambi6n se utili7an en consultas que devuelven un <nico registro por ra7ones de e%iciencia. Son
m$s r$pidos.
8n cursor se de%ine como cualquier otra variable de "L#SQL y debe nombrarse de acuerdo a
los mismos convenios que cualquier otra variable. Los cursores implicitos no necesitan
declaracin.
,l siguiente ejemplo declara un cursor explicito*
eclare
cursor cLpaises is
S7L7$T '4L"-.S, D,S'+."'.4/
*5-# "-.S,SM
6egin
() "entencias del blo%ue $$$)(
enM
"ara procesar instrucciones S,L,'T que devuelvan m$s de una %ila, son necesarios
cursores explicitos combinados con un estructura de bloque.
8n cursor admite el uso de par$metros. Los par$metros deben declararse junto con el cursor.
,l siguiente ejemplo muestra la declaracion de un cursor con un par$metro, identi%icado por
pLcontinente.
eclare
cursor cLpaises (pLcontinente IN :A5$=A52! is
S7L7$T '4L"-.S, D,S'+."'.4/
*5-# "-.S,S
<=757 '4/T./,/T, X pLcontinenteM
6egin
() "entencias del blo%ue $$$)(
enM
,l siguiente diagrama representa como se procesa una instruccin SQL a trav6s de un
cursor.

9ases para procesar una instruccin SQL
$ursores I%&licitos
"eclaraci!n e cursores i%&licitos.
Los cursores implicitos se utili7an para reali7ar consultas S7L7$T que devuelven un <nico
registro.
Deben tenerse en cuenta los siguientes puntos cuando se utili7an cursores implicitos*
'on cada cursor implicito debe existir la palabra clave INT-.
Las variables que reciben los datos devueltos por el cursor tienen que contener el
mismo tipo de dato que las columnas de la tabla.
Los cursores implicitos solo pueden devolver una <nica %ila. ,n caso de que se
devuelva m$s de una %ila (o ninguna %ila! se producir$ una excepcion. /o se preocupe si a<n no
sabe que es una excepcion, le valdr$ conocer que es el medio por el que "L#SQL gestiona los
errores.
,l siguiente ejemplo muestra un cursor implicito*
eclare
vdescripcion :A5$=A52(@D!M
6egin
S7L7$T D,S'+."'.4/
INT- vdescripcion
)ro% "-.S,S
<=757 '4L"-.S X Y,S"YM

dbmsLoutput.putLline(YLa lectura del cursor es* Y KK vdescripcion!M
enM
La salida del programa generar)a la siguiente l)nea*
La lectura del cursor es* ,S"-`-
7Fce&ciones asociaas a los cursores i%&licitos.
Los cursores implicitos slo pueden devolver una %ila, por lo que pueden producirse
determinadas excepciones. Las m$s comunes que se pueden encontrar
son noGataG)oun y tooG%anyGroPs. La siguiente tabla explica brevemente estas
excepciones.
7Fce&cion 7F&licacion
N-G"ATAG*-9N" Se produce cuando una sentencia S,L,'T intenta recuperar
datos pero ninguna %ila satis%ace sus condiciones. ,s decir,
cuando "no ha* datos"
T--G#ANIG5-<S Dado que cada cursor implicito slo es capa7 de recuperar una
%ila , esta excepcion detecta la existencia de m$s de una %ila.
$ursores 7F&licitos en PL/SQL
"eclaraci!n e cursores eF&licitos
Los cursores explicitos se emplean para reali7ar consultas S7L7$T que pueden devolver
cero %ilas, o m$s de una %ila.
"ara trabajar con un cursor explicito necesitamos reali7ar las siguientes tareas*
Declarar el cursor.
-brir el cursor con la instruccin -P7N.
Leer los datos del cursor con la instruccin *7T$=.
'errar el cursor y liberar los recursos con la instruccin $L-S7.
"ara declarar un cursor debemos emplear la siguiente sintaxis*
$95S-5 nombre_cursor IS
instruccin_"!C+
Tambi6n debemos declarar los posibles parametros que requiera el cursor*
$95S-5 nombre_cursor(param, tipo,- $$$- paramN tipoN) IS
instruccin_"!C+
"ara abrir el cursor
-P7N nombre_cursor.
o bien (en el caso de un cursor con par$metros!
-P7N nombre_cursor(valor,- valor/- $$$- valorN).
"ara recuperar los datos en variables "L#SQL.

*7T$= no%6reGcursor INT- listaLvariablesM
o bien ...
*7T$= no%6reGcursor INT- registroL"L#SQLM
"ara cerrar el cursor*
$L-S7 no%6reGcursorM
,l siguiente ejemplo ilustra el trabajo con un cursor explicito. Vay que tener en cuenta que al
leer los datos del cursor debemos &acerlo sobre variables del mismo tipo de datos de la tabla (o
tablas! que trata el cursor.
"7$LA57
$95S-5 cpaises
IS
S7L7$T '4L"-.S, D,S'+."'.4/, '4/T./,/T,
*5-# "-.S,SM

coLpais :A5$=A52(P!M
descripcion :A5$=A52(@D!M
continente :A5$=A52(B@!M
,7;IN
-P7N cpaisesM
*7T$= cpaises INT- coLpais,descripcion,continenteM
$L-S7 cpaisesM
7N"M
"odemos simpli%icar el ejemplo utili7ando el atributo de tipo N 5-<TIP7 sobre el cursor.
"7$LA57
$95S-5 cpaises
IS
S7L7$T '4L"-.S, D,S'+."'.4/, '4/T./,/T,
*5-# "-.S,SM

registro cpaisesa5-<TIP7M
,7;IN
-P7N cpaisesM
*7T$= cpaises INT- registroM
$L-S7 cpaisesM
7N"M
,l mismo ejemplo, pero utili7ando par$metros*
"7$LA57
$95S-5 cpaises (pLcontinente :A5$=A52!
IS
S7L7$T '4L"-.S, D,S'+."'.4/, '4/T./,/T,
*5-# "-.S,S
<=757 '4/T./,/T, X pLcontinenteM

registro cpaisesa5-<TIP7M
,7;IN
-P7N cpaises(Y,8+4"-Y!M
*7T$= cpaises INT- registroM
$L-S7 cpaisesM
7N"M
'uando trabajamos con cursores debemos considerar*
'uando un cursor est$ cerrado, no se puede leer.
'uando leemos un cursor debemos comprobar el resultado de la lectura utili7ando los
atributos de los cursores.
'uando se cierra el cursor, es ilegal tratar de usarlo.
,s ilegal tratar de cerrar un cursor que ya est$ cerrado o no &a sido abierto
Atri6utos e cursores

Toman los valores T+8,, 9-LS, o /8LL dependiendo de la situacin*

Atri6uto
Antes e
a6rir
Al
a6rir
"urante la
recu&eraci!n
Al )inaliBar la
recu&eraci!n
"es&uHs e
cerrar
NN-T*-9
N"
4+->DD> /8LL 9-LS, T+8, 4+->DD>
N*-9N" 4+->DD> /8LL T+8, 9-LS, 4+->DD>
NIS-P7N 9-LS, T+8, T+8, T+8, 9-LS,
N5-<$-9
NT
4+->DD> D U UU 4+->DD>

U /<mero de registros que &a recuperado &asta el momento
UU /<mero de total de registros
#ane'o el cursor
"or medio de ciclo L44" podemos iterar a trav6s del cursor. Debe tenerse cuidado de
agregar una condicin para salir del bucle*
1amos a ver varias %ormas de iterar a trav6s de un cursor. La primera es utili7ando un bucle
L44" con una sentencia ,0.T condicionada*

-P7N nombreLcursorM
L--P
*7T$= nombreLcursor INT- listaLvariablesM
78IT <=7N nombreLcursoraN-T*-9N"M
#U "rocesamiento de los registros recuperados U#
7N" L--PM
$L-S7 nombreLcursorM
-plicada a nuestro ejemplo anterior*
"7$LA57
$95S-5 cpaises
IS
S7L7$T '4L"-.S, D,S'+."'.4/, '4/T./,/T,
*5-# "-.S,SM

coLpais :A5$=A52(P!M
descripcion :A5$=A52(@D!M
continente :A5$=A52(B@!M
,7;IN
-P7N cpaisesM
L--P
*7T$= cpaises INT- coLpais,descripcion,continenteM
78IT <=7N cpaisesaN-T*-9N"M
dbmsLoutput.putLline(descripcion!M
7N" L--PM
$L-S7 cpaisesM
7N"M

4tra %orma es por medio de un bucle 2V.L, L44". La instruccin 9,'TV aparece dos
veces.

-P7N nombreLcursorM
*7T$= nombreLcursor INT- listaLvariablesM
<=IL7 nombreLcursora*-9N"
L--P
#U "rocesamiento de los registros recuperados U#
*7T$= nombreLcursor INT- listaLvariablesM
7N" L--PM
$L-S7 nombreLcursorM

"7$LA57
$95S-5 cpaises
IS
S7L7$T '4L"-.S, D,S'+."'.4/, '4/T./,/T,
*5-# "-.S,SM

coLpais :A5$=A52(P!M
descripcion :A5$=A52(@D!M
continente :A5$=A52(B@!M
,7;IN
-P7N cpaisesM
*7T$= cpaises INT- coLpais,descripcion,continenteM
<=IL7 cpaisesa)oun
L--P
dbmsLoutput.putLline(descripcion!M
*7T$= cpaises INT- coLpais,descripcion,continenteM
7N" L--PM
$L-S7 cpaisesM
7N"M

"or <ltimo podemos usar un bucle 94+ L44". ,s la %orma m$s corta ya que el cursor es
implicitamente se ejecutan las instrucciones 4",/, 9,'TV y 'L4S,.
*-5 variable IN nombreLcursor L--P
#U "rocesamiento de los registros recuperados U#
7N" L--PM

,7;IN
*-5 +,: IN (S7L7$T U *5-# "-.S,S!
L--P
dbmsLoutput.putLline(reg.descripcion!M
7N" L--PM
7N"M
$ursores e ActualiBaci!n
T"eclaraci!n y utiiBaci!n e $ursores e ActualiBaci!n.
Los 'ursores de -ctuali7acin en s) declar$n .gual Que los 'ursores explicitos,
aCadieno *-5 9P"AT7 al %inal de la Sentencia de seleccin.
$95S-5 nombre_cursor 7S
instruccin_"!C+
PA5A A$T9ALIUA5
"ara -ctuali7ar los Datos del &eno Que cursor ejecutar 8na
Sentencia 9P"AT7 especi%icando la clausula<=757 $9557NT -* &cursor_name'$
A$T9ALIUA$IVN &nombre_tabla' M97;-
&campo_,' X &valor_,'
G, &campo_/' 0 &valor_/' H
<=757 $9557NT -* <cursor_name>
,l Siguiente ,jemplo 5uestra ,L 8S4 de las /aciones 8nidas cursor de -ctuali7acin*
"7$LA5A5
$95S-5 cpaises 7S
seleccione '4L"-.S, Descripcin, '4/T./,/T,
e paises
*-5 9P"AT7 M
coLpais :A5$=A52 ( P !M
descripcion :A5$=A52 ( @D !M
'ontinente :A5$=A52 ( B@ !M
7#P7UA5
A,I75T- cpaisesM
*7T$= cpaises 7N coLpais, descripcion, 'ontinenteM
#I7NT5AS cpaises N se encuentran
LAU-
A$T9ALIUA$IVN "7 "-.S,S
M97;- "7 '4/T./,/T, X '4/T./,/T, K K Y.Y
<=757 $9557NT -* cpaisesM
*7T$= cpaises 7N coLpais, descripcion, 'ontinenteM
*IN "7L LAU- M
$755A5 cpaisesM
$-##ITK
7N" M
'8-/D4 trabajamos 'on 'ursores de -ctuali7acin debemos Tener en 'uenta Las
Siguientes 'onsideraciones*
Los 'ursores de -ctuali7acin generan bloqueos en la (ase de Datos.
7Fce&ciones en PL/SQL
#ane'o e eFce&ciones
,n "L#SQL una advertencia o condicin de error es llamada una excepcin.
Las excepciones se controlan dentro de su propio bloque.La estructura de bloque de una
excepcin se muestra a continuacin.
"7$LA57
Declaraciones
,7;IN
,jecucion
78$7PTI-N
,xcepcion
7N"M
'uando ocurre un error, se ejecuta la porcin del programa marcada por el
bloque 78$7PTI-N, trans%iri6ndose el control a ese bloque de sentencias.
,l siguiente ejemplo muestra un bloque de excepciones que captura las
excepciones N-G"ATAG*-9N" yU75-G"I:I"7. 'ualquier otra excepcion ser$ capturada en
el bloque <=7N -T=75S T=7N.
"7$LA57
Declaraciones
,7;IN
,jecucion
78$7PTI-N
<=7N N-G"ATAG*-9N" T=7N
Se ejecuta cuando ocurre una excepcion de tipo /4LD-T-L948/D
<=7N U75-G"I:I"7 T=7N
Se ejecuta cuando ocurre una excepcion de tipo W,+4LD.1.D,
<=7N -T=75S T=7N
Se ejecuta cuando ocurre una excepcion de un tipo no tratado
en los bloques anteriores
7N"M
'omo ya &emos dic&o cuando ocurre un error, se ejecuta el bloque 78$7PTI-N,
trans%iri6ndose el control a las sentencias del bloque. 8na ve7 %inali7ada la ejecucin del bloque
de 78$7PTI-N no se continua ejecutando el bloque anterior.
Si existe un bloque de excepcion apropiado para el tipo de excepcin se ejecuta dic&o
bloque. Si no existe un bloque de control de excepciones adecuado al tipo de excepcion se
ejecutar$ el bloque de excepcion <=7N -T=75S T=7N (si existeT!. <=7N -T=75S debe ser
el <ltimo manejador de excepciones.
Las excepciones pueden ser de%inidas en %orma interna o expl)citamente por el usuario.
,jemplos de excepciones de%inidas en %orma interna son la divisin por cero y la %alta de
memoria en tiempo de ejecucin. ,stas mismas condiciones excepcionales tienen sus propio
tipos y pueden ser re%erenciadas por ellos*U75-G"I:I"7 y ST-5A;7G755-5.
Las excepciones de%inidas por el usuario deben ser alcan7adas expl)citamente utili7ando la
sentencia 5AIS7.
'on las excepciones se pueden manejar los errores cmodamente sin necesidad de
mantener m<ltiples c&equeos por cada sentencia escrita. Tambi6n provee claridad en el
cdigo ya que permite mantener las rutinas correspondientes al tratamiento de los errores de
%orma separada de la lgica del negocio.
7Fce&ciones &ree)inias
"L#SQL proporciona un gran n<mero de excepciones prede%inidas que permiten controlar las
condiciones de error m$s &abituales.
Las excepciones prede%inidas no necesitan ser declaradas. Simplemente se utili7an cuando
estas son lan7adas por alg<n error determinado.
La siguiente es la lista de las excepciones predeterminadas por "L#SQL y una breve
descripcin de cu$ndo son accionadas*
7Fce&cion Se e'ecuta ... SQL$-"7
A$$7SSGINT-GN9LL
,l programa intent asignar valores a
los atributos de un objeto no
iniciali7ado
[@PD
$-LL7$TI-NGISGN9LL
,l programa intent asignar valores a
una tabla anidada a<n no iniciali7ada
[@P>
$95S-5GAL57A"IG-P7N
,l programa intent abrir un cursor
que ya se encontraba abierto.
+ecuerde que un cursor de ciclo 94+
autom$ticamente lo abre y ello no se
debe especi%icar con la sentencia
4",/
[@>>
"9PG:ALG-NGIN"78
,l programa intent almacenar
valores duplicados en una columna
que se mantiene con restriccin de
integridad de un )ndice <nico (unique
index!
>
IN:ALI"G$95S-5
,l programa intent e%ectuar una
operacin no v$lida sobre un cursor
>DD>
IN:ALI"GN9#,75
,n una sentencia SQL, la conversin
de una cadena de caracteres &acia
un n<mero %alla cuando esa cadena
no representa un n<mero v$lido
>ABB
L-;ING"7NI7"
,l programa intent conectarse a
4racle con un nombre de usuario o
passZord inv$lido
>D>A
N-G"ATAG*-9N"
8na sentencia S,L,'T ./T4 no
devolvi valores o el programa
re%erenci un elemento no iniciali7ado
en una tabla indexada
>DD
N-TGL-;;7"G-N
,l programa e%ectu una llamada a
4racle sin estar conectado
>D>B
P5-;5A#G755-5 "L#SQL tiene un problema interno [@D>
5-<TIP7G#IS#AT$=
Los elementos de una asignacin (el
valor a asignar y la variable que lo
contendr$! tienen tipos incompatibles.
Tambi6n se presenta este error
cuando un par$metro pasado a un
subprograma no es del tipo esperado
[@D=
S7L*GISGN9LL
,l par$metro S,L9 (el primero que es
pasado a un m6todo 5,5(,+! es
nulo
PD[B@
ST-5A;7G755-5
La memoria se termin o est$
corrupta
[@DD
S9,S$5IPTG,7I-N"G$-9NT
,l programa est$ tratando de
re%erenciar un elemento de un arreglo
indexado que se encuentra en una
posicin m$s grande que el n<mero
real de elementos de la coleccin
[@PP
S9,S$5IPTG-9TSI"7GLI#IT
,l programa est$ re%erenciando un
elemento de un arreglo utili7ando un
n<mero %uera del rango permitido (por
ejemplo, el elemento b>c!
[@PB
SISGIN:ALI"G5-<I"
La conversin de una cadena de
caracteres &acia un tipo roZid %all
porque la cadena no representa un
n<mero
>=>D
TI#7-9TG-NG57S-95$7
Se excedi el tiempo m$ximo de
espera por un recurso en 4racle
@>
T--G#ANIG5-<S
8na sentencia S,L,'T ./T4
devuelve m$s de una %ila
>=BB
:AL97G755-5
4curri un error aritm6tico, de
conversin o truncamiento. "or
ejemplo, sucede cuando se intenta
cal7ar un valor muy grande dentro de
una variable m$s pequeCa
[@DB
U75-G"I:I"7
,l programa intent e%ectuar una
divisin por cero
>=A[
7Fce&ciones e)inias &or el usuario
"L#SQL permite al usuario de%inir sus propias excepciones, las que deber$n ser declaradas y
lan7adas expl)citamente utili7ando la sentencia 5AIS7.
Las excepciones deben ser declaradas en el segmento "7$LA57 de un bloque,
subprograma o paquete. Se declara una excepcin como cualquier otra variable, asignandole el
tipo 78$7PTI-N. Las mismas reglas de alcance aplican tanto sobre variables como sobre las
excepciones.
"7$LA57
Declaraciones
5y,xcepcion 78$7PTI-NM
,7;IN
,jecucion
78$7PTI-N
,xcepcion
7N"M
5eglas e Alcance
8na excepcion es v$lida dentro de su ambito de alcance, es decir el bloque o programa
donde &a sido declarada. Las excepciones prede%inidas son siempre v$lidas.
'omo las variables, una excepcin declarada en un bloque es local a ese bloque y global a
todos los subbloques que comprende.
La sentencia 5AIS7
La sentencia 5AIS7 permite lan7ar una excepcin en %orma expl)cita. ,s posible utili7ar esta
sentencia en cualquier lugar que se encuentre dentro del alcance de la excepcin.
"7$LA57
Declaramos una excepcion identi%icada por 1-L4+L/,:-T.14
1-L4+L/,:-T.14 78$7PTI-NM
valor N9#,75M
,7;IN
,jecucion
valor *X >M
I* valor E D T=7N
5AIS7 1-L4+L/,:-T.14M
7N" I*K
78$7PTI-N
,xcepcion
<=7N :AL-5GN7;ATI:- T=7N
dbmsLoutput.putLline(Y,l valor no puede ser negativoY!M
7N"M
'on la sentencia 5AIS7 podemos lan7ar una excepcin de%inida por el usuario o prede%inida,
siendo el comportamiento &abitual lan7ar excepciones de%inidas por el usuario.
+ecordar la existencia de la excepcin -T=75S, que simboli7a cualquier condicin de
excepcin que no &a sido declarada. Se utili7a com<nmente para controlar cualquier tipo de
error que no &a sido previsto. ,n ese caso, es com<n observar la sentencia 5-LL,A$L en el
grupo de sentencias de la excepcin o alguna de las %unciones SQL$-"7 d SQL755#, que
se detallan en el prximo punto.
9so e SQL$-"7 y SQL755#
-l manejar una excepcin es posible usar las %unciones
prede%inidas SQL$oe y SQL755# para aclarar al usuario la situacin de error acontecida.
SQLcoe devuelve el n<mero del error de 4racle y un D (cero! en caso de exito al
ejecutarse una sentencia SQL.
"or otra parte, SQL755# devuelve el correspondiente mensaje de error.
,stas %unciones son muy <tiles cuando se utili7an en el bloque de excepciones, para aclarar
el signi%icado de la excepcin -T=75S.
,stas %unciones no pueden ser utili7adas directamente en una sentencia SQL, pero s) se
puede asignar su valor a alguna variable de programa y luego usar esta <ltima en alguna
sentencia.
"7$LA57
errLnum N9#,75M
errLmsg :A5$=A52(B@@!M
result N9#,75M
,7;IN
S7L7$T >#D INT- result
*5-# D8-LM

78$7PTI-N
<=7N -T=75S T=7N

errLnum *X SQL$-"7M
errLmsg *X SQL755#M
D(5SL48T"8T.putLline(Y,rror*YKKT-G$=A5(errLnum!!M
D(5SL48T"8T.putLline(errLmsg!M
7N"M
Tambi6n es posible entregarle a la %uncin SQL755# un n<mero negativo que represente
un error de 4racle y 6sta devolver$ el mensaje asociado.
"7$LA57
msg :A5$=A52(B@@!M
,7;IN
msg *X SQL755#(>=DP!M
D(5SL48T"8T.putLline(5S:!M
7N"M

7Fce&ciones &ersonaliBaas en PL/SQL
5AIS7GAPPLI$ATI-NG755-5
,n ocasiones queremos enviar un mensaje de error personali7ado al producirse una
excepcin "L#SQL.
"ara ello es necesario utili7ar la instruccion 5AIS7GAPPLI$ATI-NG755-5M
La sintaxis general es la siguiente*
5AIS7GAPPLI$ATI-NG755-5(EerrorLnumF,EmensajeF!M
Siendo*
errorLnum es un entero negativo comprendido entre BDDD> y BD]]]
mensaje la descripcion del error

"7$LA57
vLdiv N9#,75M
,7;IN
S7L7$T >#D INT- vLdiv *5-# D8-LM
78$7PTI-N
<=7N -T=75S T=7N
5AIS7GAPPLI$ATI-NG755-5(BDDD>,Y/o se puede dividir por ceroY!M
7N"M

Pro&agacion e eFce&ciones en PL/SQL
8na de las caracter)sticas m$s interesantes de la excepciones es la propagacin de
excepciones.
'uando se lan7a una excepcin, el control se trans%iere &asta la seccin 78$7PTI-N del
bloque donde se &a producido la excepcin. ,ntonces se busca un manejador v$lido de la
excepcin (<=7N &excepcion' T=7N,<=7N -T=75S T=7N! dentro del bloque actual.
,n el caso de que no se encuentre ning<n manejador v$lida el control del programa se
despla7a &asta el bloque 78$7PTI-N del bloque que &a reali7ado la llamada "L#SQL.
4bservemos el siguiente bloque de "L#SQL (/otese que se &a aCadido una clausula
2V,+, >XB para provocar una excepcion N-G"ATAG*-9N"!.
"7$LA57
%ec&a "AT7M
*9N$TI-N %nL%ec&a 57T95N "AT7
IS
%ec&a "AT7M
,7;IN
S7L7$T SIS"AT7 INT- %ec&a
*5-# D8-L
<=757 >XBM
57T95N %ec&aM
78$7PTI-N
<=7N U75-G"I:I"7 T=7N
dbmsLoutput.putLline(Y,0',"'.4/ W,+4LD.1.D, '-"T8+-D-
,/ %nL%ec&aY!M
7N"M
,7;IN
%ec&a *X %nL%ec&a(!M
dbmsLoutput.putLline(YLa %ec&a es YKKT4L'V-+(%ec&a, YDD#55#3333Y!!M
78$7PTI-N
<=7N N-G"ATAG*-9N" T=7N
dbmsLoutput.putLline(Y,0',"'.4/ /4LD-T-L948/D '-"T8+-D- ,/
,L (L4Q8, "+./'."-LY!M
7N"M
La excepcion N-G"ATAG*-9N" se produce durante la ejecucin de la %uncion %nL%ec&a,
pero como no existe ning<n manejador de la excepcin en dic&a %uncion, la excepcin se
propaga &asta el bloque que &a reali7ado la llamada. ,n ese momento se captura la excepcion.
Su6&rogra%as en PL/SQL
'omo &emos visto anteriormente los bloques de "L#SQL pueden ser bloques annimos
(scripts! y subprogramas.
Los subprogramas son bloques de "L#SQL a los que asignamos un nombre identi%icativo y
que normalmente almacenamos en la propia base de datos para su posterior ejecucin.
Los subprogramas pueden recibir par$metros.
Los subprogramas pueden ser de varios tipos*
Procei%ientos al%acenaos .
*unciones .
Triggers .
Su6&rogra%as en 6loDues anoni%os .

Procei%ientos al%acenaos
8n procedimiento es un subprograma que ejecuta una accin especi%ica y que no devuelve
ning<n valor. 8n procedimiento tiene un nombre, un conjunto de par$metros (opcional! y un
bloque de cdigo.
La sintaxis de un procedimiento almacenado es la siguiente*
$57AT7 Q4+ 57PLA$7R
P5-$7"957 &procedure_name' G(&param,' GINK-9TJIN -9TH &t*pe',
&param/' GINK-9TJIN -9TH &t*pe', ...!H
IS
Declaracion de variables locales
,7;IN
Sentencias
G78$7PTI-NH
Sentencias control de excepcion
7N" G&procedure_name'HM
,l uso de 4+ +,"L-', permite sobreescribir un procedimiento existente. Si se omite, y el
procedimiento existe, se producir$, un error.
La sintaxis es muy parecida a la de un bloque annimo, salvo porque se reempla7a la
seccion "7$LA57 por la secuencia P5-$7"957 ... IS en la especi%icacin del procedimiento.
Debemos especi%icar el tipo de datos de cada par$metro. Al es&eci)icar el ti&o e ato el
&arC%etro no e6e%os es&eci)icar la longitu el ti&o.
Los par$metros pueden ser de entrada (IN!, de salida (-9T! o de entrada salida (IN -9T!. ,l
valor por de%ecto es IN, y se toma ese valor en caso de que no especi%iquemos nada.
$57AT7 4+ 57PLA$7
P5-$7"957 -ctuali7aLSaldo(cuenta N9#,75,
neZLsaldo N9#,75!
IS
Declaracion de variables locales
,7;IN
Sentencias
9P"AT7 S-LD4SL'8,/T-S
S7T S-LD4 X neZLsaldo,
90L-'T8-L.W-'.4/ X SIS"AT7
<=757 '4L'8,/T- X cuentaM
7N" -ctuali7aLSaldoM
Tambi6n podemos asignar un valor por de%ecto a los par$metros, utili7ando la
clausula "7*A9LT o el operador de asigancin (*X! .
$57AT7 4+ 57PLA$7
P5-$7"957 -ctuali7aLSaldo(cuenta N9#,75,
neZLsaldo N9#,75 "7*A9LT WX !
IS
Declaracion de variables locales
,7;IN
Sentencias
9P"AT7 S-LD4SL'8,/T-S
S7T S-LD4 X neZLsaldo,
90L-'T8-L.W-'.4/ X SIS"AT7
<=757 '4L'8,/T- X cuentaM
7N" -ctuali7aLSaldoM
8na ve7 creado y compilado el procedimiento almacenado podemos ejecutarlo. Si el sistema
nos indica que el procedimiento se &a creado con errores de compilacin podemos ver estos
errores de compilacion con la orden S=-< 755-5S en SQL U"lus.
,xisten dos %ormas de pasar argumentos a un procedimiento almacenado a la &ora de
ejecutarlo (en realidad es v$lido para cualquier subprograma!. ,stas son*
Notaci!n &osicional* Se pasan los valores de los par$metros en el mismo orden en
que el procedure los de%ine.
,7;IN
ActualiBaGSalo(BDD@D>,B@DD!M
$-##ITM
7N"M
Notaci!n no%inal*Se pasan los valores en cualquier orden nombrando explicitamente
el par$metro.
,7;IN
ActualiBaGSalo(cuenta XF BDD@D>,neZLsaldo XF B@DD!M
$-##ITK
7N"M
*unciones en PL/SQL
8na %uncin es un subprograma que devuelve un valor.
La sintaxis para construir %unciones es la siguiente*
$57AT7 Q4+ 57PLA$7R
*9N$TI-N &fn_name'1(&param,' IN &t*pe', &param/' IN &t*pe', ...!H
57T95N &return_t*pe'
IS
result &return_t*pe'M
,7;IN

return(result!M
G78$7PTI-NH
Sentencias control de excepcion
7N" G&fn_name'2M
,l uso de 4+ +,"L-', permite sobreescribir una %uncin existente. Si se omite, y la %uncin
existe, se producir$, un error.
La sintaxis de los par$metros es la misma que en los procedimientos almacenado,
exceptuando que solo pueden ser de entrada.
,jemplo*
$57AT7 4+ 57PLA$7
*9N$TI-N %nL4btenerL"recio(pLproducto :A5$=A52!
57T95N N9#,75
IS
result N9#,75M
,7;IN
S7L7$T "+,'.4 INT- result
*5-# "+,'.4SL"+4D8'T4S
<=757 '4L"+4D8'T4 X pLproductoM
return(result!M
78$7PTI-N
<=7N N-G"ATAG*-9N" T=7N
return DM
7N" M
Si el sistema nos indica que el la %uncin se &a creado con errores de compilacin podemos
ver estos errores de compilacion con la orden S=-< 755-5S en SQL U"lus.
8na ve7 creada y compilada la %uncin podemos ejecutarla de la siguiente %orma*
"7$LA57
1alor N9#,75M
,7;IN
1alor *X )nG-6tenerGPrecio(YDDD>DDY!M
7N"M
Las %unciones pueden utili7arse en sentencias SQL de manipulacin de datos (S,L,'T,
8"D-T,, ./S,+T y D,L,T,!*
S7L7$T '4L"+4D8'T4,
D,S'+."'.4/,
)nG-6tenerGPrecio('4L"+4D8'T4!
*5-# "+4D8'T4SM

Triggers
"eclaraci!n e triggers
8n trigger es un bloque "L#SQL asociado a una tabla, que se ejecuta como consecuencia de
una determinada instruccin SQL (una operacin D5L* ./S,+T, 8"D-T, o D,L,T,! sobre
dic&a tabla.
La sintaxis para crear un trigger es la siguiente*
$57AT7 Q4+ 57PLA$7R T5I;;75 &nombre_trigger'
Y,7*-57JA*T75Z
Y"7L7T7JINS75TJ9P"AT7 Q-* col>, colB, ..., col/R
Q4+ Y"7L7T7JINS75TJ9P"AT7 Q-* col>, colB, ..., col/R...RZ
-N &nombre_tabla'
Q*-5 7A$= 5-< Q<=7N (<condicion')RR
"7$LA57
variables locales
,7;IN
Sentencias
G78$7PTI-NH
Sentencias control de excepcion
7N" &nombre_trigger'M
,l uso de 4+ +,"L-', permite sobreescribir un trigger existente. Si se omite, y el trigger
existe, se producir$, un error.
Los triggers pueden de%inirse para las operaciones ./S,+T, 8"D-T, o D,L,T,, y
pueden ejecutarse antes o despu6s de la operacin. ,l modi%icador (,94+, -9T,+ indica
que el trigger se ejecutar$ antes o despues de ejecutarse la sentencia SQL de%inida por
D,L,T, ./S,+T 8"D-T,. Si incluimos el modi%icador 49 el trigger solo se ejecutar$ cuando
la sentencia SQL a%ecte a los campos incluidos en la lista.
,l alcance de los disparadores puede ser la %ila o de orden. ,l modi%icador 94+ ,-'V +42
indica que el trigger se disparar$ cada ve7 que se reali7an operaciones sobre una %ila de la
tabla. Si se acompaCa del modi%icador 2V,/, se establece una restriccinM el trigger solo
actuar$, sobre las %ilas que satis%agan la restriccin.
La siguiente tabla resume los contenidos anteriores.
:alor "escri&ci!n
INS75T, "7L7T7, 9P"AT7
De%ine qu6 tipo de orden D5L provoca la activacin del
disparador.
,7*-57 , A*T75
De%ine si el disparador se activa antes o despu6s de que
se ejecute la orden.
*-5 7A$= 5-<
Los disparadores con nivel de %ila se activan una ve7 por
cada %ila a%ectada por la orden que provoc el disparo.
Los disparadores con nivel de orden se activan slo una
ve7, antes o despu6s de la orden. Los disparadores con
nivel de %ila se identi%ican por la cl$usula 94+ ,-'V
+42 en la de%inicin del disparador.
La cl$usula 2V,/ slo es v$lida para los disparadores con nivel de %ila.
Dentro del ambito de un trigger disponemos de las variables 4LD y /,2 . ,stas variables se
utili7an del mismo modo que cualquier otra variable "L#SQL, con la salvedad de que no
es necesario declararlas, son de tipo N5-<TIP7 y contienen una copia del registro antes
(4LD! y despues(/,2! de la accin SQL (./S,+T, 8"D-T,, D,LT,! que &a ejecutado el
trigger. 8tili7ando esta variable podemos acceder a los datos que se est$n insertando,
actuali7ando o borrando.
,l siguiente ejemplo muestra un trigger que inserta un registro en la tabla
"+,'.4SL"+4D8'T4S cada ve7 que insertamos un nuevo registro en la tabla "+4D8T4S*
$57AT7 -5 57PLA$7 T5I;;75 T+L"+4D8'T4SLD>
A*T75 INS75T -N "+4D8'T4S
*-5 7A$= 5-<
"7$LA57
local variables
,7;IN
INS75T INT- "+,'.4SL"+4D8'T4S
('4L"+4D8'T4,"+,'.4,90L-'T8-L.W-'.4/!
:AL97S
(*N7<.'4L"+4D8'T4,>DD,S3SD-T,!M
7N" M
,l trigger se ejecutar$ cuando sobre la tabla "+4D8'T4S se ejecute una sentencia
./S,+T.
INS75T INT- "+4D8'T4S
('4L"+4D8'T4, D,S'+."'.4/!
:AL97S
(YDDD>DDY,Y"+4D8'T4 DDD>DDY!M
-ren e e'ecuci!n e los triggers
8na misma tabla puede tener varios triggers. ,n tal caso es necesario conocer el orden en el
que se van a ejecutar.
Los disparadores se activan al ejecutarse la sentencia SQL.
Si existe, se ejecuta el disparador de tipo (,94+, (disparador previo! con nivel de
orden.
"ara cada %ila a la que a%ecte la orden*
o Se ejecuta si existe, el disparador de tipo (,94+, con nivel de %ila.
o Se ejecuta la propia orden.
o Se ejecuta si existe, el disparador de tipo -9T,+ (disparador posterior! con
nivel de %ila.
Se ejecuta, si existe, el disparador de tipo -9T,+ con nivel de orden.
5estricciones e los triggers
,l cuerpo de un trigger es un bloque "L#SQL. 'ualquier orden que sea legal en un bloque
"L#SQL, es legal en el cuerpo de un disparador, con las siguientes restricciones*
8n disparador no puede emitir ninguna orden de control de
transacciones* $-##IT, 5-LL,A$L oSA:7P-INT. ,l disparador se activa como parte de la
ejecucin de la orden que provoc el disparo, y %orma parte de la misma transaccin que dic&a
orden. 'uando la orden que provoca el disparo es con%irmada o cancelada, se con%irma o
cancela tambi6n el trabajo reali7ado por el disparador.
"or ra7ones id6nticas, ning<n procedimiento o %uncin llamado por el disparador puede
emitir rdenes de control de transacciones.
,l cuerpo del disparador no puede contener ninguna declaracin de variables L4/: o
L4/: +-2
9tiliBaci!n e A-L" y AN7<
Dentro del ambito de un trigger disponemos de las variables 4LD y /,2 . ,stas variables se
utili7an del mismo modo que cualquier otra variable "L#SQL, con la salvedad de que no
es necesario declararlas, son de tipo N5-<TIP7 y contienen una copia del registro antes
(4LD! y despues(/,2! de la accin SQL (./S,+T, 8"D-T,, D,LT,! que &a ejecutado el
trigger. 8tili7ando esta variable podemos acceder a los datos que se est$n insertando,
actuali7ando o borrando.
La siguiente tabla muestra los valores de 4LD y /,2.
A$$I-N
SQL
-L" N7<
./S,+T
/o de%inidoM todos los campos
toman valor /8LL.
1alores que ser$n insertados cuando
se complete la orden.
8"D-T,
1alores originales de la %ila, antes
de la actuali7acin.
/uevos valores que ser$n escritos
cuando se complete la orden.
D,L,T,
1alores, antes del borrado de la
%ila.
/o de%inidosM todos los campos toman
el valor /8LL.
Los registros 4LD y /,2 son slo v$lidos dentro de los disparadores con nivel de %ila.
"odemos usar 4LD y /,2 como cualquier otra variable "L#SQL.
9tiliBaci!n e &reicaos e los triggersA INS75TIN;, 9P"ATIN; y "7L7TIN;
Dentro de un disparador en el que se disparan distintos tipos de rdenes D5L (./S,+T,
8"D-T, y D,L,T,!, &ay tres %unciones booleanas que pueden emplearse para determinar de
qu6 operacin se trata. ,stos predicados son ./S,+T./:, 8"D-T./: y D,L,T./:.
Su comportamiento es el siguiente*
Preicao $o%&orta%iento
INS75TIN; T+8, si la orden de disparo es ./S,+TM 9-LS, en otro
caso.
9P"ATIN;
T+8, si la orden de disparo es 8"D-T,M 9-LS, en otro
caso.
"7L7TIN;
T+8, si la orden de disparo es D,L,T,M 9-LS, en otro
caso.

Su6&rogra%as en 6loDues an!ni%os
Dentro de la seccion D,'L-+, de un bloque annimo podemos declarar %unciones y
procedimientos almacenados y ejecutarlos desde el bloque de ejecucin del script.
,ste tipo de subprogramas son menos conocidos que los procedimientos almacenados,
%unciones y triggers, pero son enormemente <tiles.
,l siguiente ejemplo declara y ejecuta utili7a una %uncion (%nLmultiplicaLxB!.
"7$LA57
idx N9#,75M
*9N$TI-N %nLmultiplicaLxB(num N9#,75!
57T95N N9#,75
IS
result N9#,75M
,7;IN
result *X num UBM
return resultM
7N" %nLmultiplicaLxBM
,7;IN
*-5 idx IN >..>D
L--P
dbmsLoutput.putLline
(YLlamada a la %uncion ... YKKT-G$=A5(%nLmultiplicaLxB(idx!!!M
7N" L--PM

7N"M
/otese que se utili7a la %uncion T4L'V-+ para convertir el resultado de la %uncin
%nLmultiplicaLxB (num6rico! en al%anum6rico y poder mostrar el resultado por pantalla.
Pac?ages en PL/SQL
8n paquete es una estructura que agrupa objetos de "L#SQL compilados(procedures,
%unciones, variables, tipos ...! en la base de datos. ,sto nos permite agrupar la %uncionalidad de
los procesos en programas.
Lo primero que debemos tener en cuenta es que los paquetes est$n %ormados por dos
partes* laes&eci)icaci!n y el cuer&o. La especi%icacin del un paquete y su cuerpo se crean
por separado.
La especi%icacin es la inter%a7 con las aplicaciones. ,n ella es posible declarar los tipos,
variables, constantes, excepciones, cursores y subprogramas disponibles para su uso posterior
desde %uera del paquete. ,n la especi%icacin del paquete slo se declaran los objetos
(procedures, %unciones, variables ...!, no se implementa el cdigo. Los objetos declarados en la
especi%icacin del paquete son accesibles desde %uera del paquete por otro script de "L#SQL o
programa. Vaciendo una analog)a con el mundo de ', la especi%icacin es como el arc&ivo de
cabecera de un programa en '.
"ara crear la especi%icacin de un paquete la sintaxis general es la siguiente*
$57AT7 G4+ 57PLA$7H PA$LA;7 Ep3gNameF
IS

Declaraciones de tipos y registros p<blicas
IGTIP7 E+*peNameF IS E4atat*peFMHJ

Declaraciones de variables y constantes publicas
Tambi6n podemos declarar cursores
IGEConstantNameF $-NSTANT E4atat*peF *X EvalorFMHJ
IGE5ariableNameF E4atat*peFMHJ
Declaraciones de procedimientos y %unciones p<blicas
IG*9N$TI-N EFunctionNameF(E6arameterF E4atat*peF,...!
57T95N E4atat*peFMHJ
IGP5-$7"957 E6rocedureNameF(E6arameterF E4atat*peF, ...!MHJ
7N" Ep3gNameFM
,l cuerpo el laimplementacin del paquete. ,l cuerpo del paquete debe implementar lo que
se declar inicialmente en la especi%icacin. ,s el donde debemos escribir el cdigo de los
subprogramas. ,n el cuerpo de un pacNage podemos declarar nuevos subprogramas y tipos,
pero estos seran privados para el propio pacNage.
La sintaxis general para crear el cuerpo de un paquete es muy parecida a la de la
especi%icacin, tan solo se aCade la palabra clave ,-"I, y se implementa el cdigo de los
subprogramas.
$57AT7 G4+ 57PLA$7H PA$LA;7 ,-"I Ep3gNameF
IS

Declaraciones de tipos y registros privados
IGTIP7 E+*peNameF IS E4atat*peFMHJ

Declaraciones de variables y constantes privadas
Tambi6n podemos declarar cursores
IGEConstantNameF $-NSTANT E4atat*peF *X EvalorFMHJ
IGE5ariableNameF E4atat*peFMHJ
.mplementacion de procedimientos y %unciones
*9N$TI-N EFunctionNameF(E6arameterF E4atat*peF,...!
57T95N EDatatypeF
IS
1ariables locales de la %uncion
,7;IN
.mplementeacion de la %uncion
return(E+esultF!M
G78$7PTI-NH
'ontrol de excepciones
7N"M

P5-$7"957 E6rocedureNameF(E6arameterF E4atat*peF, ...!
IS
1ariables locales de la %uncion
,7;IN
.mplementacion de procedimiento
G78$7PTI-NH
'ontrol de excepciones
7N"M
7N" Ep3gNameFM
,l siguiente ejemplo crea un paquete llamado 678_C9N+:;#!#4:4.
"ara crear la especi%icacin del paquete*
$57AT7 -5 57PLA$7 PA$LA;7 PL;G$-NTA,ILI"A"
IS

Declaraciones de tipos y registros p<blicas
TIP7 'uentaLcontable IS 57$-5"
(
codigoLcuenta :A5$=A52([!,
naturale7a :A5$=A52(B! ,
actividad :A5$=A52(=! ,
debeL&aber :A5$=A52(>!
!M

Declaraciones de variables y constantes publicas
D,(, $-NSTANT :A5$=A52(>! *X YDYM
V-(,+ $-NSTANT :A5$=A52(>! *X YDYM
,++4+L'4/T-(.L.W-+ 78$7PTI-NM
Declaraciones de procedimientos y %unciones p<blicas
P5-$7"957 'ontabili7ar (mes 1-+'V-+B! M
*9N$TI-N %nL4btenerLSaldo(codigoLcuenta 1-+'V-+B! 57T95N N9#,75M
7N" PL;G$-NTA,ILI"A"M
-qu) slo &emos declarado las variables y constantes, prototipado las %unciones y
procedimientos p<blicos . ,s en el cuerpo del paquete cuando escribimos el cdigo de los
subprogramas Contabili<ar y fn_9btener_"aldo.
$57AT7 PA$LA;7 ,-"I PL;G$-NTA,ILI"A" IS
*9N$TI-N %nL4btenerLSaldo(codigoLcuenta :A5$=A52!
57T95N N9#,75
IS
saldo N9#,75M
,7;IN
S7L7$T S-LD4 INT- saldo
*5-# S-LD4S
<=757 '4L'8,/T- X codigoLcuentaM
return (saldo!M
7N"M

P5-$7"957 'ontabili7ar(mes :A5$=A52!
IS
$95S-5 cDatos(vmes :A5$=A52!
IS
S7L7$T U
*5-# 9-'T8+-'.4/
<=757 90L9-'T8+-'.4/ X vmes
AN" ",/D.,/T,L'4/T-(.L.W-+ X YSYM

%ila cDatosa5-<TIP7M

,7;IN
-P7N cDatos(mes!M
L--P *7T$= cDatos INT- %ilaM
78IT <=7N cDatosaN-T*-9N"M
#U "rocesamiento de los registros recuperados U#
7N" L--PM
$L-S7 cDatosM

78$7PTI-N
<=7N -T=75S T=7N
5AIS7 ,++4+L'4/T-(.L.W-+M
7N" 'ontabili7arM
7N" ";:L'4/T-(.L.D-DM
,s posible modi%icar el cuerpo de un paquete sin necesidad de alterar por ello la
especi%icacin del mismo.
Los paquetes pueden llegar a ser programas muy complejos y suelen almacenar gran parte
de la lgica de negocio.
5egistros PL/SQL
'uando vimos los tipos de datos, omitimos intencionadamente ciertos tipos de datos.
,stos son*
5egistros
Ta6las e PL
:A55AI
"eclaraci!n e un registro.
8n registnslpZdro es una estructura de datos en "L#SQL, almacenados en campos, cada
uno de los cuales tiene su propio nombre y tipo y que se tratan como una sola unidad lgica.
Los campos de un registro pueden ser iniciali7ados y pueden ser de%inidos como /4T /8LL.
-quellos campos que no sean iniciali7ados expl)citamente, se iniciali7ar$n a /8LL.
La sintaxis general es la siguiente*
TIP7 EnombreF IS 57$-5"
(
campo &tipo_datos' G/8LL K /4T /8LLH
G,&tipo_datos'...H
!M
,l siguiente ejemplo crea un tipo "-.S, que tiene como campos el cdigo, el nombre y el
continente.
TIP7 "-.S IS 57$-5"
(
'4L"-.S N9#,75 ,
D,S'+."'.4/ :A5$=A52(@D!,
'4/T./,/T, :A5$=A52(BD!
!M
Los registros son un tipo de datos, por lo que podremos declarar variables de dic&o tipo de
datos.
"7$LA57
TIP7 "-.S IS 57$-5"
(
'4L"-.S N9#,75 ,
D,S'+."'.4/ :A5$=A52(@D!,
'4/T./,/T, :A5$=A52(BD!
!M
#U Declara una variable identi%icada por mi"-.S de tipo "-.S
,sto signi%ica que la variable mi"-.S tendr$ los campos
.D, D,S'+."'.4/ y '4/T./,/T,.
U#
mi"-.S PAISM
,7;IN
#U -signamos valores a los campos de la variable.
U#
mi"-.S.'4L"-.S *X BAM
mi"-.S.D,S'+."'.4/ *X Y.T-L.-YM
mi"-.S.'4/T./,/T, *X Y,8+4"-YM
7N"K
Los registros pueden estar anidados. ,s decir, un campo de un registro puede ser de un tipo
de dato de otro registro.
"7$LA57
TIP7 "-.S IS 57$-5"
('4L"-.S N9#,75 ,
D,S'+."'.4/ :A5$=A52(@D!,
'4/T./,/T, :A5$=A52(BD!
!M
TIP7 54/,D- IS 57$-5"
( D,S'+."'.4/ :A5$=A52(@D!,
"-.SL54/,D- PAIS !M

mi"-.S PAISM
mi54/,D- #-N7"AM
,7;IN
#U Sentencias
U#
7N"M
"ueden asignarse todos los campos de un registro utili7ando una sentencia S,L,'T. ,n
este caso &ay que tener cuidado en especi%icar las columnas en el orden conveniente seg<n la
declaracin de los campos del registro. "ara este tipo de asignacin es muy %recuente el uso
del atributo N5-<TIP7 que veremos m$s adelante.
S7L7$T '4L"-.S, D,S'+."'.4/, '4/T./,/T,
INT- mi"-.S
*5-# "-.S,S
<=757 '4L"-.S X BAM
"uede asignarse un registro a otro cuando sean del mismo tipo*
"7$LA57
TIP7 "-.S IS 57$-5" ...
mi"-.S "-.SM
otro"-.S "-.SM
,7;IN
mi"-.S.'4L"-.S *X BAM
mi"-.S.D,S'+."'.4/ *X Y.T-L.-YM
mi"-.S.'4/T./,/T, *X Y,8+4"-YM
otro"-.S *X mi"-.SM
7N"K

"eclaraci!n e registros con el atri6uto N5-<TIP7
Se puede declarar un registro bas$ndose en una coleccin de columnas de una tabla, vista o
cursor de la base de datos mediante el atributo N5-<TIP7.
"or ejemplo, si tengo una tabla "-.S,S declarada como*
$57AT7 TA,L7 "-.S,S(
'4L"-.S N9#,75,
D,S'+."'.4/ :A5$=A52(@D!,
'4/T./,/T, :A5$=A52(BD! !M
"uedo declarar una variable de tipo registro como "-.S,SN5-<TIP7M
"7$LA57
mi"-.S "-.S,SN5-<TIP7M
,7;IN
#U Sentencias ... U#
7N"M
Lo cual signi%ica que el registro mi"-.S tendr$ la siguiente estructura* '4L"-.S
/85(,+, D,S'+."'.4/ 1-+'V-+B(@D!, '4/T./,/T, 1-+'V-+B(BD!.
De esta %orma se crea el registro de %orma dinamic y se podr$n asignar valores a los campos
de un registro a trav6s de un select sobre la tabla, vista o cursor a partir de la cual se creo el
registro.

Ta6las PL/SQL
"eclaraci!n e ta6las e PL/SQL
Las tablas de "L#SQL son tipos de datos que nos permiten almacenar varios valores del
mismo tipo de datos.
8na tabla "L#SQL *
,s similar a un array
Tiene dos componenetes* 8n )ndice de tipo (./-+3L./T,:,+ que permite acceder a
los elementos en la tabla "L#SQL y una columna de escalares o registros que contiene
los valores de la tabla "L#SQL
"uede incrementar su tamaCo din$micamente.
La sintaxis general para declarar una tabla de "L es la siguiente*
TIP7 &nombre_tipo_tabla' IS TA,L7 -*
Etipo_datosF GN-T N9LLH
IN"78 ,I ,INA5IGINT7;75 M
8na ve7 que &emos de%inido el tipo, podemos declarar variables y asignarle valores.
"7$LA57
#U De%inimos el tipo "-.S,S como tabla "L#SQL U#
TIP7 "-.S,S IS TA,L7 -* /85(,+ IN"78 ,I ,INA5IGINT7;75 M
#U Declaramos una variable del tipo "-.S,S U#
t"-.S,S "-.S,SM
,7;IN
t"-.S,S(>! *X >M
t"-.S,S(B! *X BM
t"-.S,S(P! *X PM
7N"M
/o es posible iniciali7ar las tablas en la iniciali7acin.
,l rango de binary integer es dB>=A=?P[=A.. B>=A=?P[=A, por lo tanto el )ndice puede ser
negativo, lo cual indica que el )ndice del primer valor no tiene que ser necesariamente el cero.
Ta6las PL/SQL e registros
,s posible declarar elementos de una tabla "L#SQL como de tipo registro.
"7$LA57
TIP7 "-.S IS 57$-5"
(
'4L"-.S N9#,75 N-T N9LL ,
D,S'+."'.4/ :A5$=A52(@D!,
'4/T./,/T, :A5$=A52(BD!
!M
TIP7 "-.S,S IS TA,L7 -* "-.S IN"78 ,I ,INA5IGINT7;75 M
t"-.S,S "-.S,SM
,7;IN
t"-.S,S(>!.'4L"-.S *X BAM
t"-.S,S(>!.D,S'+."'.4/ *X Y.T-L.-YM
t"-.S,S(>!.'4/T./,/T, *X Y,8+4"-YM
7N"K
*unciones &ara el %ane'o e ta6las PL/SQL
'uando trabajamos con tablas de "L podemos utili7ar las siguientes %unciones*
*I5ST. Devuelve el menor )ndice de la tabla. /8LL si est$ vac)a.
LAST. Devuelve el mayor )ndice de la tabla. /8LL si est$ vac)a.
,l siguiente ejemplo muestra el uso de 9.+ST y L-ST *
"7$LA57
TIP7 A55G$I9"A"7S IS TA,L7 -* :A5$=A52(@D! IN"78 ,I
,INA5IGINT7;75M
mis'iudades A55G$I9"A"7SM
,7;IN
mis'iudades(>! *X Y5-D+.DYM
mis'iudades(B! *X Y(.L(-4YM
mis'iudades(P! *X Y5-L-:-YM

*-5 i IN mis'iudades.*I5ST..mis'iudades.LAST
L--P
dbmsLoutput.putLline(mis'iudades(i!!M
7N" L--PM
,/DM
78ISTS(i!. 8tili7ada para saber si en un cierto )ndice &ay almacenado un valor.
Devolver$ T+8, si en el )ndice i &ay un valor.
"7$LA57
TIP7 -++L'.8D-D,S IS TA,L7 -* :A5$=A52(@D! IN"78 ,I
,INA5IGINT7;75M
mis'iudades A55G$I9"A"7SM
,7;IN
mis'iudades(>! *X Y5-D+.DYM
mis'iudades(P! *X Y5-L-:-YM

*-5 i IN mis'iudades.*I5ST..mis'iudades.LAST
L--P
I* mis'iudades.78ISTS(i! T=7N
dbmsLoutput.putLline(mis'iudades(i!!M
7LS7
dbmsLoutput.putLline(Y,l elemento no existe*YKKT4L'V-+(i!!M
7N" I*M
7N" L--PM
7N"M
$-9NT. Devuelve el n<mero de elementos de la tabla "L#SQL.
"7$LA57
TIP7 -++L'.8D-D,S IS TA,L7 -* 1-+'V-+B(@D! IN"78 ,I
,INA5IGINT7;75M
mis'iudades -++L'.8D-D,SM
,7;IN
mis'iudades(>! *X Y5-D+.DYM
mis'iudades(P! *X Y5-L-:-YM
#U Devuelve B, ya que solo &ay dos elementos con valor U#
dbmsLoutput.putLline(
Y,l n<mero de elementos es*YKKmis'iudades.$-9NT!M
7N"M
P5I-5 (n!. Devuelve el n<mero del )ndice anterior a n en la tabla.
"7$LA57
TIP7 -++L'.8D-D,S IS TA,L7 -* :A5$=A52(@D! IN"78 ,I
,INA5IGINT7;75M
mis'iudades A55G$I9"A"7SM
,7;IN
mis'iudades(>! *X Y5-D+.DYM
mis'iudades(P! *X Y5-L-:-YM
#U Devuelve >, ya que el elemento B no existe U#
dbmsLoutput.putLline(
Y,l elemento previo a P es*Y KK mis'iudades.P5I-5(P!!M
7N"M
N78T (n!. Devuelve el n<mero del )ndice posterior a n en la tabla.
"7$LA57
TIP7 -++L'.8D-D,S IS TA,L7 -* :A5$=A52(@D! IN"78 ,I
,INA5IGINT7;75M
mis'iudades A55G$I9"A"7SM
,7;IN
mis'iudades(>! *X Y5-D+.DYM
mis'iudades(P! *X Y5-L-:-YM
#U Devuelve P, ya que el elemento B no existe U#
dbmsLoutput.putLline(
Y,l elemento siguiente es*Y KK mis'iudades.N78T(>!!M
7N"M
T5I#. (orra un elemento del %inal de la tabla "L#SQL.
T5I#(n! borra n elementos del %inal de la tabla "L#SQL.
"7L7T7. (orra todos los elementos de la tabla "L#SQL.
"7L7T7(n! borra el correspondiente al )ndice n.
"7L7T7(m,n! borra los elementos entre m y n.
:A55AIS
"e)inici!n e :A55AIS.
8n varray se manipula de %orma muy similar a las tablas de "L, pero se implementa de %orma
di%erente. Los elementos en el varray se almacenan comen7ando en el )ndice > &asta la
longitud m$xima declarada en el tipo varray.
La sintaxis general es la siguiente*
TIP7 &nombre_tipo' IS :A55AI (&tamao_maximo'! -* &tipo_elementos'M
8na consideracin a tener en cuenta es que en la declaracin de un varray el tipo de datos
no puede ser de los siguientes tipos de datos*
(44L,-/
/'V-+
/'L4(
/1-+'V-+(n!
+,9 '8+S4+
T-(L,
1-++-3
Sin embargo se puede especi%icar el tipo utili7ando los atributos NTIP7 y N5-<TIP7.
Los :A55AI deben estar iniciali7ados antes de poder utili7arse. "ara iniciali7ar
un :A55AI se utili7a un constructor (podemos iniciali7ar el 1-++-3 en la seccin D,'L-+,
o bien dentro del cuerpo del bloque!*
"7$LA57
#U Declaramos el tipo 1-++-3 de cinco elementos 1-+'V-+BU#
TIP7 tLcadena IS :A55AI(@! -* :A5$=A52(@D!M
#U -signamos los valores con un constructor U#
vLlista tLcadena*X tLcadena(Y-itorY, Y-liciaY, Y"edroY,YY,YY!M
,7;IN
vLlista(=! *X YTitaYM
vLlista(@! *X Y-in&oaYM
7N"M
7l ta%aEo e un :A55AI se esta6lece %eiante el n(%ero e &arC%etros utiliBaos
en el constructor, si declaramos un 1-++-3 de cinco elementos pero al iniciali7arlo pasamos
slo tres par$metros al constructor, el tamaCo del 1-++-3 ser$ tres. Si se &acen asignaciones
a elementos que queden %uera del rango se producir$ un error.
,l tamaCo de un 1-++-3 podr$ aumentarse utili7ando la %uncin ,0T,/D, pero nunca con
mayor dimensin que la de%inida en la declaracin del tipo. "or ejemplo, la variable vLlista que
slo tiene P valores de%inidos por lo que se podr)a ampliar &asta cinco elementos pero no m$s
all$.
8n 1-++-3 comparte con las tablas de "L todas las %unciones v$lidas para ellas, pero
aCade las siguientes*
LI#IT . Devuelve el n<mero maximo de elementos que admite el 1-++-3.
78T7N" .-Cade un elemento al 1-++-3.
78T7N"(n! .-Cade (n! elementos al 1-++-3.
:arrays en la 6ase e atos
Los 1-++-3S pueden almacenarse en las columnas de la base de datos. Sin embargo, un
varray slo puede manipularse en su integridad, no pudiendo modi%icarse sus elementos
individuales de un varray.
"ara poder crear tablas con campos de tipo 1-++-3 debemos crear el 1-++-3 como un
objeto de la base de datos.
La sintaxis general es*
$57AT7 Q-5 57PLA$7R
TIP7 &nombre_tipo' IS :A55AI (&tamao_maximo'! -* &tipo_elementos'M
8na ve7 que &ayamos creado el tipo sobre la base de datos, podremos utili7arlo como un
tipo de datos m$s en la creacion de tablas, declaracin de variables ....
1ease el siguiente ejemplo*
$57AT7 4+ 57PLA$7 TIP7 "-';L"+4D8'T4S AS :A55AI(>D! -*
:A5$=A52([D!M
$57AT7 TA,L7 49,+T-S
(
'4L49,+T- N9#,75,
"+4D8'T4S PA$LGP5-"9$T-S,
"+,'.4/ N9#,75
!M
"ara modi%icar un varray almacenado, primero &ay que seleccionarlo en una variable
"L#SQL. Luego se modi%ica la variable y se vuelve a almacenar en la tabla.
La utiliBaci!n e :A55AIS en la 6ase e atos estC co%&leta%ente esaconse'aa.

,9LL $-LL7$T
PL/SQL nos permite leer varios registros en una tabla de "L con un <nico acceso a trav6s de
la instruccin,9LL $-LL7$T.
,sto nos permitir$ reducir el n<mero de accesos a disco, por lo que optimi7aremos el
rendimiento de nuestras aplicaciones. 'omo contrapartida el consumo de memoria ser$ mayor.
"7$LA57
TIP7 tLdescripcion IS TA,L7 -* "-.S,S.D,S'+."'.4/aTIP7M
TIP7 tLcontinente IS TA,L7 -* "-.S,S.'4/T./,/T,aTIP7M
vLdescripcion tLdescripcionM
vLcontinente tLcontinenteM

,7;IN
S7L7$T D,S'+."'.4/,
'4/T./,/T,
,9LL $-LL7$T INT- vLdescripcion, vLcontinente
*5-# "-.S,SM
*-5 i IN vLdescripcion.*I5ST .. vLdescripcion.LAST L--P
dbmsLoutput.putLline(vLdescripcion(i! KK Y, Y KK vLcontinente(i!!M
7N" L--PM
7N"M
#
"odemos utili7ar ,9LL $-LL7$T con registros de "L.
"7$LA57
TIP7 "-.S IS 57$-5" ('4L"-.S N9#,75 ,
D,S'+."'.4/ :A5$=A52(@D!,
'4/T./,/T, :A5$=A52(BD!!M
TIP7 tLpaises IS TA,L7 -* "-.SM
vLpaises tLpaisesM
,7;IN
S7L7$T '4L"-.S, D,S'+."'.4/, '4/T./,/T,
,9LL $-LL7$T INT- vLpaises
*5-# "-.S,SM

*-5 i IN vLpaises.*I5ST .. vLpaises.LAST L--P
dbmsLoutput.putLline(vLpaises(i!.D,S'+."'.4/ KK
Y, Y KK vLpaises(i!.'4/T./,/T,!M
7N" L--PM
7N"M
#
Tambien podemos utili7ar el atributo 5-<TIP7.
"7$LA57

TIP7 tLpaises IS TA,L7 -* "-.S,Sa5-<TIP7M
vLpaises tLpaisesM
,7;IN
S7L7$T '4L"-.S, D,S'+."'.4/, '4/T./,/T,
,9LL $-LL7$T INT- vLpaises
*5-# "-.S,SM

*-5 i IN vLpaises.*I5ST .. vLpaises.LAST L--P
dbmsLoutput.putLline(vLpaises(i!.D,S'+."'.4/ KK
Y, Y KK vLpaises(i!.'4/T./,/T,!M
7N" L--PM
7N"M
#
Transacciones
8na transaccin es un conjunto de operaciones que se ejecutan en una base de datos, y que
son tratadas como una <nica unidad lgica por el S:(D.
,s decir, una transaccin es una o varias sentencias SQL que se ejecutan en una base de
datos como una <nica operacin, con%irmandose o des&aciendose en grupo.
/o todas las operaciones SQL son transaccionales. Slo son transaccionales las
operaciones correspondiente al "#L, es decir,
sentencias S7L7$T, INS75T, 9P"AT7 y "7L7T7
"ara con%irmar una transaccin se utili7a la sentencia $-##IT. 'uando
reali7amos $-##IT los cambios se escriben en la base de datos.
"ara des&acer una transaccin se utili7a la sentencia 5-LL,A$L. 'uando
reali7amos 5-LL,A$L se des&acen todas las modi%icaciones reali7adas por la transaccin en
la base de datos, quedando la base de datos en el mismo estado que antes de iniciarse la
transaccin.
8n ejemplo cl$sico de transaccin son las trans%erencias bancarias. "ara reali7ar una
trans%erencia de dinero entre dos cuentas bancarias debemos descontar el dinero de una
cuenta, reali7ar el ingreso en la otra cuenta y grabar las operaciones y movimientos necesarios,
actuai7ar los saldos ... .Si en alguno de estos puntos se produce un %allo en el sistema
podr)amos &acer descontado el dinero de una de las cuentas y no &aberlo ingresado en la otra.
"or lo tanto, todas estas operaciones deben ser correctas o %allar todas. ,n estos casos, al
con%irmar la transaccion ('455.T! o al des&acerla (+4LL(-';! garanti7amos que todos los
datos quedan en un estado consistente.
,n una transaccin los datos modi%icados no son visibles por el resto de usuarios &asta que
se con%irme la transaccin.
,l siguiente ejemplo muestra una supuesta transaccin bancaria*
"7$LA57
importe N9#,75M
cta4rigen :A5$=A52(BP!M
ctaDestino :A5$=A52(BP!M
,7;IN
importe *X >DDM
cta4rigen *X YB@PD >D BDDD >BP=@[A?]DYM
ctaDestino *X YB@PB >D BD>D D]?A[@=PB>YM
9P"AT7 '8,/T-S S7T S-LD4 X S-LD4 importe
<=757 '8,/T- X cta4rigenM
9P"AT7 '8,/T-S S7T S-LD4 X S-LD4 ^ importe
<=757 '8,/T- X ctaDestinoM
INS75T INT- 541.5.,/T4S
('8,/T-L4+.:,/, '8,/T-LD,ST./4,.5"4+T,, 9,'V-L541.5.,/T4!
:AL97S
(cta4rigen, ctaDestino, importeU(>!, S3SD-T,!M
INS75T INT- 541.5.,/T4S
('8,/T-L4+.:,/, '8,/T-LD,ST./4,.5"4+T,, 9,'V-L541.5.,/T4!
:AL97S
(ctaDestino,cta4rigen, importe, S3SD-T,!M
$-##ITM
78$7PTI-N
<=7N -T=75S T=7N
dbmsLoutput.putLline(Y,rror en la transaccion*YKKSQL,++5!M
dbmsLoutput.putLline(YSe des&acen las modi%icaciones!M
5-LL,A$LM
7N"M
Si alguna de las tablas a%ectadas por la transaccin tiene triggers, las operaciones que
reali7a el trigger est$n dentro del ambito de la transaccin, y son con%irmadas o des&ec&as
conjuntamente con la transaccin.
Durante la ejecucin de una transaccin, una segunda transaccin no podr$ ver los cambios
reali7ados por la primera transaccin &asta que esta se con%irme.
4+-'L, es completamente transaccional. Siempre debemos especi%icar si que queremos
des&acer o con%irmar la transacion.

Transacciones aut!no%as
,n ocasiones es necesario que los datos escritos por parte de una transaccin sean
persistentes a pesar de que la transaccion se des&aga con 5-LL,A$L.
"L#SQL permite marcar un bloque con P5A;#A A9T-N-#-9SGT5ANSA$TI-N. 'on
esta directiva marcamos el subprograma para que se comporte como transaccin di%erente a la
del proceso principal, llevando el control de $-##IT o 5-LL,A$L independiente.
4bservese el siguiente ejemplo. "rimero creamos un procedimiento y lo marcamos
con P5A;#A A9T-N-#-9SGT5ANSA$TI-N.
$57AT7 -5 57PLA$7 P5-$7"957 :rabarLLog(descripcion :A5$=A52!
IS
P5A;#A A9T-N-#-9SGT5ANSA$TI-NM
,7;IN
INS75T INT- L4:L-"L.'-'.4/
('4L,++4+, D,S'+.".'.4/, 90L,++4+!
:AL97S
(SQL,++4+./,0T1-L, descripcion, S3SD-T,!M
$-##ITM ,ste commit solo a%ecta a la transaccion autonoma
7N" M
- continuacin utili7amos el procedimiento desde un bloque de "L#SQL*
"7$LA57
producto "+,'.4SNTIP7M
,7;IN
producto *X Y>DD@]]YM
INS75T INT- "+,'.4S
('4L"+4D8'T4, "+,'.4, 90L-LT-!
:AL97S
(producto, >@D, S3SD-T,!M
$-##ITM
78$7PTI-N
<=7N -T=75S T=7N
:rabarLLog(SQL755#!M
5-LL,A$LM
#U Los datos grabados por O:rabarLLogO se escriben en la base
de datos a pesar del +4LL(-';, ya que el procedimiento est$
marcado como transaccin autonoma.
U#
7N"M
,s muy com<n que, por ejemplo, en caso de que se produ7ca alg<n tipo de error
queramos insertar un registro en una tabla de log con el error que se &a produccido y &acer
+4LL(-'; de la transaccin. "ero si &acemos +4LL(-'; de la transaccin tambien lo
&acemos de la insertcin del log.
SQL "ina%ico
Sentencias "#L con SQL ina%ico
"L#SQL o%rece la posibilidad de ejecutar sentencias SQL a partir de cadenas de caracteres.
"ara ello debemos emplear la instruccin 787$9T7 I##7"IAT7.
"odemos obtener in%ormacin acerca de n<mero de %ilas a%ectadas por la instruccin
ejecutada por 78789T7 I##7"IAT7 utili7ando SQLN5-<$-9NT.
,l siguiente ejemplo muestra la ejecucin de un comando SQL dinamico.
"7$LA57
ret N9#,75M
*9N$TI-N %nLexecute 57T95N N9#,75 IS
sqlLstr :A5$=A52(>DDD!M
,7;IN
sqlLstr *X Y8"D-T, D-T4S S,T /45(+, X YY/8,14 /45(+,YY
2V,+, '4D.:4 X >YM
787$9T7 I##7"IAT7 sqlLstrM
57T95N SQLN5-<$-9NTM
7N" %nLexecute M
,7;IN
ret *X %nLexecute(!M
dbmsLoutput.putLline(T-G$=A5(ret!!M
7N"M
"odemos adem$s parametri7ar nuestras consultas a trav6s de variables &ost. 8na variable
&ost es una variable que pertenece al programa que est$ ejecutando la sentencia SQL
din$mica y que podemos asignar en el interior de la sentencia SQL con la palabra
clave 9SIN; . Las variables &ost van precedidas de dos puntos O*O.
,l siguiente ejemplo muestra el uso de variables &ost para parametri7ar una sentencia SQL
dinamica.
"7$LA57
ret N9#,75M
*9N$TI-N %nLexecute (nombre :A5$=A52, codigo N9#,75! 57T95N
N9#,75
IS
sqlLstr :A5$=A52(>DDD!M
,7;IN
sqlLstr *X Y8"D-T, D-T4S S,T /45(+, X *neZLnombre
2V,+, '4D.:4 X *codigoYM
787$9T7 I##7"IAT7 sqlLstr 9SIN; nombre, codigoM
57T95N SQLN5-<$-9NTM
7N" %nLexecute M
,7;IN
ret *X %nLexecute(YDevjoNerY,>!M
dbmsLoutput.putLline(T-G$=A5(ret!!M
7N"M
$ursores con SQL inC%ico
'on SQL din$mico tambi6n podemos utili7ar cursores.
"ara utili7ar un cursor implicito solo debemos construir nuestra sentencia S,L,'T en una
variable de tipo caracter y ejecutarla con ,0,'8T, .55,D.-T, utili7ando la palabra clave
./T4.
"7$LA57
strLsql :A5$=A52(B@@!M
lLcnt :A5$=A52(BD!M
,7;IN
strLsql *X YS,L,'T count(U! 9+45 "-.S,SYM
787$9T7 I##7"IAT7 strLsql INT- lLcntM
dbmsLoutput.putLline(lLcnt!M
7N"M
Trabajar con cursores explicitos es tambi6n muy %$cil. enicamente destacar el uso de 57*
$95S-5 para declarar una variable para re%erirnos al cursor generado con SQL dinamico.
"7$LA57
TIP7 '8+LT3" IS 57* $95S-5M
cLcursor $95GTIPM
%ila "-.S,SN5-<TIP7M
vLquery :A5$=A52(B@@!M
,7;IN
vLquery *X YS,L,'T U 9+45 "-.S,SYM

-P7N cLcursor *-5 vLqueryM
L--P
*7T$= cLcursor INT- %ilaM
78IT <=7N cLcursorNN-T*-9N"M
dbmsLoutput.putLline(%ila.D,S'+."'.4/!M
7N" L--PM
$L-S7 cLcursorM
7N"M
Las varibles &ost tambien se pueden utili7ar en los cursores.
"7$LA57
TIP7 curLtyp IS 57* $95S-5M
cLcursor $95GTIPM
%ila "-.S,SN5-<TIP7M
vLquery :A5$=A52(B@@!M
codigoLpais :A5$=A52(P! *X Y,S"YM
,7;IN
vLquery *X YS,L,'T U 9+45 "-.S,S 2V,+, '4L"-.S X *cpaisYM
-P7N cLcursor *-5 vLquery 9SIN; codigoLpaisM
L--P
*7T$= cLcursor INT- %ilaM
78IT <=7N cLcursorNN-T*-9N"M
dbmsLoutput.putLline(%ila.D,S'+."'.4/!M
7N" L--PM
$L-S7 cLcursorM
7N"M

*unciones integraas e PL/SQL
"L#SQL tiene un gran n<mero de %unciones incorporadas, sumamente <tiles. - continuacin
vamos a ver algunas de las m$s utili7adas.
SIS"AT7
Devuelve la %ec&a del sistema*
S7L7$T SIS"AT7 *5-# D8-LM
N:L
Devuelve el valor recibido como par$metro en el caso de que expresin sea /8LL,o
expresin en caso contrario.

N:L(&expresion', &valor'!
,l siguiente ejemplo devuelve D si el precio es nulo, y el precio cuando est$ in%ormado*
S7L7$T '4L"+4D8'T4, N:L("+,'.4, D! *5-# "+,'.4SM
"7$-"7
Decode proporciona la %uncionalidad de una sentencia de control de %lujo if-elseif-else.
"7$-"7(&expr'- &cond,'- &val,'1- $$$- &condN'- &valN'2- &default'!
,sta %uncin eval<a una expresin O&expr'", si se cumple la primera condicin
O&cond,'" devuelve el valor>"&val,'", en caso contrario eval<a la siguiente condicin
y as) &asta que una de las condiciones se cumpla. Si no se cumple ninguna condicin se
devuelve el valor por de%ecto.
,s muy com<n escribir la %uncin D,'4D, identada como si se tratase de un bloque .9.
S7L7$T "7$-"7 (coLpais, #U ,xpresion a evaluar U#
Y,S"Y, Y,S"-`-Y, #U Si coLpais X Y,S"Y XXF Y,S"-`-Y U#
Y5,0Y, Y5,0.'4Y, #U Si coLpais X Y5,0Y XXF Y5,0.'4Y U#
Y"-.S YKKcoLpais!#U ,LS, XXF concatena U#
*5-# "-.S,SM
T-G"AT7
'onvierte una expresin al tipo %ec&a. ,l par$metro opcional %ormato indica el %ormato de
entrada de la expresin no el de salida.
T-G"AT7(&expresion'- 1&formato'2!
,n este ejemplo convertimos la expresion YD>#>B#BDD[Y de tipo 'V-+ a una %ec&a (tipo
D-T,!. 'on el par$metro %ormato le indicamos que la %ec&a est$ escrita como d)amesaCo
para que devuelve el uno de diciembre y no el doce de enero.
S7L7$T T-G"AT7(YD>#>B#BDD[Y,
YDD#55#3333Y!
*5-# D8-LM
,ste otro ejemplo muestra la conversin con %ormato de d)a y &ora.
S7L7$T T-G"AT7(YP>#>B#BDD[ BP*@]*@]Y,
YDD#55#3333 VVB=*5.*SSY!
*5-# D8-LM
T-G$=A5
'onvierte una expresin al tipo 'V-+. ,l par$metro opcional %ormato indica el %ormato
de salida de la expresin.
T-G$=A5(&expresion'- 1&formato'2!
S7L7$T T-G$=A5(SIS"AT7, YDD#55#33333Y!
*5-# D8-LM
T-GN9#,75
'onvierte una expresion al%anum6rica en numerica. 4pcionalmente podemos especi%icar el
%ormato de salida.
T-GN9#,75(&expresion'- 1&formato'2!

S7L7$T T-GN9#,75 (Y>DY!
*5-# D8-LM
T59N$
Trunca una %ec&a o n<mero.
Si el par$metro recibido es una %ec&a elimina las &oras, minutos y segundos de la misma.
S7L7$T T59N$(S3SD-T,!*5-# D8-LM
Si el par$metro es un n<mero devuelve la parte entera.
S7L7$T T59N$(].]]!*5-# D8-LM
L7N;T=
Devuelve la longitud de un tipo 'V-+.
S7L7$T L7N;T=(YV4L- 58/D4Y!*5-# D8-LM
INST5
(usca una cadena de caracteres dentro de otra. Devuelve la posicion de la ocurrencia de la
cadena buscada.
Su sintaxis es la siguiente*
INST5(&char'- &search_string'- &startpos'- &occurrence' !
S7L7$T INST5(Y-Q8. ,S D4/D, S, (8S'-Y, Y(8S'-Y, >, > !
*5-# D8-LM
57PLA$7
+eempla7a un texto por otro en un expresion de busqueda.
57PLA$7(&expresion'- &bus%ueda'- &reempla<o'!
,l siguiente ejemplo reempla7a la palabra YV4L-Y por Y1-3-Y en la cadena YV4L- 58/D4Y.
S7L7$T 57PLA$7 (YV4L- 58/D4Y,YV4L-Y, Y1-3-Y! devuelve 1-3-
58/D4
*5-# D8-LM
S9,ST5
4btiene una parte de una expresion, desde una posicin de inicio &asta una determinada
longitud.
S9,ST5(&expresion'- &posicion_ini'- &longitud' !
S7L7$T S9,ST5(YV4L- 58/D4Y, [, @! Devuelve 58/D4
*5-# D8-LM
9PP75
'onvierte una expresion al%anumerica a may<sculas.
S7L7$T 9PP75(Y&ola mundoY! Devuelve V4L- 58/D4
*5-# D8-LM

L-<75
'onvierte una expresion al%anumerica a min<sculas.
S7L7$T L-<75(YV4L- 58/D4Y! Devuelve &ola mundo
*5-# D8-LM

5-<I"T-$=A5
'onvierte un +42.D a tipo caracter.
S7L7$T 5-<I"T-$=A5(+42.D!
*5-# D8-LM
5PA"
-Cade / veces una determinada cadena de caracteres a la derec&a una expresin. 5uy util
para generar %ic&eros de texto de anc&o %ijo.
5PA"(&expresion'- &longitud'- &pad_string' !
,l siguiente ejemplo aCade puntos a la expresion YVola mundoY &asta alcan7ar una longitud
de @D caracteres.
S7L7$T 5PA"(YVola 5undoY, @D, Y.Y!
*5-# D8-LM
LPA"
-Cade / veces una determinada cadena de caracteres a la i7quierda de una expresin. 5uy
util para generar %ic&eros de texto de anc&o %ijo.
LPA"(&expresion'- &longitud'- &pad_string' !
,l siguiente ejemplo aCade puntos a la expresion YVola mundoY &asta alcan7ar una longitud
de @D caracteres.
S7L7$T LPA"(YVola 5undoY, @D, Y.Y!
*5-# D8-LM
5T5I#
,limina los espacios en blanco a la derec&a de una expresion
S7L7$T 5T5I# (YVola 5undo Y!
*5-# D8-LM
LT5I#
,limina los espacios en blanco a la i7quierda de una expresion
S7L7$T LT5I# (Y Vola 5undoY!
*5-# D8-LM
T5I#
,limina los espacios en blanco a la i7quierda y derec&a de una expresion
S7L7$T T5I# (Y Vola 5undo Y!
*5-# D8-LM
#-"
Devuelve el resto de la divisin entera entre dos n<meros.
#-"(&dividendo'- &divisor' !
S7L7$T #-"(BD,>@! Devuelve el modulo de dividir BD#>@
*5-# D8-L

Secuencias
4+-'L, proporciona los objetos de secuencia para la generacin de cdigos numericos
autom$ticos.
Las secuencias son una solucin %$cil y elegante al problema de los codigos autogenerados.
L- sintaxis general es la siguiente*
$57AT7 S7Q97N$7 &secuence_name'
G#IN:AL97 Emin_valFH
G#A8:AL97 &max_val'2
GSTA5T <IT= &ini_val'2
GIN$57#7NT ,I &inc_val'2
GN-$A$=7 K $A$=7 &cache_val'2
G$I$L7H
G-5"75HM
,l siguiente ejemplo crea una secuencia "=_6>94?C+9"$
$57AT7 S7Q97N$7 SQL"+4D8'T4S
#IN:AL97 >
#A8:AL97 ]]]]]]]]]]]]]]]]]]]]]]]]]]]
STA5T <IT= >
IN$57#7NT ,I >
$A$=7 BDM
Se puede simpli%icar la orden, tomando los valores por de%ecto. ,l ejemplo anterior quedar)a
del siguiente modo*
$57AT7 S7Q97N$7 SQL"+4D8'T4SM
"ara obtener el siguiente valor de una secuencia debemos utili7ar la
%uncin N78T:AL. N78T:AL se puede utili7ar el cualquier sentencia
SQL "#L (S7L7$T, INS75T, 9P"AT7!.
S7L7$T SQL"+4D8'T4S.N78T:AL
*5-# D8-LM
"odemos obtener el <ltimo valor generado por la secuencia con la %uncin $955:AL. "ara
poder ejecutar la %uncin '8++1-L debemos &aber ejecutado previamente la
%uncin N78T:AL.
S7L7$T SQL"+4D8'T4S.$955:AL
*5-# D8-LM
"ara eliminar una secuencia de%initivamente de la base de datos debemos utili7ar la
sentencia "5-P.
"5-P S7Q97N$7 SQL"+4D8'T4S M

PL/SQL y Mava
4tra de la virtudes de "L#SQL es que permite trabajar conjuntamente con \ava.
"L#SQL es un excelente lenguaje para la gestion de in%ormacin pero en ocasiones,
podemos necesitar de un lenguaje de programacin m$s potente. "or ejemplo podr)amos
necesitar consumir un servicio 2eb, conectar a otro servidor, trabajar con SocNets .... "ara
estos casos podemos trabajar conjuntamente con "L#SQL y \ava.
"ara poder trabajar con \ava y "L#SQL debemos reali7ar los siguientes pasos*
'rear el programa \ava y cargarlo en la base de datos.
'rear un program de recubrimiento (2rapper! de "L#SQL.
$reacion e -6'etos Mava en la 6ase e atos -5A$L7.
-5A$L7 incorpora su propia versin de la m$quina virtual \ava y del \+,. ,sta versin de
\ava se instala conjuntamente con -5A$L7.
"ara crear objetos \ava en la base de datos podemos utili7ar la uitlidad Load\ava
de -5A$L7 desde linea de comandos o bien crear objetos MA:A S-95$7 en la propia base
de datos.
La sintaxis para la creacin de MA:A S-95$7 en -5A$L7 es la siguiente.
$57AT7 Q-5 57PLA$7R AN" $-#PIL7
MA:A S-95$7
NA#7" E@ava"ourceNameF
AS
public class EclassNameF
I
&Aava code'
...
JM
,l siguiente ejemplo crea y compila una clase \ava 4racle\ava'lass en el interior de MA:A
S-95$7 9uentes\ava. 9n as&ecto %uy a tener en cuenta es Due los %Htoos e la clase
'ava Due Duera%os invocar ese PL/SQL e6en ser estaticos.
$57AT7 -5 57PLA$7 AN" $-#PIL7
MA:A S-95$7
NA#7" 9uentes\ava
AS
public class -racleMava$lass
I
public static String Saluda(String nombre!
I
return (OVola desde \avaO ^ nombre!M
J
J
M
8n mismo MA:A S-95$7 puede contener varias clases de \ava.
$57AT7 -5 57PLA$7 AN" $-#PIL7
MA:A S-95$7
NA#7" 9uentes\ava
AS
public class -racleMava$lass
I
public static String Saluda(String nombre!
I
return (OVola desde \avaO ^ nombre!M
J
J
public class -racleMava#e'oraa
I
public static String Saludo5ejorado(String nombre!
I
return (OSaludo mejorado desde \ava para*O ^ nombre!M
J
J
M
La otra opcin ser)a guardar nuestro codigo java en el arc&ivo 4racle\ava'lass.java,
compilarlo y cargarlo en-5A$L7 con Load\ava.
- continuacin se muestran ejemplos del uso de la utilidad Load\ava
loaMava &elp
loaMava u usario#passZord v % r 4racle\ava'lass.class
loaMava u usario#passZord v % r 4racle\ava'lass.java
7'ecuci!n e &rogra%as Mava con PL/SQL
8na ve7 que tenemos listo el programa de \ava debemos integrarlo con "L#SQL. ,sto se
reali7a a trav6s de subprogramas de recubrimiento llamados 2rappers.
No &oe%os crear un <ra&&er en un 6loDue anoni%o.
La sintaxis general es la siguiente*
$57AT7 G-5 57PLA$7H
*9N$TI-NKP5-$7"957 &name' G(&params'-$$$!H
G57T95N &tipo'H
ISKAS
LAN;9A;7 MA:A NA#7
Y&clase'.&metodo' Greturn &tipo'HY M
,l siguiente ejemplo muestra el 2rapper para nuestra %uncin Saludo.
$57AT7 -5 57PLA$7
*9N$TI-N SaludaLZrap (nombre :A5$=A52!
57T95N :A5$=A52
AS
LAN;9A;7 MA:A NA#7
Y4racle\ava'lass.Saluda(java.lang.String! return java.lang.StringYM
8na ve7 creado el Zrapper, podremos ejecutarlo como cualquier otra %uncion o procedure de
"L#SQL. Debemos crear un Zrapper por cada %uncin java que queramos ejecutar desde
"L#SQL.
'uando ejecutemos el Zrapper, es decir, la %uncin OSaludaLZrapO, internamente
se ejecutar$ la clase java y se invocar$ el m6todo est$tico O4racle\ava'lass.SaludaO.

9n as&ecto a tener en cuenta es Due es necesario &ro&orcionar el no%6re el ti&o 'ava
co%&leto, es ecir, e6e%os es&eci)icar 'ava.lang.String en lugar e (nica%ente String.
S7L7$T S-L8D-L2+-"(YD,1\4;,+Y!
*5-# D8-LM
La ejecucin de este ejemplo en SQLU"lus genera la siguiente salida*
SQLF S,L,'T S-L8D-L2+-"(YD,1\4;,+Y! 9+45 D8-LM
S-L8D-L2+-"(YD,1\4;,+Y!

Vola desde \avaD,1\4;,+


8na recomendacin de diseCo ser)a agrupar todos los 2rapper en un mismo paquete.
,n el caso de que nuestro programa \ava necesitase de pacNages \ava adicionales,
deberiamos cargarlos en la base de datos con la utilidad Load\ava.

S-ar putea să vă placă și