Manual PL SQL
Manual PL SQL
Manual PL SQL
V
V
V
½
denominada bloque.
ÿ
ÿ
!
"
Antes de hacer ningún bloque tenemos que ejecutar el siguiente comando en nuestra
ejemplo de un bloque
#$%$ %! 1-23456"
7 % ! ./ !$-(0
Este lenguaje suele tener unos tipos de datos compatibles con SQL para las columnas de las
Para declarar los datos en un bloque tenemos que utilizar una sintaxis como esta:
999
!
68';+()"
!
>=('?@)"
9999
Una de las ventajas de PL/SQL es que nos permite declarar una variable del mismo tipo que
otra variable o que una columna de una tabla. Esto lo hacemos con el atributo %TYPE.
Otra ventaja es que nos permite guardar el contenido de una fila entera de una tabla en una
%7 %! 45A"
Con esto ya podemos trabajar con variables dentro de nuestro bloque. Ahora tenemos que
ver las estructuras de control que podemos manejar dentro de nuestros bloques.
à
Las estructuras de control son básicamente las mismas que podemos utilizar en cualquier
lenguaje de programación.
<
=
2<
=
9999
2
<"
5=
"
Si queremos que nos vaya contando al revés, es decir de 5 hasta 0 por ejemplo, la sintaxis
seria la siguiente:
< #
& >2
79999999
99999
"
9999
5=
999
"
Es importante saber que en nuestros bloques PL/SQL es bastante práctico el uso de cursores.
sino que se guarda en un área de memoria a la que se accede mediante los nombrados
cursores. Para realizar una consulta en PL/SQL tenemos que guardar el resultado en
cursores. Esto es muy sencillo y basta con meter un INTO en las consultas. Un ejemplo seria
este:
%D #
& D 7
% & ÿ./
'E) #% 7
% # "
La variable que sigue al INTO recibe el valor de la columna. Por este motivo es importante
£
Las excepciones sirven para tratar los errores y mensajes. Oracle tiene una serie de
excepciones que son las más frecuentes y con las que la mayoría de la gente trabaja.
#! #
/
'?0)"
#7
#
/
'(0)"
! +7
#! +#7
7
% %! ./
%!-?@"
"
à
Bloques anónimos: Son los que no tienen nombre y comienzan con el DECLARE, es decir los
2
ÿ
"
ÿ2
!
"
"
En el formato distinguimos dos partes claramente, la cabecera donde esta el nombre del
Funciones: similares a los procedimientos pero con la función añadida de que pueden
devolver valores.
Si subís varias lineas y veis el ejemplo de control de excepciones, podéis ver que hemos
utilizado un atributo como DBMS_OUTPUT. Bien pues esto lo que nos permite es visualizar en
pantalla los resultados, tanto excepciones como mensajes. Lo utilizamos porque PL/SQL no
dispone de ordenes o sentencias que capturen datos introducidos por teclado, ni tampoco
Si queremos que un bloque nos pida algún dato tenemos que anteponer el símbolo & delante
de la variable, de esta forma cuando el bloque llegue a ese punto nos pedirá por pantalla el
valor.
Otra sentencia importante es la que nos permite visualizar los errores que hemos podido
También podemos guardar los bloques anónimos en ficheros para poderlos ejecutar
# %&
7
/
Y para ejecutarlo primero tenemos que cargar el fichero en el buffer y para ello tenemos que
%&
7
/
Una vez cargado el fichero ejecutamos el bloque con la sentencia run nombrefichero.
O podemos hacer los dos pasos con una sola sentencia: start nombrefichero
Sin embargo para los procedimientos es totalmente distinto ya que al tener nombre se
almacena automáticamente en la base de datos y para ejecutarlo tan solo tenemos que
realizar la siguiente operación:
%&
$!
% '!
C%
)"
En el siguiente capitulo revisaremos todo lo que hemos visto en la introducción del PL/SQL,
Todo bloque debe acabar en . para que sea almacenado en el buffer SQL. Una vez guardado
lo podemos ejecutar con la orden ³run´. También podemos guardarlo en un fichero con la
siguiente orden:
Para cargar y ejecutar este bloque anónimo guardado en fichero ejecutaremos la siguiente
orden:
start nombrefichero
Pero también podemos cargarlo sin ejecutarlo con la orden ³get´ y luego ejecutarlo
Un ejemplo muy sencillo de bloque seria el que nos muestra en pantalla un nombre.
82$6696$',%& ,)"
"
Además en los bloques PL/SQL se pueden utilizar lo que llamamos variables de sustitución,
que nos pedirán datos por pantalla antes de ejecutar el bloque. Estas variables tienen que ir
Un ejemplo seria un bloque que nos pide el DNI de un usuario y nos muestra su nombre.
>%
9%&
4A"
%&
>% 7
%
./
<- ,H>$7,"
82$6696$ '>%)"
"
Como veis es bastante sencillo, pero no tienen tanta funcionalidad como los procedimientos
o funciones.
# Al quedar los bloques anónimos almacenados en el buffer, a no ser que se guardasen en ficheros,
se perderían al limpiar el buffer, cosa que no ocurre con los procedimientos y funciones, que se
Otra cosa que nos diferencia los bloques anónimos de los procedimientos o funciones es que
modificarlo si ya existe.
2
< >=('?0)"
% >=('?0)"
7+ %
<+% 7
%
./
%&
-%"
82$6696$', / %
:: %)"
"
Si el compilador detecta errores nos saldrá un mensaje como este: ³Procedimiento creado
con errores de compilación´. Para ver estos errores tenemos la orden SHOW ERRORS.
Al tener almacenado el procedimiento en la base de datos, este puede ser llamado por
cualquier usuario que tenga los permisos oportunos. Para invocar un procedimiento
Para invocar al procedimiento que hemos creado antes tendríamos que ejecutar la siguiente
orden:
EXECUTE ver_usuario('Luis');
# $ ',,)"
"
siguiente forma:
ë
Este lenguaje dispone de los mismo tipos de datos que podemos encontrar en SQL, pero
á| etc.
Además es importante señalar que el programador puede definir sus propios tipos de datos a
partir de los ya definidos.
º
Se utilizan para nombrar los objetos que intervienen en los programas PL/SQL como son las
Pueden tener como máximo 30 caracteres empezando siempre por una letra, que puede ir
seguida por otras letras, numeros, $, # ó _. Es importante destacar que PL/SQL no
Como doy por sentado que todos sabemos lo que son las variables, pasaremos directamente
No podemos indicar una lista de variables del mismo tipo y luego declarar el tipo, tenemos
68'(,0)"
%&
/
'@) 6 1-K2
K"
999
$%&
$'()%&
%TYPE: declara una variable del mismo tipo que otra, o que una columna de una tabla
%ROWTYPE : crea una variable registro cuyos campos se corresponden con las columnas de
una tabla o vista.
Por ejemplo si tenemos una variable definida previamente llamada cantidad podemos definir
4A"
De esta forma la variable total tendrá las mismas características que la variable cantidad.
Otro ejemplo seria declarar una variable que fuera del mismo tipo que la columna nombre de
la tabla profesor.
**
La variable será local para el bloque en el que ha sido declarada y global para los bloque
hijos de éste, mientras que las variables declaradas en los bloque hijos no son globales a los
bloques padre.
siguiente forma:
m
Asignación :=
AND
Lógicos OR
NOT
Concatenación ||
Is null
=
!=
<>
<
>
Comparación
<=
>=
between...and
like
in
y sus correspondientes negaciones
Aritméticos + - * / **
Ë
En PL/SQL tenemos las mismas funciones predefinidas que en SQL (AVG, MIN, MAX, COUNT,
SUM, etc), pero tenemos que tener dos cosas muy claras a la hora de utilizarlas y son:
1.| La función no modifica el valor de las variables o expresiones que se pasan como
valor nulo.
à
Podemos utilizar etiquetas para poder irnos a cualquier parte del programa utilizando la
sentencia GOTO siempre y cuando se cumplan las siguientes reglas:
valor de retorno.
excepciones.
artículos anteriores:
Ë
Las funciones son muy similares a los procedimiento con la diferencia que éstas siempre
devolverán un valor. Su estructura es la siguiente:
ÿ <6 %&
<
ÿ'!
C%
) 6 !
2 ÿ!
#
6 # ! "
ÿ
!
"
La cláusula RETURN de la cabecera nos especifica el tipo de valor que nos va a devolver la
función.
Además podemos hacer el paso de parámetros de un tipo a otro. Generalmente si los tipos
son compatibles PL/SQL lo hace automáticamente. En cualquier caso, podemos hacerlo de
en suposición.
á| Nominal: el símbolo => después del parámetro actual y antes del nombre del formal,
Para que esto quede más claro pasamos a escribir un ejemplo de paso de parámetros y
conversión de tipos.
6 ! % '
>=(
2999
Desde el siguiente bloque se podrán realizar las llamadas indicadas:
>='L0)
999
F F !
!
% '%$ !
% + )"
999
"
Esto nos pasaría los parámetros num_departamento al mismo tipo que n_departamento y
Los parámetros que soporta PL/SQL pueden ser de entrada, salida o entrada/salida
ÿ I 1- : <6J #
Además es importante recordar que al especificar parámetros debemos indicar el tipo, pero
no el tamaño.
Cuando creamos subprogramas con SQL * PLUS utilizando los comandos CREATE, Oracle
automáticamente compila el código fuente, genera el código objeto y los guarda en el
Para volver a compilar un subprograma almacenado utilizaremos la orden ALTER en vez del
CREATE y su formato es el siguiente:
Para ver el código de un subprograma almacenado podemos ejecutar una sentencia como
esta;
+ 262'+?+M0) 7
% 62$26 ./
% - ,%&
&!
%,"
# PL/SQL implementa la recursividad en los subprogramas, esto quiere decir, que un programa
En los anteriores capítulos hemos visto los fundamentos del lenguaje PL/SQL, bien pues, a
partir de ahora pasaremos a estudiar el manejo de este lenguaje para trabar con el gestor de
select mediante la clausula into a una variable. Pero esto es un problema cuando el resultado
de una subconsulta nos devolvía varias filas, porque esto nos daria un error al ejecutar la
consulta
Para que no nos salte un error en estos casos debemos utilizar los +
Los cursores explícitos los utilizamos cuando tenemos consultas que nos devuelven
2.| Apertura del cursor: Deberá colocarse en la zona de instrucciones, con el siguiente
formato:
%&
"
Si tenemos una única variable que recoge los datos de todas las columnas, el
formato de la variable seria el siguiente:
#
& %&
45A"
la cláusula select, por lo que serán del mismo tipo que las columnas.
>% >=('?()"
>! >=('(0)"
?"
"
2 ?"
"
interrumpirá.
á| $"
(
# devuelve verdadero si el cursor está abierto.
>% >=('?@)"
?"
"
2 ?"
"
En el ejemplo siguiente podemos observar que en la cláusula WHERE se incluye una variable
que se debería haber declarado previamente. Este tipo de variables reciben el nombre de
durante la recuperación de los datos con FETCH, el conjunto de filas que contiene el cursor
no variará.
2
>% >='?@)"
# N1-
N"
?"
82$6696$'>%)"
"
2 ?"
"
Si os fijáis en el siguiente ejemplo veréis que en la cláusula where se incluye una variable
que se deberá declarar previamente. Este tipo de variables recibe el nombre de variables de
!
!
#
$O
'
N #
/
()
2
# N #
/
('L)"
?
%&
7
% O
./
-# N"
#% #
/
('?@)"
# N1-
N"
?"
<=
? #%"
5=
?47
82$6696$'#%)"
<=
? #%"
"
2
?"
"
Ëm !mm
El trabajo normal de un cursor consiste en declarar un cursor, declarar una variable que
recogerá los datos del cursor, abrir el cursor, recuperar con fetch, una a una, las filas
Para resumir todas esas tareas, tenemos una estructura cursor FOR...LOOP que hace todas
nombreCursor
(
%&
+ ! +
7
% O
./
?(00"
< #
(
"
"
Un cursor puede tener parámetros; en este caso se aplicara el siguiente formato genérico:
62 %&
ÿ'!
C%
) 2 2
N
#
C
! C% "
Los parámetros formales indicados después del nombre del cursor tienen la siguiente
sintaxis:
%&
ÿ ! ÿI1-:<6J #
Todos los parámetros formales de un cursor son parámetros de entrada y su ámbito es local
al cursor por eso sólo pueden ser referenciados dentro de la consulta.
999
&
!
C%
/
% 7
%1
%&
ÿ'!
C%
)"
Los atributos de los cursores implícitos que se crean son los siguientes:
á| SQL%ISOPEN: Nos dice si el cursor esta cerrado, por lo que en teoría siempre nos
dará falso ya que Oracle cierra automáticamente el cursor después de cada orden
SQL.
Si se trata de un select into tenemos que tener en cuenta que solo puede devolver una única
Cuando un select into hace referencia a una función de grupo nuca se levantará la excepción
NO_DATA_FOUND y SQL%FOUND siempre será verdadero. Esto se explica porque las
funciones de grupo siempre devuelven algún valor (NULL se considera un valor).
Ê
"
Para realizar una actualización con un cursor tenemos que añadir la siguiente FOR UPDATE al
final de la declaración del cursor:
62 %&
$
< 6
Esto indica que las filas seleccionadas por el cursor van a ser actualizadas o borradas. Una
2
62
2 2 7
+
<8 %! 5=
$ !-%$ !
< 6"
45A"
68 ';)"
"
<=
"
5=
4<6
1-'
9
D?00 )E
"
<=
"
"
"
También podemos usar ROWID en lugar de FOR UPDATE. ROWID nos indicará la fila que se
va a actualizar. Para ello, al declarar el cursor en la cláusula SELECT indicaremos que
62 %&
$
2 2
%?+
%(+9995 <8 &"
Al ejecutarse el FETCH se guardará el número de fila en una variable y después ese número
se podrá usar en la cláusula WHERE de la actualización:
2
62
2 2 7
+
+5 <8 %! 5=
$ !-%$ !
< 6"
45A"
68 ';)"
"
<=
"
5=
4<6
1-'
9
D?00 )E
"
95"
<=
"
"
"
En este artículo del Manual de PL/SQL de Oracle vamos a ver lo que son las excepciones,
para qué sirven y cómo utilizarlas. Daremos un repaso también a los tipos de excepciones,
las excepciones definidas por el usuario y la sintaxis con la que tenemos que especificarlas.
Por último, de paso que vemos cosas acerca del tratamiento de errores en PL/SQL,
#
m
para definir qué se debe hacer frente a errores en sentencias definidas por el usuario.
Cuando se produce un error PL/SQL levanta una excepción y pasa el control a la sección
999999999
999999
999999
5= %&
$
!
=
"
999999
"
"
à
à
Son aquellas que crea el usuario. Para ello se requieren tres pasos:
nombre_excepción EXCEPTION
2.| Disparar o levantar la excepción mediante la orden raise: RAISE ;
999
%! $% "
999
999
< !
5 %B% %C % =
<"
999
999
"
m
Existen otros errores internos de Oracle que no tienen asignada una excepción, sino un
forma:
Su formato es el siguiente:
2$$'% $ +% O $ )"
Es importante saber que el número de error está comprendido entre -20000 y -20999 y el
mensaje es una cadena de caracteres de hasta 512 bytes.
Este procedimiento crea una excepción que solo puede ser tratada en WHEN OTHERS.
2
/
$
68"
2
/
/
$
7
% %! ./
$ %! - %! "
7 /
$
6 /
2$$'F(00?0+, / ,)"
7"
/(
Un ejemplo:
9999
! % -(0 ./
$%-?0*"
%% . S"
999
&
S .
S"
"
/
Este comando da por concluida la transacción actual y hace definitivos los cambios realizados
liberando las filas bloqueadas. Sólo después de que se ejecute commit tendremos acceso a
'3
Este comando da por concluida la transacción actual y deshace los cambios que se pudiesen
haber producido en la misma, liberando las filas bloqueadas. Se utiliza especialmente cuando
no se puede concluir una transacción porque se han levantado excepciones.
*
El número de savepoint esta limitado a 5 por sesión pero lo podemos modificar con la
siguiente sentencia:
'3
'3
Deshace el trabajo realizado después del punto indicado. Pero no se confirma el trabajo
!
!
!
& '7 %&
)
&
# ! "
# ! "
7 7-? /
&
S "
7 7-( /
&
S "
&
S "
7"
%%"
!
./ / /
&
S
! &"
Con este artículo terminamos la parte básica sobre oracle, PL/SQL y pasamos a lo que
siguiente artículo.
En el presente artículo vamos a estudiar acerca de los triggers, donde veremos qué son y
cómo se construyen, comenzando con los trigger de tablas y más tarde veremos los trigger
de sustitución y los de sistema. Para ello lo primero que tenemos que ver es su definición.
ë
bloques de código de los triggers están asociados a una tabla y se ejecutan automáticamente
Se suelen utilizar para prevenir transacciones erróneas y nos sirven también para
implementar restricciones de integridad o seguridad.
Su formato básico es el siguiente:
!
%&
$
%& $&
ÿ7
/ I
. : % : ./ '
)J
DE
% R
ED
ÿ
&
ÿ
!
!
"
4: nivel del disparo del trigger que por defecto es statement que significa que se
dispara una sola vez por cada operación independientemente del número de filas afectadas.
Variables posibles para update: la primera es :old que hace referencia a los valores
anteriores y :new que hace referencia a los nuevos valores de actualización de la fila.
á| Cuando el evento que dispara el trigger es un delete haremos referencia al valor :old
á| Cuando el evento que dispara el trigger es un insert haremos referencia al valor :new
á| Cuando el evento es un update tiene sentido hacer referencia a los dos valores.
á| Sólo se pueden utilizar cuando el trigger es a nivel de fila (for each row).
7 ! 7
%!
7
/
.
&
', / %7
, :: 19%$ %! )"
"
m
Una misma tabla puede tener varios triggers y el orden de disparo sería el siguiente:
1.| Antes de comenzar a ejecutar la orden que provoca el disparo se ejecutaran los
Cuanndo se dispara un trigger este forma parte de la operación que lo disparó de manera
que si el trigger falla, Oracle dará por fallida la operación completa. Aunque el fallo sea a
Ejemplo:
!
%&
$
& 7
&
7 /
99999
7 /
9999
7 ! /
999
7
9999
"
Podemos crear triggers que no se ejecutan antes ni después de una instrucción sino en lugar
de (instead of).
Solo podemos utilizar estos triggers si están asociados a vistas, además actúan siempre a
nivel de fila.
ÿ
!
%&
$
ÿ I : : ! J
%& #
ÿ 7
/
.
ÿ
&
ÿ
!
!
"
Sobre una vista podemos hacer un select pero si hacemos un insert, delete o update puede
Los trigger sobre vistas vas a sustituir a estas operaciones por las correspondientes en las
!
$&
$ %!
7 %!
7
/
.
&
7
% %! ./
%!$%-19
"
Estos trigger se disparan cuando se arranca o para la base de datos, entra o sale un usuario,
cuando se crea, modifica o elimina un objeto, etc.
En Oracle para crear este tipo de trigger tenemos que tener privilegios de Administer
database trigger.
ÿ
!
%&
$
I & :
/ %J ÿ./ '
)
!
'&N D23)
Donde la lista de eventos de definición puede tener uno o más eventos DDL separados por or
y la lista de eventos del sistema igualmente separados por or.
continuación os dejo una tabla de evento, momento y cuando se dispararía para dejarlo todo
mas o menos claro.
Oracle tiene algunas funciones que permiten acceder a los atributos del evento del disparo
ORA_YSEVENT, ORA_LOGIN, etc. Estas funciones pueden usarse en la clausula WHEN o en el
cuerpo del disparador. En el manual de Oracle podéis encontrar el listado de todas estas
funciones.
Un ejemplo seria un trigger que nos guarda los datos de un usuario al hacer login en la base
de datos:
!
7
&
&
$
'
+ %% + # )
"
En este artículo que pertenece al tutorial de Oracle trateremos el tema de los paquetes de
forma detenida.
Los paquetes en Oracle se utilizan para guardar subprogramas y otros objetos de la base de
datos.
ÿ
!
!
S %&
$!N
!T&
!
7
&!
%
%&
$!N "
La sintaxis del cuerpo sería la siguiente:
ÿ
!
!
S &G %&
$!N
!
#
&!
%
ÿ&
%& $!N "
DE &
ED
!
!
S &
$ %!
A $ $ %!
'%$ %! %! 9 %!$4A+
! %! 9! 4A+
%! 9 4A+
! % %! 9 !$4A)"
!
#
$!
$%
'#$
%! 9 %!$4A)"
!
#
$!
$! '#$! %! 9! 4A)"
7
'#$
%! 9 %!$4A)
$ $ %! "
&
$ %! "
DE ! ED
!
!
S &G &
$ %!
#$ %! $ $ %! "
!
#
$ %! " DE !
% !
#ED
!
#
$!
$%
'#$
%! 9 %!$4A)
&
%!$+ ! +
+ !$ #$ %! 7
% %! ./
%!$-#$
"
# $ %! "
!
#
$!
$! '#$! %! 9! 4A)
&
%!$+! +
+ !$ #$ %! 7
% %! ./
! -#$! "
# $ %! "
# $! $! "
7
'#$
%! 9 %!$4A)
$ $ %!
&
%!$+! +
+ !$ #$ %! 7
% %! ./
%!$-#$
"
!
#
$ %!
&
# $ %! "
&
$ %! "
Como podéis ver este paquete nos permite buscar un empleado de tres formas distintas y
Ê "
Podemos utilizar los objetos definidos en los paquetes básicamente de dos maneras
distintas:
á| Desde el mismo paquete: esto quiere decir que cualquier objeto puede ser utilizado
á| Desde fuera del paquete: Podemos utilizar los objetos de un paquete siempre y
cuando haya sido declarado en la especificación del mismo. Para llamar a un objeto o
En los paquetes también podemos introducir cursores, para ello debemos declararlo en la
cabecera del paquete indicando su nombre, los parámetros y tipo devuelto. Para que lo veáis
99999
999
%! "
9999
9999
%! "
2
1 7
$
/
G &
&%$
1 7
$!
$
&%$!1
7
!$
#(%7: sql dinámico significa que el programa es capaz de ejecutar órdenes de definición y manipulación
999999
$
1- 82$239$62"
82$2392'$
+
+82$239>L)"
#$% 1-82$2396'$
)"
82$2392$62'$
)"
999999
Lo que hacemos es abrir el cursor y nos devuelve el id del mismo para poder trabajar con él.