You are on page 1of 94

Oracle

Plsql 9i2005
manual del curso teleformedia. NIVEL II

Coleccin temtica del manual: Bases de


Datos
Propiedad del manual: Garben Consultores
Datos del autor del manual: Marta Costales
Prez
Datos del revisor del manual: Miguel
Paniagua Lpez de Haro

MANUAL DE PL/SQL PARA ORACLE 9i

objetivos unidad didctica 1


MANUAL DE PL/SQL PARA ORACLE 9i
Al finalizar el curso, los alumnos habrn aprendido a escribir procesos, funciones y paquetes
PL/SQL, a trabajar con los entornos Procedure
Builder y SQL*Plus y a crear y gestionar unidades de programa PL/SQL. Los alumnos habrn
aprendido tambin a usar algunos de los paquetes proporcionados por Oracle.
Aprender a almacenar en la Base de Datos Procedimientos, Funciones, Paquetes y Triggers.
Utilizar el entorno de programacin iSQL*Plus
para desarrollar dichas unidades de programa,
gestionar dependencias, adems de manipular
objetos de gran tamao (LOBs) y de utilizar los
paquetes PL/SQL proporcionados por Oracle.

1
3

ndice
HTML / ndice

ndice de contenido
UNIDAD DIDCTICA 1: PL/SQL PARA ORACLE 9i

LECCION 1: TEMAS GENERALES DE PL/SQL

INTRODUCCIN

1. BREVE HISTORIA

2. VENTAJAS DE USAR PL/SQL

3. ENTORNO DE PL/SQL

4. NUEVAS CARACTERSTICAS DE PL/SQL 9i

LECCIN 2: CONCEPTOS BSICOS PL/SQL


INTRODUCCIN

16
16

5. FUNDAMENTOS DE PL/SQL

16

6. BLOQUES

17

7. DECLARACIONES

18

8. EXPRESIONES Y COMPARACIONES

19

9. TIPOS DE DATOS

19

10. ESTRUCTURAS DE CONTROL

22

11. INTERACCIN CON ORACLE SERVER

24

12. DATOS COMPUESTOS

26

13. CURSORES

37

LECCIN 3. EXCEPCIONES, SUBPROGRAMAS PL/SQL Y TRIGGERS43


INTRODUCCION

43

14. EXCEPCIONES

43

15. SUBPROGRAMAS

48

16. DISPARADORES O TRIGGERS DE LA BASE DE DATOS 59

ENUNCIADOS EJERCICIOS DE REPASO.

77

SOLUCIONES EJERCICIOS DE REPASO.

80

GLOSARIO

85

/4

u.d. 1

leccin 1: Temas generales de Pl / Sql


unidad
didctica 1:

NIVEL II

PL/SQL PARA ORACLE 9i

LECCION 1: TEMAS GENERALES DE PL/SQL


INTRODUCCIN

Oracle, primero, introdujo Procedural Language/Structured Query Language (PL/SQL) en


la versin 6.0 de su Sistema de Gestor de Base de Datos Relacional (RDBMS). Mientras
que su RDBMS se desarroll, Oracle realiz cambios de desarrollo en el lenguaje PL/SQL,
introduciendo nuevas caractersticas y realzando caractersticas existentes.
PL/SQL incorpora la estructura de los lenguajes de tercera generacin (3GL), que en SQL
no se puede aplicar ya que es un lenguaje de cuarta generacin (4GL); esto significa que
utiliza las construcciones y los elementos que especifican qu hacer, sin tener que especificar cmo hacerlo. Es un lenguaje importante para Oracle RDBMS (tambin para otros
RDBMSs), y se ha utilizado para la definicin de los datos, consultas a la base de datos, y
manipulacin y control de datos. Sin embargo, hay situaciones que necesitan el uso de las
construcciones 3GL, tales como ejecuciones condicionales o iterativas de SQL. Este tipo de
flujo de la lgica y del control se puede alcanzar solamente en un lenguaje 3GL como Java,
C++, o C, para acomodar las caractersticas 3GL, Oracle dise e implement el lenguaje
PL/SQL como extensin procedural al SQL. PL/SQL se integra con SQL, y los dos sirven
como lenguajes principales del lado del servidor de la base de datos, aunque tambin se
puede utilizar PL/SQL en el lado del cliente.

1. BREVE HISTORIA
PL/SQL, primero, fue introducido en 1991 con Oracle 6.0. Fue proporcionado como la opcin
procedural del lado del servidor. Al mismo tiempo, fue introducido, posteriormente, en el
lado cliente con SQL * versin 3.0, de manera que tena su propio motor PL/SQL. La primera
versin fue PL/SQL 1.0, tena caractersticas procedurales muy limitadas. Pero, uno de sus
puntos fuertes era su capacidad para procesar las sentencias mltiples del SQL, mezcladas
con las construcciones procedurales.
PL/SQL tiene sus races en el ADA, un lenguaje de programacin de alto nivel. El concepto
del bloque PL/SQL se parece al concepto de estructura de bloque en el ADA que usa BEGIN
y END para delimitar dichos bloques. PL/SQL comparte otras caractersticas con el ADA, tal
como la sintaxis = utilizado para la comparacin y:= utilizada para la asignacin, manejo
de excepciones, y la sintaxis declarativa, para definir subprogramas almacenados.
Con el tiempo, Oracle subi con las nuevas versiones de PL/SQL. Con Oracle 7.0, Oracle
lanz PL/SQL 2.0, que convirti a Oracle en una base de datos activa con la capacidad
almacenar la lgica de negocio y lgica de la aplicacin en la base de datos bajo la forma
de procedimientos, funciones, y paquetes almacenados. Tambin defini la capacidad para
declarar registros y arrays, definidos por el programador bajo la forma de tablas PL/ SQL.
PL/SQL 2.1 entr con Oracle 7.1 y permiti el uso de funciones almacenadas en sentencias
SQL. Tambin, el SQL dinmico fue introducido en PL/SQL por primera vez con el paquete
de DBMS_SQL. Oracle 7.2 fue lanzado posteriormente, y junto con l vino PL/SQL 2.2. Tena
la capacidad para definir los wrappers binarios para los subprogramas almacenados de PL/
SQL, de manera que se oculta el cdigo para otros desarrolladores. Tambin fue introducido
el paquete DBMS_JOB, que permiti a lo programadores submitir trabajos dentro de la base
de datos. El lanzamiento siguiente PL/SQL era PL/SQL 2.3, que fue introducido con Oracle

/5

u.d. 1

leccin 1: Temas generales de Pl / Sql

NIVEL II

7.3. Realz las capacidades de las tablas PL/SQL con la capacidad de definir nuevos mtodos,
y tambin permiti a los programadores tener acceso al sistema de ficheros dentro de la
base de datos. Los ficheros I/O se podan hacer usando el paquete de UTL_FILE.
Oracle 8.x era una brecha importante en la historia de Oracle con la introduccin de objetos,
y Java en la base de datos. PL/SQL 8.x fue lanzado junto con Oracle 8.x y las caractersticas
importantes incluidas, tales como SQL dinmico nativo, procedimientos almacenados en
Java, y triggers a nivel de sistema y de esquema de la base de datos.
Finalmente, Oracle 9i fue lanzado, y junto con l vino PL/SQL 9.2 y 9.0, correspondiendo
a los lanzamientos 2 y 1 de este lanzamiento de Oracle 9i. En esta versin, se introduce
la compilacin nativa del cdigo PL/SQL, mejora de los cursores PL/SQL bajo la forma de
expresiones del cursor, nuevos tipos de datos, funciones canalizadas, herencia de verdad
entre objetos

2. VENTAJAS DE USAR PL/SQL


PL/SQL es un lenguaje estructurado en bloques, que permite encapsular la lgica del negocio
en un lugar. sta es la ventaja ms grande de PL/SQL.
Otras ventajas de usar PL/SQL son las siguientes:
Capacidades procedural
La ventaja primaria de PL/SQL es su capacidad para definir e implementar GL con instrucciones y sentencias embebidas de SQL. Usando PL/SQL, se puede implementar las capacidades estndares 3GL, tales como ayuda para los tipos de datos volanos, lgica secuencial,
condicional, e iterativa; arrays y subprogramas; y caractersticas orientadas a objetos.
La capacidad para definir las construcciones 3GL es, sobre todo, beneficiosa cuando se
utiliza PL/SQL en las aplicaciones que mezcla, y compara la lgica del negocio. PL/SQL es
un lenguaje procedural primario para las herramientas del lado del cliente de Oracle, tales
como Oracle Forms y Oracle Reports.

Portabilidad
Los programas escritos en PL/SQL son independientes del hardware y del sistema operativo.
Son altamente portables, y trabajan bien sobre cualquier plataforma donde estn instalados
un servidor y un entorno integrado de desarrollo (IDE) Oracle.

Fuerte integracin con SQL


Oracle ha integrado SQL y PL/SQL. Los programas escritos en PL/SQL pueden utilizar casi
todas las caractersticas del SQL, como tipos de datos de SQL y la construccin NULL.
Adems, Oracle 9i tiene un programa de anlisis integrado de SQL y de PL/SQL. Esto significa que el mismo programa de anlisis est utilizado para ambos cdigos, que da lugar
a un funcionamiento ms eficiente.

Modularidad
PL/SQL permite escribir programas como mdulos independientes que se pueden integrar.
Se puede ejecutar esta modularidad, utilizando procedimientos, funciones, y paquetes.

/6

NIVEL II

leccin 1: Temas generales de Pl / Sql

u.d. 1

Un funcionamiento mejor
PL/SQL ofrece un funcionamiento mejor por tres razones principales:
1. La conversin de tipos de datos no es necesaria en la entrada y salida.
2. Normalmente, las aplicaciones de la base de datos en un entorno cliente-servidor tienen
una arquitectura de dos niveles (Oracle en el servidor y PL/SQL en el cliente) o una estructura de tres capas (una capa del servidor de la base de datos, otra capa del servidor de las
aplicaciones en un servidor de aplicaciones, y una capa de presentacin en un cliente). Con
PL/SQL, se puede agrupar un conjunto de sentencias SQL (junto con la lgica de aplicacin)
en un bloque PL/SQL, y submitirlo al servidor de Oracle, mejorando el trfico de red. El
concepto de estructura de bloque tambin significa que habr pocas llamadas a la base de
datos, lo que da lugar a un mejor funcionamiento.
3. PL/SQL 9i introduce la compilacin nativa del cdigo PL/SQL, la conversin subsecuente
a C y el almacenamiento del cdigo mquina. Esto da lugar a una ejecucin ms rpida.
Antes de Oracle 9i, las versiones interpretadas del cdigo PL/SQL, conocidas como p-cdigo,
mostraban solamente la ejecucin ms rpida del PL/SQL.

Orientacin a objetos
PL/SQL proporciona caractersticas orientadas a objetos, como encapsulacin, abstraccin
(la capacidad de definir tipos de datos abstractos), los datos e informacin se ocultan, reutilidad, herencia, polimorfismo, y envo dinmico de mtodos.

3. ENTORNO DE PL/SQL
Para desarrollar y para ejecutar los programas 3GL, se necesita un entorno de desarrollo
en el que se pueda escribir y ejecutar los programas. A esto se le llama Entorno Integrado
de Desarrollo, o IDE. La mayora de los 3GLs como Java, C proporcionan IDEs, como Visual
Age for Java de IBM, y Visual C++, respectivamente.
Hay tres tipos de entornos necesarios para cualquier lenguaje de programacin, y PL/SQL
no es ninguna excepcin:

Entorno de desarrollo

Entorno de ejecucin

Entorno de eliminar errores

El entorno de ejecucin de
PL/SQL se podra representar
de la siguiente manera:

Imagen1-1-1

/7

u.d. 1

NIVEL II

leccin 1: Temas generales de Pl / Sql

Oracle proporciona dos ambientes importantes de desarrollo para el desarrollo y la ejecucin


de programas PL/SQL: SQL * Plus y Procedure Builder (Constructor de procedimientos).
Estos IDEs no slo permiten el desarrollo y la ejecucin, tambin permiten llevar un control
para eliminar errores de los programas PL/SQL. Sin embargo, el interfaz para cada uno de
estos ambientes es diferente. Ambos son interactivos, pero con el Procedure Builder se
proporciona un mayor grado de funcionalidad para eliminar errores.
En esta imagen se
muestra el entorno
de SQL*Plus.

Imagen1-1-2

Y en esta imagen se muestra el entorno de de Procedure Builder que es ms una herramienta


GUI, y tiene una capacidad de gran alcance para eliminar errores.

Imagen1-1-3

4. NUEVAS CARACTERSTICAS DE PL/SQL 9i


Se han agregado nuevas caractersticas a PL/SQL en Oracle 9i, algunas son nuevas caractersticas del propio lenguaje, otras son mejoras hechas a las caractersticas existentes, y
otras siguen siendo funcionalidades agregadas con respecto a cmo se ejecuta PL/SQL.
Para ver estas nuevas caractersticas, las dividiremos en dos grupos: las No orientadas a
objetos y las S orientadas a objetos.

4.1 CARACTERSTICAS NO ORIENTADAS A OBJETOS EXCLUSIVAS DE PL/SQL 9i


Sentencia CASE
Oracle 9i introduce la sentencia CASE como alternativa de mejora a la sentencia IF ELSIF.
El uso de esta sentencia proporciona un cdigo ms compacto y aumenta la utilidad por

/8

u.d. 1

leccin 1: Temas generales de Pl / Sql

NIVEL II

parte del programador, y la legibilidad por parte del revisor del cdigo. La sintaxis de la
sentencia CASE es:
CASE SELECT r
WHEN value1 THEN action1;
WHEN value2 THEN action2;
WHEN value3 THEN action3;
... ...
ELSE
actionN;
END CASE;

Donde SELECT r es una variable o una expresin, y value1, value2, y value3 son los valores
del SELECT r. El SELECT r se evala solamente una vez. En el caso de una sentencia CASE,
esto es evidente para el compilador, pues el SELECT r se especifica solamente una vez al
principio. La orden WHEN determina qu acciones se tienen que ejecutar.
Ejemplo:
CASE report_choice
WHEN 1 THEN p_proc_report1;
WHEN 2 THEN p_proc_report2;
WHEN 3 THEN p_proc_report3;
WHEN 4 THEN p_proc_report4;
ELSE dbms_output.put_line(Invalid option.);
END CASE;

Si todo esto se tuviera que hacer con una sentencia IF...ELSEIF... sera:
IF (report_choice=1) THEN
p_proc_report1;
ELSIF (report_choice=2) THEN
p_proc_report2;
ELSIF (report_choice=3) THEN
p_proc_report3;
ELSIF (report_choice=4) THEN
p_proc_report4;
ELSE
dbms_output.put_line(Invalid option.);

Expresin CASE
Se puede utilizar la construccin CASE en una expresin, y asignarla a una variable para
generar un valor. La sintaxis de la expresin CASE es:
var := CASE SELECT r
WHEN value1 THEN assigned_value1
WHEN value2 THEN assigned_value2
WHEN value3 THEN assigned_value3
... ...
ELSE assigned_valueN;
END CASE;

Donde var es una variable declarada que recibe un valor, value1, value2 y value3 son los valores del SELECT r, y assigned_value1, assigned_value2, assigned_value3, y assigned_valueN
son los valores que se asignan a la variable var, dependiendo del valor del SELECT r.
Como ejemplo, veremos un segmento del cdigo siguiente, que es parte de un programa
que convierte dgitos a las palabras:
temp := CASE i
WHEN 0 THEN Zero
WHEN 1 THEN One
WHEN 2 THEN Two

/9

u.d. 1

leccin 1: Temas generales de Pl / Sql


WHEN 3
WHEN 4
WHEN 5
WHEN 6
WHEN 7
WHEN 8
WHEN 9
ELSE
NULL
END;

THEN
THEN
THEN
THEN
THEN
THEN
THEN

NIVEL II

Three
Four
Five
Six
Seven
Eight
Nine

Sentencia de bsqueda CASE


Esta sentencia es una variante de CASE y no tiene ningn SELECT r definido. En vez de
probar la igualdad del SELECT r, prueba una expresin booleana para un valor verdadero.
La sintaxis es:
CASE
WHEN (boolean_condition1) THEN action1;
WHEN (boolean_condition2) THEN action2;
WHEN (boolean_condition3) THEN action3;
... ...
ELSE
actionN;
END CASE;

Ejemplo:
CASE
WHEN (report_choice = 1) THEN p_proc_report1;
WHEN (report_choice = 2) THEN p_proc_report2;
WHEN (report_choice = 3) THEN p_proc_report3;
WHEN (report_choice = 4) THEN p_proc_report4;
ELSE dbms_output.put_line(Invalid option.);
END CASE

Expresin de bsqueda CASE


Es una variante de la expresin CASE, y omite el SELECT r. Prueba para el valor verdadero
de una condicin booleana, en vez igualar un solo SELECT r, comn para todas las clusulas
WHEN.
Ejemplo:
temp := CASE
WHEN (i=0)
WHEN (i=1)
WHEN (i=2)
WHEN (i=3)
WHEN (i=4)
WHEN (i=5)
WHEN (i=6)
WHEN (i=7)
WHEN (i=8)
WHEN (i=9)
ELSE
NULL
END;

THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN
THEN

Zero
One
Two
Three
Four
Five
Six
Seven
Eight
Nine

Estas expresiones tienen mas alcance que las expresiones normales CASE, porque se pueden
utilizar para evaluar las mltiples condiciones que implican mltiples variables.

/ 10

u.d. 1

leccin 1: Temas generales de Pl / Sql

NIVEL II

Por ejemplo:
declare
a number := 20;
b number := -40;
string varchar2(50);
begin
string := case
when (a>b) then A es mayor que B
when (a<b) then A es menor que B
else
A es igual que B
end;
dbms_output.put_line(string);
end;
/

La salida de este programa sera:


A es mayor que B
Expresiones Cursor
Oracle 9i ha incorporado la facilidad para jerarquizar los cursores en las sentencias cursor
PL/SQL, bajo la forma de expresiones cursor. Estas expresiones eliminan la necesidad de
declarar y usar cursores mltiples, y, por lo tanto, dan lugar a un esquema ms eficaz
para la optimizacin del motor SQL (solamente una sentencia del SQL) que en el caso de
los cursores mltiples (sentencias mltiples del SQL). Oracle 9i quita la limitacin de usar
expresiones cursor en el SQL embebido en el cdigo PL/SQL. Ahora, se pueden utilizar
expresiones cursor como parte de los cursores PL/ SQL. Tambin, cuando se utiliza SQL
dinmico, se pueden utilizar y traer expresiones cursor en variables REF. En este caso,
soportan los enlaces complejos y es necesario definir cursores de referencia. Esto no es
soportado por DBMS_SQL.

Compilacin nativa del cdigo del PL/SQL


PL/SQL 9i permite la compilacin nativa de los paquetes PL/SQL, de los procedimientos, de
las funciones, de la conversin subsecuente al cdigo nativo de C y del almacenamiento
del cdigo mquina. PL/SQL se traduce a cdigo C antes que al p-cdigo, que est en modo
interpretado, utiliza el compilador C de la plataforma utilizada, y despus se enlaza directamente en procesos Oracle. Cuando se llama al subprograma almacenado particular, el
programa nativo compilado traza al rea global del programa (PGA). Esta compilacin nativa
del cdigo PL/SQL es la ms eficaz cuando se estn escribiendo subprogramas PL/SQL, que
realizan tareas independientes de la base de datos. En este caso, la compilacin nativa da
lugar a una ejecucin ms rpida de PL/SQL.

Operaciones DML que implican registros enteros PL/SQL


PL/SQL 9i como Oracle 9i, con la Release 2 permite operaciones INSERT y UPDATE que
implican registros enteros PL/SQL. En vez de especificar una lista de los atributos del registro
individualmente, se pueden insertar registros en la base de datos, usando una sola variable
del tipo RECORD o %ROWTYPE. Esto tambin se puede realizar con sentencias UPDATE.
Tambin, se puede hacer con las sentencias SELECT, FETCH, INSERT, UPDATE, y RETURNING TO y usar una sola variable del tipo PL/SQL tabla de registros, en vez de especificar
las tablas individuales PL/SQL para cada columna SQL.

/ 11

leccin 1: Temas generales de Pl / Sql

u.d. 1

NIVEL II

Arrays relacionados o asociados


Con la Oracle9i Release 2 se permite la definicin de ndices por tablas, que son indexados
por los valores VARCHAR2, en vez de BINARY_INTEGER. El ndice VARCHAR2 sirve como
clave primaria de una tabla de la base de datos y mejora el funcionamiento, permitiendo
operaciones de bsqueda rpidas de los elementos individuales del array, eliminando la
necesidad de saber la posicin del elemento individual, y evitando la colocacin a travs
de todos los elementos del array.

Nuevos paquetes PL/ SQL y mejoras de los paquetes existentes


PL/SQL 9i incorpora muchos paquetes nuevos y proporciona mejoras a los paquetes existentes. Los nuevos paquetes que merecen la mencin son el dbms_xmlgen, que se utiliza
para crear un documento XML de cualquier consulta de SQL (bajo la forma CLOB), y el
dbms_metadata, que tiene el interfaz de programacin de aplicaciones (API), para extraer
definiciones completas de los objetos de la base de datos en formato XML o como Lenguaje
de Definicin de Datos SQL (DDL). Otros nuevos paquetes son:
dbms_transform
dbms_xmlquery
dbms_xmlsave
dbms_aqelm
dbms_encode
dbms_fga
dbms_flashback
dbms_ldap
dbms_libcache
dbms_logmnr_cdc_publish
dbms_logmnr_cdc_subscribe
dbms_odci
dbms_outln_edit
dbms_redefinition
dbms_url
dbms_wm
dbms_types
utl_encode

Adems, Oracle 9i tiene tres nuevos tipos de datos especiales SQL, que permiten la encapsulacin dinmica y acceso para escribir descripciones, instancias de datos. Adems, se pueden
utilizar estos tres tipos especiales para crear tipos annimos, incluyendo la coleccin annima. Los tres tipos especiales son SYS.ANYTYPE, SYS.ANYDATA, y SYS.ANYDATASET.
De los paquetes mejorados, el paquete UTL_FILE, que proporciona el API para la entradasalida del archivo (I/O), tiene algunas mejoras con respecto a permitir la abertura, lectura,
y escritura de los archivos en formato Unicode.
El paquete de UTL_HTTP tiene nuevas caractersticas para apoyar la autentificacin, las
cookies, enviar mensajes grandes y conexiones persistentes.

Mejoras varias
Otras nuevas caractersticas son:

Integracin del programa de anlisis del SQL y del PL/SQL.

Integracin de CLOB con VARCHAR2.

Autogeneracin llamadas PL/SQL para procedimientos almacenados en Java. Caractersticas orientadas al objeto exclusivas a PL/a SQL 9i.

/ 12

leccin 1: Temas generales de Pl / Sql

u.d. 1

NIVEL II

4.2 CARACTERSTICAS ORIENTADAS A OBJETOS EXCLUSIVAS DE PL/SQL 9i


Bula Dinmico SQL y manejo de excepciones con Bulk Binding
Oracle 9i PL/SQL permite el Bulk Binding dinmico, el cual permite el uso de la construccin
BULK COLLECT para las sentencias SELECT, FORALL USING para INSERT, y las sentencias UPDATE y DELETE con la construccin EXECUTE INMEDIATE, para poder hacer el Bulk
Binding con el SQL dinmico nativo en PL/SQL. El Bulk Binding dinmico tambin soporta
las consultas implcitas en una sentencia DML, mediante la palabra clave RETURNING.
Una segunda nueva caracterstica de PL/SQL 9i es la capacidad dl volumen que trae una
variable cursor, usando SQL dinmico nativo.
Oracle 9i introduce la clusula SAVE EXCEPTIONS con el Bulk Binding, para permitir la
continuacin de la operacin en caso de excepciones.

Funciones TABLE canalizadas


Es una funcin PL/SQL que devuelve un resultset, y se puede llamar en la clusula FROM
de una sentencia SELECT de SQL. Antes de Oracle 9i, PL/SQL soportaba funciones de tabla,
pero en una forma elemental en las que solamente podan devolver colecciones de tipos a
nivel schema, y de tipos que no son de PL/SQL.
Ahora PL/SQL 9i, esta funcin puede:

Devolver un tipo PL/SQL basado en una tabla de registros.

Ser canalizado para poder devolver filas de datos incrementalmente, en vez de esperar
a la funcin para ejecutarse totalmente, y se almacenarn un sistema entero de filas
en memoria. La coleccin entera no necesita ser instanciada en memoria. Esto da
lugar a un tiempo de respuesta mejor y a menos consumo de memoria.

Eliminar la necesidad de almacenar datos en tablas intermedias.

Hacer ejecuciones paralelas, que mejora velocidad y la escalabilidad.

Colecciones de varios niveles


PL/SQL 9i introduce el concepto de colecciones jerarquizadas, o de colecciones de colecciones. El nivel del anidamiento puede estar a una profundidad arbitraria. Adems, las tablas
relacionadas pueden tener columnas de niveles mltiples de la coleccin.

Tipos de herencia de objetos y envo de mtodos dinmicos


PL/SQL 9i soporta el tipo herencia de objetos como parte de las caractersticas del modelo
de objetos relacional de Oracle 9i. Esta herencia se refiere a la capacidad para organizar
objetos como tipos, y tipos como tipo jerarquas. La jerarqua formada constituye una jerarqua del supertipo/subtipo, con los subtipos que heredan los atributos (datos) y los mtodos
(comportamiento) de sus supertipos. De hecho, un subtipo hereda todos los atributos y los
mtodos de todos sus supertipos.
La herencia conduce a la sustitucin y al envo dinmico del mtodo, o al polimorfismo
dinmico, como normalmente es llamado. PL/SQL 9i tambin soporta la sustitucin, que
es la capacidad para utilizar el valor de un subtipo.
Adems, soporta el envo dinmico de mtodos, que es la capacidad de determinar en tiempo

/ 13

u.d. 1

leccin 1: Temas generales de Pl / Sql

NIVEL II

de ejecucin para ejecutar el mtodo especfico de la jerarqua de objetos que corresponde


al tipo de objeto que invoca el mtodo.

Tipos Objetos SQLJ y Tipo de Evolucin


Oracle 9i, ahora, soporta persistencia de objetos de Java con los tipos y el tipo de evolucin
de objeto SQLJ. Los tipos del objeto SQLJ son tipos de objeto SQL del lenguaje Java. Se
pueden utilizar estos tipos en cualquier sitio que se pueda utilizar un tipo del objeto SQL,
tal como el tipo tabla de objeto, atributo de un tipo, o una columna de una objeto tabla
relacional. Se puede consultar y manipular objetos del esquema de SQL del tipo SQLJ.
El tipo de evolucin se refiere a la capacidad para cambiar los atributos y mtodos de un
tipo existente del objeto, sin tener que reconstruir el tipo y sus datos y todos sus tipos
dependientes.

Nueva API para cargar objetos grandes de archivos externos


Oracle 9i introduce dos funciones para cargar datos binarios y de carcter en los objetos
grandes binarios (BLOBs), y los objetos grandes del carcter (CLOBs) de archivos externos.
Estas funciones se han agregado al paquete DBMS_LOB PL/SQL API y son:
DBMS_LOB.LOADBLOBFROMFILE: Carga datos binarios de un archivo binario (BFILE) en
un BLOB.
DBMS_LOB.LOADCLOBFROMFILE: Carga datos de carcter de un BFILE en CLOB.

/ 14

final de leccin
FINAL DE LA LECCIN 1
Notas de trabajo del alumno:

Conclusiones:

Temas clave a recordar:

Oracle, primero, introdujo Procedural


Language/Structured Query Language (PL/
SQL) en la versin 6.0 de su Sistema de
Gestor de Base de Datos Relacional (RDBMS).
Mientras que su RDBMS se desarroll, Oracle
realiz cambios de desarrollo en el lenguaje
PL/SQL, introduciendo nuevas caractersticas
y realzando caractersticas existentes.

Hay tres tipos de entornos necesarios para


cualquier lenguaje de programacin, y PL/SQL
no es ninguna excepcin:

Entorno de desarrollo

Entorno de ejecucin

Entorno de eliminar errores

PL/SQL incorpora la estructura de los lenguajes de tercera generacin (3GL), que en SQL
no se puede aplicar, ya que es un lenguaje
de cuarta generacin (4GL); esto significa que
utiliza las construcciones y los elementos que
especifican qu hacer, sin tener que especificar cmo hacerlo.

/ 15

leccin 2: Conceptos bsicos Pl / Sql

u.d. 1

NIVEL II

LECCIN 2: CONCEPTOS BSICOS PL/SQL


INTRODUCCIN

El rea de contexto es la memoria designada para procesar una instruccin SQL, que incluye
el nmero de registros procesados, un apuntador a la representacin de la instruccin
SQL analizada y, en el caso de una consulta, el conjunto de registros que regresan de la
consulta.

5. FUNDAMENTOS DE PL/SQL
PL/SQL no es CASE-SENSITIVE
Una lnea en PL/SQL contiene grupos de caracteres conocidos como UNIDADES LEXICAS,
que pueden ser clasificadas como:

DELIMITADOR: Es un smbolo simple o compuesto que tiene una funcin especial en


PL/SQL

Operadores Aritmticos

Operadores Lgicos

Operadores Relacionales

IDENTIFICADOR: Son empleados para nombrar objetos de programas en PL/SQL, as


como a unidades dentro del mismo, estas unidades y objetos incluyen:

Constantes

Cursores

Variables

Subprogramas

Excepciones

Paquetes

LITERAL: Es un valor de tipo numrico, carcter, cadena o lgico no representado por


un identificador (es un valor explcito).

COMENTARIO: Son soportados 2 estilos de comentarios, el de lnea simple y de multilnea, para lo cual son empleados ciertos caracteres especiales, como son:

-- Lnea simple
/*
Conjunto de Lneas
*/
NOTA:
No pueden ser empleados en forma anidada

/ 16

NIVEL II

leccin 2: Conceptos bsicos Pl / Sql

u.d. 1

6. BLOQUES
A continuacin, se muestra cmo es la estructura general de los bloques de instrucciones
de PL/SQL, que se usarn ms adelante en la creacin de procedimientos, funciones y triggers.
PL/SQL agrega construcciones propias de lenguajes procedurales, obtenindose como resultado un lenguaje estructural ms poderoso que SQL. La unidad de programacin utilizada
por PL/SQL es el bloque. Todos los programas de PL/SQL estn conformados por bloques.
Normalmente, cada bloque lleva a cabo una accin lgica en el programa. Un bloque tendr
siempre la siguiente estructura:

DECLARE
//Seccin declarativa: variables, tipos, y subprogramas
//de uso local
BEGIN
//Seccin ejecutable: las instrucciones procedurales, y de SQL
//aparecen aqu. Es la nica seccin obligatoria en el bloque.
EXCEPTION
//Seccin de manejo de excepciones. Las rutinas de manejo de errores
//aparecen aqu
END;

Solo se requiere que aparezca la seccin ejecutable. Lo dems es opcional. Las nicas instrucciones SQL permitidas en un bloque PL/SQL son INSERT, UPDATE, DELETE y SELECT,
adems de algunas instrucciones para manipulacin de datos, e instrucciones para control
de transacciones. Otras instrucciones de SQL como DROP, CREATE o ALTER no son permitidas. Se permite el uso de comentarios estilo C (/*...*/). PL/SQL no es case sensitive, por lo
que no hay distincin entre nombres con maysculas y minsculas.
Los tipos de bloques que hay son:

Bloque annimo: Es una seccin del cdigo incluida dentro declaraciones BEGIN y
END. No tiene ningn nombre asociado a ella.

Bloque nombrado (Procedimiento): Esto es un bloque PL/SQL, almacenado en la base


de datos como subprograma e identificado por un nombre nico. Este bloque se pone
en ejecucin por medio de subprogramas y de triggers almacenados de la base de
datos.

Bloque etiquetado (Funcin): Esto es un bloque PL/SQL, identificado por una etiqueta.
Comienza con una etiqueta PL/SQL seguida por un BEGIN y una sentencia END.

Imagen1-2-1

/ 17

leccin 2: Conceptos bsicos Pl / Sql

u.d. 1

NIVEL II

7. DECLARACIONES
Los programas pueden emplear variables y constantes para almacenar valores, dichos identificadores son colocados en el rea de declaraciones de un bloque, como por ejemplo:
VARIABLES:
fecha
DATE
cuenta
SMALLINT :=0;
clave
VARCHAR2(5) NOT NULL := HZM030297;

CONSTANTES:
limite

CONSTANT REAL := 90000.00;

VARIANTES y AUXILIARES:

DEFAULT
num_max
SMALLINT DEFAULT 96;
valido BOOLEAN
DEFAULT FALSE;

%TYPE
credito
debito

NUMBER(7,2);
credito%TYPE;

%ROWTYPE
emp_reg
prueba%ROWTYPE;
CURSOR datos IS SELECT clave, nom, edad FROM prueba;
emp_reg2
datos%ROWTYPE;

En la seccin de declaraciones, se indican las variables, que sern usadas dentro del bloque
y sus tipos. Por ejemplo:
DECLARE
myBeer VARCHAR(20);
price NUMBER(6,2);

En algunos casos, es posible que se desee que el tipo de una variable coincida con el tipo
usado para una columna de una tabla determinada; en esos casos, se puede usar la construccin:
DECLARE
myBeer Beers.name%TYPE;

Con lo cual, se logra que la variable myBeer tenga el mismo tipo que la columna name de
la tabla Beers.
Tambin es posible inicializar las variables, mediante el operador:=. Adems, mediante
el uso del mismo operador es posible hacer asignaciones en el cuerpo del programa. Por
ejemplo:
DECLARE
price NUMBER := 300;
BEGIN
price := price + 150;
END;
run

La ejecucin de este bloque no tendr ningn efecto, ya que no se estn haciendo cambios
sobre la base de datos. Adems, es posible usar sentencias condicionales y ciclos dentro
de los bloques de PL/SQL.

/ 18

leccin 2: Conceptos bsicos Pl / Sql

u.d. 1

NIVEL II

8. EXPRESIONES Y COMPARACIONES
Algunas reglas importantes deben ser tomadas en cuenta al realizar una comparacin; a
continuacin, se listan algunas de ellas:
Las comparaciones que involucren valores NULL, siempre nos devolvern NULL.
Al aplicar el operador NOT a un valor NULL, devolver NULL.
Si una expresin condicional evala NULL, no se ejecutar NADA.
Si un argumento NULL es pasado a una funcin, sta devolver NULL.

Referencia de funciones

SQLCODE: Regresa el nmero asociado con el manejador de excepcin recientemente


empleado.

SQLERRM: Regresa el mensaje de error asociado con el valor actual de SQLCODE.

UID: Retorna el numero de identificacin nico, asignado para el usuario actual en


Oracle.

USER: Regresa el nombre del usuario actual en Oracle.

9. TIPOS DE DATOS
Cada constante y variable tiene un tipo de dato en el cual se especifica el formato de almacenamiento, restricciones y rango de valores vlidos.
PL/SQL proporciona una variedad predefinida de tipos de datos ESCALARES y COMPUESTOS, que contienen componentes internos que pueden ser manipulados en forma individual.
Casi todos los tipos de datos manejados por PL/SQL son similares a los soportados por
SQL.

9.1 DATOS ESCALARES


NUMBER (Numrico): Almacena nmeros enteros o de punto flotante, virtualmente de cualquier longitud, aunque puede ser especificada la precisin (Nmero de dgitos) y la escala,
que es la que determina cundo se llevar a cabo el redondeo.
NUMBER [(precisin, escala)]
CHAR (Carcter): Almacena datos de tipo carcter con una longitud mxima de 32767, y
cuyo valor de longitud por defecto es 1.
CHAR [(longitud _ mxima)]
VARCHAR2 (Carcter de longitud variable): Almacena datos de tipo carcter, empleando
slo la cantidad necesaria, aun cuando la longitud mxima sea mayor.
VARCHAR2 (longitud _ mxima)
BOOLEAN (lgico): Se emplea para almacenar valores TRUE o FALSE, pero no de tipo
NULL.
DATE (Fecha): Almacena datos de tipo fecha en el rango de ENERO 1 de 4712 A.C. a Diciembre 31 de 4712 D.C.

/ 19

u.d. 1

leccin 2: Conceptos bsicos Pl / Sql

NIVEL II

9.2 DATOS COMPUESTOS


Un dato de tipo compuesto tiene componentes internos que se pueden manipular individualmente. Estos datos son tambin conocidos como colecciones, y pueden ser de tipo
TABLE, RECORD, NESTED TABLE Y VARRAY.

TABLE
Una tabla es un tipo de dato compuesto, donde el tamao es ilimitado, ya que puede ser
incrementado de manera dinmica.
Una tabla esta formada por una columna y una llave primaria, donde la columna puede ser
de cualquier tipo escalar, y la clave primaria deber ser de tipo BINARY_INTEGER.
Debe ser declarada en 2 pasos bsicos:
Definir un TYPE TABLE
Definir el identificador de tipo TABLE
Ejemplo:
TYPE nombres_emp IS TABLE OF prueba.nom%TYPE
INDEX BY BINARY_INTEGER;
nom_tab nombres_emp;

Para hacer referencia a los elementos de una tabla, debe realizarse de la siguiente
manera:
nom_tab(1) := Alberto;

Es recomendable emplear un bucle para realizar la insercin de valores en la tabla.

RECORD e INDEX BY TABLE


Estos tipos de datos se utilizan para tratar datos relacionados, pero distintos como una
unidad lgica. Se tratarn ms detalladamente en el punto 1.8.

NESTED TABLE
Una tabla anidadas o jerarquizadas es un array unidimensional ilimitado y desordenado
de elementos del mismo tipo de datos. Es similar a Tablas INDEX-BY, salvo que la clusula
INDEX BY BINARY_INTEGER no est en su definicin. Un array de tablas anidadas no tiene
ningn lmite mximo y puede llegar a ser escaso, esto significa que los elementos en
cualquier ndice dinmico pueden ser suprimidos. Por eso, se debe crear una tabla anidada
con todos sus elementos en una orden secuencial. El nmero mximo de elementos en una
tabla anidada es 2GB.
Una tabla anidada es, generalmente, un array unidimensional, a menos que est definida
de otra manera a una coleccin de niveles mltiples; en este caso, simula un array de ms
de una dimensin.

VARRAY
Son los arrays uni-dimensionales que estn limitados por un nmero mximo de elementos.
Se utilizan para almacenar un nmero fijo de elementos en un array definido. Esto ayuda a
materializar colecciones de tamao fijo.

/ 20

leccin 2: Conceptos bsicos Pl / Sql

u.d. 1

NIVEL II

NOTA:
Los tipos NESTED TABLE y VARRAY se vern ms detalladamente en la unidad de PL/SQL Avanzado.

9.3 DATOS LOB


Con este tipo de datos se pueden almacenar bloques de datos no estructurados, como texto,
imgenes, vdeos, y formatos de sonido, como mximo de 4GB. Estos datos permiten un
acceso ms eficiente y dinmico a los datos.
Los tipos que hay son:

CLOB
Un CLOB es un objeto grande de carcter, que puede almacenar hasta 4GB de datos tipo
carcter. CLOBs es de dos tipos, CLOB y NCLOB.
CLOB se refiere a datos carcter en el juego de caracteres de la base de datos. NCLOB se
refiere a datos carcter en el conjunto de datos carcter nacional. Los datos en columnas
CLOB o NCLOB pueden tener un ancho fijo o variable, y puede ser single-byte o multiplebyte. Se puede tener varias columnas del tipo CLOB en una sola tabla.
Ejemplo:
CREATE TABLE clob_tab
(id NUMBER PRIMARY KEY,
clob_data CLOB);

BLOB
Es un LOB que puede almacenar hasta 4GB de datos no estructurados o binarios. Se pueden
definir atributos de un tipo de objeto o de columnas de una tabla de la base de datos en
fecha el tipo BLOB. Se pueden tener varias columnas del tipo BLOB en una sola tabla.
Ejemplo:
CREATE TABLE blob_tab
(id NUMBER PRIMARY KEY,
blob_data BLOB);

Se puede asignar una columna de la BLOB de tres maneras:

Cambiar a NULL

Cambiar a un BLOB vaco

Cambiar a un valor especfico

BFILE
Un BFILE es un archivo binario grande, que puede almacenar hasta 4GB de datos binarios,
y est situado en el sistema de ficheros del sistema operativo. Solamente se almacena un
puntero externo a este archivo en la base de datos. Se pueden tener varias columnas del
tipo BFILE en una sola tabla.
Ejemplo:
CREATE TABLE bfile_tab
(id NUMBER PRIMARY KEY,
bfile_data BFILE);

/ 21

u.d. 1

leccin 2: Conceptos bsicos Pl / Sql

NIVEL II

10. ESTRUCTURAS DE CONTROL


10.1 ESTRUCTURAS CONDICIONALES. IF y CASE
Una construccin condicional ejecuta un sistema de declaraciones, basadas en una condicin que es verdad.
En esta versin de Oracle se ha incluido adems de la sentencia IF, la sentencia CASE.

Estructura IF
La sintaxis es:
IF (expresin) THEN
-- Instrucciones
ELSEIF
-- Instrucciones
ELSE
-- Instrucciones
END IF;

Ejemplo:
DECLARE
a number := 50;
b number := -20;
BEGIN
IF (a>b) THEN
dbms_output.put_line(A is greater than B);
ELSIF (a<b) THEN
dbms_output.put_line(A is less than B);
ELSE
dbms_output.put_line(A is equal to B);
END IF;

Estructura CASE:
CASE SELECT r
WHEN value1 THEN action1;
WHEN value2 THEN action2;
WHEN value3 THEN action3;
... ...
ELSE
actionN;
END CASE;

Ejemplo:
CASE report_choice
WHEN 1 THEN p_proc_report1;
WHEN 2 THEN p_proc_report2;
WHEN 3 THEN p_proc_report3;
WHEN 4 THEN p_proc_report4;
ELSE dbms_output.put_line(Invalid option.);
END CASE;

10.2 ESTRUCTURAS DE REPETICION. LOOP-EXIT, WHILE-LOOP Y FOR-LOOP


Las estructuras de repeticin se especifican por medio de bucles. Hay tres tipos de bucles
para realizar el flujo de control de repeticin.

/ 22

leccin 2: Conceptos bsicos Pl / Sql

u.d. 1

NIVEL II

Estructura LOOP:
Simple:
LOOP
-- Instrucciones
END LOOP;
Compuesto:
LOOP
-- Instrucciones
IF (expresion) THEN
-- Instrucciones
EXIT;
END IF;
END LOOP;

Ejemplo:
DECLARE
line_length NUMBER := 50;
separator VARCHAR2(1) := =;
actual_line VARCHAR2(150);
i NUMBER := 1;
BEGIN
LOOP
actual_line := actual_line || separator;
EXIT WHEN i = line_length;
i:= i + 1;
END LOOP;
DBMS_OUTPUT.PUT_LINE(actual_line);
END;

Estructura WHILE:
WHILE (expresion) LOOP
-- Instrucciones
END LOOP;

Ejemplo:
DECLARE
line_length NUMBER := 50;
separator VARCHAR2(1) := =;
actual_line VARCHAR2(150);
idx NUMBER := 1;
BEGIN
WHILE (idx<=line_length) LOOP
actual_line := actual_line || separator;
idx := idx +1 ;
END LOOP;
DBMS_OUTPUT.PUT_LINE(actual_line);
END;
/

Estructura FOR LOOP:


FOR contador IN [REVERSE] inicio..final LOOP
-- Instrucciones
END LOOP;

/ 23

u.d. 1

leccin 2: Conceptos bsicos Pl / Sql

NIVEL II

Ejemplo:
DECLARE
line_length NUMBER := 50;
separator VARCHAR2(1) := =;
actual_line VARCHAR2(150);
BEGIN
FOR idx in 1..line_length LOOP
actual_line := actual_line || separator;
END LOOP;
DBMS_OUTPUT.PUT_LINE(actual_line);
END;
/

11. INTERACCIN CON ORACLE SERVER


Podemos manipular los datos almacenados de una manera flexible y segura, porque PL/SQL
soporta todos los comandos de manipulacin de datos, control de transacciones, funciones
y operadores manejados por SQL.
Sin embargo, PL/SQL no soporta comandos de definicin de datos, tales como CREATE, o
comandos de control del sistema, tal como ALTER SYSTEM.
Para la manipulacin de los datos pueden ser empleadas las operaciones siguientes:

INSERT
Aade filas a una tabla. Posee varios formatos posibles:
La sintaxis es:
INSERT INTO <nombre-tabla> VALUES (<serie de valores>)

El orden en el que se asignen los valores en la clusula VALUES tiene que coincidir con el
orden en que se definieron las columnas en la creacin del objeto tabla, dado que los valores
se asignan por posicionamiento relativo.
INSERT INTO <nombre-tabla> (<columna1>, <columna2>.....) VALUES (<valor1>, <valor2>....)

En este caso, los valores se asignarn a cada una de las columnas mencionadas por posicionamiento relativo, siendo necesario que, por lo menos, se asignen valores a todas aquellas
columnas que no admiten valores nulos en la tabla.

Sentencia insert con mltiples filas


Para insertar un subconjunto de filas de una tabla en otra se escribe una sentencia INSERT
con una SUBSELECT interna. Los formatos posibles son:
INSERT INTO <nombre-tabla> (<columna1>, <columna2>.....) SELECT (<sentencia Select>)

Asigna a las columnas los valores recuperados en la sentencia Select. Inserta en la tabla
todas las filas que se recuperen en la Select.
INSERT INTO <nombre-tabla> SELECT * FROM <nombre-tabla-fuente>

En este caso, las estructuras de las tablas tienen que ser iguales.
Si no se inserta ninguna fila, los atributos devuelven los siguientes valores:

/ 24

u.d. 1

leccin 2: Conceptos bsicos Pl / Sql


SQL%NOTFOUND
SQL%FOUND
SQL%ROWCOUNT

NIVEL II

-> TRUE
-> FALSE
-> 0

Si se dan de alta una o mas filas, los atributos devuelven los siguientes valores:
SQL%NOTFOUND
SQL%FOUND
SQL%ROWCOUNT

-> FALSE
-> TRUE
-> Nmero de filas insertadas

UPDATE
Actualiza valores de una o ms columnas para un subconjunto de filas de una tabla.
UPDATE <nombre-tabla>
SET <columna1> = valor1 [, <columna2> = valor2 ...?
[WHERE <condicin>?

Actualiza los campos correspondientes junto con los valores que se le asig nen, en el subconjunto de filas que cumplan la condicin de seleccin. Si no
se pone condicin de seleccin, la UPDATE se da en todas las filas de la tabla.
Si se desea actualizar a nulos, se asignar el valor NULL.
Si no se actualiza ninguna fila, los atributos devuelven los siguientes valores:
SQL%NOTFOUND
SQL%FOUND
SQL%ROWCOUNT

-> TRUE
-> FALSE
-> 0

Si se actualizan una o mas filas, los atributos devuelven los siguientes valores:
SQL%NOTFOUND
SQL%FOUND
SQL%ROWCOUNT

-> FALSE
-> TRUE
-> Nmero de filas actualizadas

DELETE
Borra una o ms filas de una tabla. La sintaxis es la siguiente:
DELETE FROM <nombre-tabla>
[WHERE <condicin>?

Si no se pone condicin de seleccin, borra todas las filas de la tabla.


SQL%NOTFOUND
SQL%FOUND
SQL%ROWCOUNT

-> TRUE
-> FALSE
-> 0

Si se borran una o mas filas, los atributos devuelven los siguientes valores:
SQL%NOTFOUND
SQL%FOUND
SQL%ROWCOUNT

-> FALSE
-> TRUE
-> Nmero de filas borradas

SELECT
La sintaxis bsica de una consulta de seleccin es la siguiente:
SELECT Campos FROM Tabla;

/ 25

u.d. 1

leccin 2: Conceptos bsicos Pl / Sql

NIVEL II

En donde campos es la lista de campos que se deseen recuperar, y tabla es el origen de los
mismos, por ejemplo:
SELECT Nombre, Telefono FROM Clientes;

Esta consulta devuelve un conjunto de resultados con el campo nombre y telfono de la


tabla clientes.
Si se desea seleccionar todos los registros sin distincin de columnas, se utiliza el carcter
*; en este caso, la sintaxis ser la siguiente:
SELECT * FROM tabla

Para poder recuperar valores en variables, la consulta slo debe devolver una fila. Las
excepciones predefinidas ms comunes que nos podemos encontrar son:
Si la consulta no devuelve ninguna fila:
Se produce la excepcin predefinida NO_DATA_FOUND
El error ORACLE (SQLCODE) ORA-01403
El mensaje de error (SQLERRM) no data found
SQL%NOTFOUND
SQL%FOUND
SQL%ROWCOUNT

-> TRUE
-> FALSE
-> 0

Si la consulta devuelve ms de una fila:


Se produce la excepcin predefinida TOO_MANY_ROWS
El error ORACLE (SQLCODE) ORA-01427
El mensaje de error (SQLERRM) Single-row query returns more than one row
SQL%NOTFOUND
SQL%FOUND

-> FALSE
-> TRUE

SQL%ROWCOUNT

-> 2

NOTA:
Todas estas sentencias se han visto con detalle en el manual de SQL.

12. DATOS COMPUESTOS


12.1 REGISTROS (RECORDS)
Un registro es un tipo de dato compuesto, que consiste en elementos individuales que
son lgicamente relacionados. Cada elemento del registro se llama campo, tiene un valor
asociado a l y se puede determinar como elemento individual del registro. Cada campo
en un registro tiene un nombre y es, normalmente, de tipo de datos escalar. Sin embargo,
un campo en un registro puede ser otro registro. Usar este tipo de datos permite aplicar la
abstraccin de los datos, porque se trabaja con datos como grupo en vez de usar elementos
individuales. Esto tambin implica menos cdigo, que a la vez implica fcil mantenimiento.
Como ejemplo, consideramos que una empresa se puede definir como registro con los
campos integrados por la informacin lgica relacionada con ella, como identificacin de
la empresa, nombre corto de la empresa, y el nombre largo de la empresa.
PL/SQL deja definir tres tipos de registros: los registros explcitamente definidos, registros
orientados a tablas, y registros orientados a cursores.

/ 26

u.d. 1

leccin 2: Conceptos bsicos Pl / Sql

NIVEL II

Definir el tipo de registro


Para definir un tipo de registro se usa la sentencia TYPE.
La sintaxis es:
TYPE record_type_name IS RECORD
( field_name1 datatype [NOT NULL] [DEFAULT value1 | := assign1],
field_name2 datatype [NOT NULL] [DEFAULT value2 | := assign2],
... ...
field_nameN datatype [NOT NULL] [DEFAULT valueN | := assignN]
);

Donde record_type_name es el nombre que identifica la estructura del nuevo registro que
contiene campos individuales, con los nombres field_name1 al field_nameN. Observar que
cada campo tiene un tipo de dato especificado (que puede ser escalar o subtipo definido
por el usuario, u otro tipo de registro), una restriccin (constraint) opcional NOT NULL,
y una clusula DEFAULT, con los valores iniciales especificados por value1 a travs de
valueN. Alternativamente, los valores iniciales se pueden especificar para usar la asignacin
inicial con la sintaxis:= seguida de un valor. Aqu, assign1 y assignN son expresiones que
evalan un valor con el mismo tipo de dato que el tipo de dato especificado por el campo
correspondiente.
Ejemplo:
TYPE hrc_org_rec IS RECORD
(hrc_org_id NUMBER,
hrc_descr VARCHAR2(20),
org_short_name VARCHAR2(30));

Donde hrc_org_rec de es un registro que tiene una estructura de tres campos.

Declarar una variable del tipo de registro


Una vez que se haya definido un tipo de registro con una estructura especfica, se necesita
declarar los registros reales de ese tipo.
La sintaxis es:
<record_var_name> <record_type_name>;

En esta lnea, record_type_name es el tipo de registro definido, usando el TYPE RECORD,


y record_var_name es un nombre variable arbitrario con un tipo de datos de este tipo de
registro.
Ejemplo:
v_example_rec hrc_org_rec;

Un ejemplo completo que combina los dos pasos precedentes es como sigue:
DECLARE
TYPE hrc_org_rec IS RECORD
(hrc_org_id NUMBER,
hrc_descr VARCHAR2(20),
org_short_name VARCHAR2(30));
v_example_rec hrc_org_rec;
BEGIN
/* Do some processing */
null;
END;
/

/ 27

u.d. 1

leccin 2: Conceptos bsicos Pl / Sql

NIVEL II

Usar un tipo de registro


Una vez que se haya definido el tipo de registro y declarado variables de ese tipo, el paso
siguiente es utilizar el registro para procesar datos. Este paso consiste, generalmente, en
tener acceso a los elementos de registro individuales, almacenar de datos en el registro, y
realizar operaciones de mantenimiento.

Acceso a elementos individuales del registro


Para acceder a los elementos individuales de un registro se usa la notacin del punto. La
sintaxis es:
<record_var_name>.<field_name>

Esta sintaxis es similar a ls sintaxis que se utiliza para tener acceso a una columna en una
tabla de la base de datos, usando el sintaxis de <table_name>.<column_name>. Esto hace
que haya una analoga entre las tablas de la base de datos y los registros. Sin embargo,
una diferencia entre los dos es que las anteriores estn almacenadas en una base de datos,
mientras que los ltimos no estn y no se pueden almacenar en una base de datos.
Aqu est el ejemplo para el registro del hrc_org_rec, definido anteriormente:
DECLARE
TYPE hrc_org_rec IS RECORD
(hrc_org_id NUMBER,
hrc_descr VARCHAR2(20),
org_short_name VARCHAR2(30));
v_example_rec hrc_org_rec;
BEGIN
v_example_rec.hrc_org_id := 1001;
v_example_rec.hrc_descr := CEO/COO;
v_example_rec.org_short_name := Office of CEO/COO ABC Inc.;
dbms_output.put_line(An example record:);
dbms_output.new_line;
dbms_output.put_line(to_number(v_example_rec.hrc_org_id)|| ||
v_example_rec.hrc_descr|| ||
v_example_rec.org_short_name);
END;
/

La salida del cdigo anterior es:


Un registro del ejemplo:
1001 CEO/COO Office of CEO/COO ABC Inc.
PL/SQL procedure successfully completed.
Adems de tener acceso a elementos individuales de un registro, se puede tener acceso,
en algunos casos, al registro entero; por ejemplo, cuando se inicializa un registro con otro
registro o cuando se pasa un registro como parmetro a un subprograma.

Inicializacin del registro


Un tipo de registro es un tipo de datos compuesto, y, como tal, las reglas para inicializar
este tipo de datos son diferentes a las de inicializar el tipo variables escalares. Para inicializar
una variable escalar, se proporciona simplemente un valor inicial en su sentencia, usando
DEFAULT o la sintaxis:=. Para inicializar una variable de registro, se tiene que asignar una
segunda variable de registro que sea compatible con la variable de registro que se est
inicializando. Sin embargo, tambin tiene que utilizar el DEFAULT o la sintaxis:=.

/ 28

u.d. 1

leccin 2: Conceptos bsicos Pl / Sql

NIVEL II

La inicializacin de registro es til cuando se est pasando registros como parmetros a los
subprogramas. Puede ser que pase un registro como parmetro, declarar una variable de
registro local del mismo tipo que la del parmetro, y despus inicializar esta variable local
con el parmetro que se est pasando.

Asignacin del registro


En los trminos ms simples, la asignacin de registro significa asignar valores a un registro.
Esto implica dos cosas: rellenar los campos individuales de un registro y asignar un registro
a otro registro. El ltimo, se llama asignacin agregada. PL/ SQL 9i permite que se asigne
un registro con valores de las cuatro maneras siguientes:

Asignacin individual del campo


Este mtodo consiste en asignar valores a cada uno de los campos individuales del registro.
Para referirse a ellos se usa la notacin record_name.field_name en el lado izquierdo del
operador de asignacin, y se asignan los campos con valores.

Rellenar un registro con un SELECT INTO (con un cursor implcito).


Una segunda manera de rellenar un registro es con un SELECT INTO en la sentencia. La
clusula INTO puede especificar el nombre de registro entero o puede especificar los campos
individuales de los registros, usando la notacin del punto. Sin embargo, la estructura de
la lista de columnas en la SELECT debe ser exactamente igual a la estructura de registro.
Esto significa que el tipo de datos de cada columna y el nmero de columnas en la lista
SELECT deben ser exactamente el de los campos de registro. Los nombres individuales de
la columna en la SELECT pueden ser diferentes.
Ejemplo:
DECLARE
TYPE hrc_org_rec IS RECORD
(hrc_org_id NUMBER,
hrc_descr VARCHAR2(20),
org_short_name VARCHAR2(30));
v_example_rec hrc_org_rec;
BEGIN
SELECT hrc_org_seq.nextval, h.hrc_descr, o.org_short_name
INTO
v_example_rec
FROM org_tab o, hrc_tab h
WHERE o.hrc_code = h.hrc_code
AND o.org_id = 1001;
dbms_output.put_line(An example record: );
dbms_output.new_line;
dbms_output.put_line(to_number(v_example_rec.hrc_org_id)|| ||
v_example_rec.hrc_descr|| ||
v_example_rec.org_short_name);
END;
/

Rellenar un registro con FETCH INTO (con un cursor explcito).


Una tercera manera de rellenar un registro es con la sentencia FETCH INTO, resultando un
cursor explcito. Como con el cursor implcito, la clusula INTO puede especificar el nombre
de registro entero o puede especificar los campos individuales de los registros, usando la
notacin del punto. Sin embargo, la estructura de la lista de columnas de la SELECT del

/ 29

u.d. 1

leccin 2: Conceptos bsicos Pl / Sql

NIVEL II

cursor debe ser exactamente igual a la estructura del registro. Esto significa que el tipo de
datos de cada columna y el nmero de columnas en la SELECT del cursor deben ser exactamente iguales a la de los campos de registro. Sin embargo, los nombres individuales de
la columna de la SELECT del cursor pueden ser diferentes.
Ejemplo:
DECLARE
TYPE hrc_org_rec IS RECORD
(hrc_org_id NUMBER,
hrc_descr VARCHAR2(20),
org_short_name VARCHAR2(30));
v_example_rec hrc_org_rec;
CURSOR csr_hrc_org IS
SELECT hrc_org_seq.nextval, h.hrc_descr, o.org_short_name
FROM org_tab o, hrc_tab h
WHERE o.hrc_code = h.hrc_code
AND h.hrc_code = 1;
BEGIN
OPEN csr_hrc_org;
dbms_output.put_line(An example output: );
dbms_output.new_line;
LOOP
FETCH csr_hrc_org INTO v_example_rec;
EXIT WHEN csr_hrc_org%NOTFOUND;
dbms_output.put_line(to_number(v_example_rec.hrc_org_id)|| ||
v_example_rec.hrc_descr|| ||
v_example_rec.org_short_name);
END LOOP;
CLOSE csr_hrc_org;
END;
/

Asignar un registro usando un segundo registro (asignacin agregada)


En este caso, los campos individuales del registro destino no se asignan uno por uno. En
lugar de esto, se utiliza registros tipo-compatibles a ambos lados del operador de asignacin.
El registro se debe rellenar antes de que se haga la asignacin.

12.2 %ROWTYPE
Registros orientados a tablas
Se ha visto que un registro de PL/ SQL es un tipo de dato compuesto por campos. Estos
campos se eligen y se agrupan arbitrariamente juntos para formar parte de un solo registro.
En muchos casos, puede ser necesario construir un registro que se parezca a la estructura
de una fila de una tabla de la base de datos. Este registro se llama un registro orientado a
tabla o registro de tabla. En este caso, los campos individuales estn formados por todas
las columnas de una fila de una tabla de la base de datos. Los campos de este registro
corresponden uno por uno, tanto en el nombre como en la estructura, a las columnas de la
tabla de la base de datos en la cual se basa el registro.
Para crear un registro de tabla se utiliza el operador %ROWTYPE.
La sintaxis es:
record_var_name table_name%ROWTYPE;

Donde la variable record_var_name del registro tiene la misma estructura de registro que
una fila, en la tabla identificada por table_name. Para definir este tipo de registros se declara

/ 30

u.d. 1

leccin 2: Conceptos bsicos Pl / Sql

NIVEL II

directamente, sin tener que definir el tipo de registro. El tipo de registro se hereda de la
estructura de la fila de la tabla de la base de datos.
Para acceder a los campos individuales de este tipo de registro tambin se utiliza la notacin
del punto.
Ejemplo:
DECLARE
hrc_rec hrc_tab%ROWTYPE;
BEGIN
SELECT *
INTO
hrc_rec
FROM
hrc_tab
WHERE hrc_code = 1;
dbms_output.put_line(An example record:);
dbms_output.new_line;
dbms_output.put_line(to_char(hrc_rec.hrc_code)|| ||hrc_rec.hrc_descr);
END;
/

La salida del programa es:


1 CEO/COO
PL/SQL procedure successfully completed.

Registros orientados a cursores


Este tipo de registro se asemeja a la estructura de un cursor PL/SQL (que se ver en el
siguiente punto). En este caso, los campos individuales se componen de las columnas del
cursor PL/SQL SELECT. Los campos de este registro corresponden uno por uno en nombre
y estructura a las columnas del cursor PL/SQL en el que se basa el registro.
Para crear un registro orientado a un cursor, tambin se utiliza el operador %ROWTYPE.

La sintaxis es:
record_var_name cursor_name%ROWTYPE;

Donde la variable record_var_name del registro tiene la misma estructura que el registro
de una fila del cursor identificado por cursor_name. Al igual que con los registros de tabla,
se declara directamente sin tener que definir el tipo de registro, porque se hereda de la
estructura de la fila del cursor.
Para acceder a los campos individuales de este tipo de registro tambin se utiliza la notacin
del punto.
Ejemplo:
DECLARE
CURSOR csr_hrc IS
SELECT * FROM hrc_tab ORDER BY 1;
hrc_rec csr_hrc%ROWTYPE;
BEGIN
OPEN csr_hrc;
dbms_output.put_line(Hierarchy records: );
dbms_output.new_line;
LOOP
FETCH csr_hrc INTO hrc_rec;
EXIT WHEN csr_hrc%NOTFOUND;
dbms_output.put_line(to_char(hrc_rec.hrc_code)|| ||hrc_rec.hrc_descr);

/ 31

u.d. 1

NIVEL II

leccin 2: Conceptos bsicos Pl / Sql


END LOOP;
CLOSE csr_hrc;
END;
/

La salida del programa es:


Hierarchy records:
1 CEO/COO
2 VP
3 Director
4 Manager
5 Analyst
PL/SQL procedure successfully completed.

12.3 TABLAS INDEX BY O TABLAS INDEXADAS


Es una estructura de datos compuesta, integrada por una coleccin de elementos homogneos parecido a un array. Los elementos en esta coleccin son ilimitados, distribuidos, e
indexados con enteros (de ah, el nombre INDEX-BY tabla). Antes de Oracle8, se llamaban
tablas PL/SQL. y estaban disponibles en PL/SQL 2.0 y versiones posteriores.
Los elementos individuales de tablas INDEX-BY son elementos de tipo de datos escalar
o de registro PL/SQL. Estn indexados por BINARY_INTEGER. Puesto que los lmites ms
bajos y superiores de BINARY_INTEGER son -2**31 y 2**31-1, stos pueden tener muchos
elementos. Aunque Tablas INDEX-BY sern parecidos a los arrays 3GL que tienen elementos homogneos, existen unas diferencias a la hora de implementarlos, como muestra la
siguiente tabla.

Imagen1-2-2

Definir INDEX-BY tabla


Como con los registros PL/SQL, se muestra primero definiendo el tipo de tabla y, enseguida,
declarando una variable de ese tipo.

Definir el tipo de la tabla


Se define un tipo de tabla usando la sentencia TYPE.
La sintaxis es:
TYPE table_type_name IS TABLE OF type [NOT NULL] INDEX BY BINARY_INTEGER;

/ 32

u.d. 1

leccin 2: Conceptos bsicos Pl / Sql

NIVEL II

Donde table_type_name identifica la estructura del nuevo Tablas INDEX-BY, que contiene
los elementos individuales del tipo de datos. Observar que cada elemento tiene un ndice
asociado a l y a un valor. El tipo de datos del elemento puede ser cualquier tipo escalar como
VARCHAR2, NUMBER, DATE, BOOLEAN , o puede ser una referencia a un tipo escalar,
usando %TYPE o un tipo de registro. Se puede especificar una constraint NOT NULL opcional
para indicar que cada elemento creado en Tablas INDEX-BY debe ser un valor no nulo.
Ejemplo:
TYPE num_tab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;

Declarar una variable del tipo tabla


Una vez que se haya definido el tipo de tabla, se necesita declarar Tablas INDEX-BY de ese
tipo. La sintaxis es:
<table_var_name> <table_type_name>;

Donde table_type_name es definido usando la especificacin TYPE TABLE, y table_var_


name es un nombre de variable arbitrario, con un tipo de datos del tipo de la tabla. Ejemplo:
v_example_tab num_tab;

Un ejemplo completo que combina los dos pasos sera:


DECLARE
TYPE num_tab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
v_example_tab num_tab;
BEGIN
/* Do some processing */
null;
END;
/

Usar INDEX-BY tabla


Una vez que se haya definido Tablas INDEX-BY y declarado variables de este tipo, el paso
siguiente es utilizar la tabla para procesar datos. Esto consiste en, generalmente, tener
acceso a los elementos individuales de tabla, rellenar tabla con los elementos (filas), y el
realizar operaciones en INDEX-BY tabla.

Tener acceso INDEX-BY tabla


Los elementos en Tablas INDEX-BY se llaman filas, pues tienen una estructura de dos
columnas, que consisten en el ndice como primera columna, y el valor correspondiente
como segunda columna.
La sintaxis es:
<table_var_name> (<index_value>)

Los parntesis son obligatorios. Observar que se utiliza el nombre de la variable de la tabla
real, y no el nombre del tipo de la tabla.

/ 33

leccin 2: Conceptos bsicos Pl / Sql

u.d. 1

NIVEL II

Ejemplo:
DECLARE
TYPE num_tab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
v_example_tab num_tab;
v_num NUMBER := 13;
BEGIN
v_example_tab(1) := 1001;
v_example_tab(10) := 1002;
v_example_tab(-10) := 1003;
v_example_tab(v_num) := 1004;
dbms_output.put_line(An example array:);
dbms_output.new_line;
dbms_output.put_line(to_char(v_example_tab(1))|| ||
to_char(v_example_tab(10))|| ||
to_char(v_example_tab(-10))|| ||
to_char(v_example_tab(v_num)) );
END;
/

En este ejemplo, el Tablas INDEX-BY de cuatro filas es creado explcitamente, especificando


el ndice y el valor a cada fila.
Adems de poder tener acceso a filas individuales del INDEX-BY tabla, en algunos casos
se puede tener acceso a la tabla entera. Por ejemplo, se puede hacer cuando se inicializa
una tabla con otra tabla o cuando se pasa Tablas INDEX-BY como parmetro a un subprograma.
Ejemplo:
DECLARE
TYPE num_tab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
v_example_tab1 num_tab;
v_example_tab2 num_tab;
v_num NUMBER := 13;
BEGIN
v_example_tab1(1) := 1001;
v_example_tab1(10) := 1002;
v_example_tab1(-10) := 1003;
v_example_tab1(v_num) := 1004;
v_example_tab2 := v_example_tab1;
dbms_output.put_line(An example array:);
dbms_output.new_line;
dbms_output.put_line(to_char(v_example_tab2(1))|| ||
to_char(v_example_tab2(10))|| ||
to_char(v_example_tab2(-10))|| ||
to_char(v_example_tab2(v_num)) );
END;
/

Rellenar una tabla INDEX-BY


La manera ms simple de rellenar tablas INDEX-BY es asignar explcitamente valores a cada
fila, eligiendo ndices arbitrarios. Sin embargo, se tiene otras maneras de crear INDEX-BY.
El PL/SQL 9i permite tres maneras de asignar un registro con valores:

Creacin individual de la fila por asignacin

Asignar filas por medio de un LOOP

Asignar una tabla usando una segunda tabla (asignacin agregada)

/ 34

u.d. 1

leccin 2: Conceptos bsicos Pl / Sql

NIVEL II

Creacin individual de la fila por asignacin


Este mtodo consiste en crear cada fila de Tablas INDEX-BY, eligiendo un ndice al azar y asignando un valor al elemento correspondiente. Se refiere usando la notacin table_var_name
(ndice) en el lado izquierdo del operador de asignacin, y se asigna cada fila con valores.

Asignar filas por medio de un LOOP


La creacin individual de una fila por asignacin es til cuando se desea rellenar Tablas
INDEX-BY no secuenciales. Sin embargo, se puede necesitar rellenar tablas INDEX-BY
secuencialmente. En este caso, se puede hacer esta asignacin explcita, usando un loop.
La diferencia es que se utiliza un bucle y un contador que se utiliza para fijar el valor del
ndice de cada fila en la tabla INDEX-BY.
Ejemplo:
DECLARE
TYPE num_tab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
v_example_tab num_tab;
BEGIN
FOR idx IN 1..10 LOOP
v_example_tab(idx) := (2**idx)+1;
END LOOP;
dbms_output.put_line(An example array:);
dbms_output.new_line;
FOR idx IN 1..10 LOOP
dbms_output.put_line(to_char(v_example_tab(idx)));
END LOOP;
END;
/

Asignar una tabla usando una segunda tabla (asignacin agregada)


Este mtodo consiste en asignar la tabla entera con una segunda tabla. En este caso, no
se asignan los elementos individuales a la tabla destino uno por uno. En lugar de eso, se
utilizan las tablas de tipos compatibles a ambos lados del operador de asignacin. La tabla
origen se debe rellenar antes.
Ejemplo:
DECLARE
TYPE num_tab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
v_example_tab1 num_tab;
v_example_tab2 num_tab;
v_num NUMBER := 13;
BEGIN
v_example_tab1(1) := 1001;
v_example_tab1(10) := 1002;
v_example_tab1(-10) := 1003;
v_example_tab1(v_num) := 1004;
v_example_tab2 := v_example_tab1;
dbms_output.put_line(An example array:);
dbms_output.new_line;
dbms_output.put_line(to_char(v_example_tab2(1))|| ||
to_char(v_example_tab2(10))|| ||
to_char(v_example_tab2(-10))|| ||
to_char(v_example_tab2(v_num)) );
END;
/

En este caso, el ndice y el valor de cada fila en la tabla en blanco se fija a los valores de la
fila correspondiente en la tabla origen. Esto es bastante limpio, implica menos cdigo, y
provoca menos errores que la asignacin individual o la asignacin en un loop.

/ 35

NIVEL II

leccin 2: Conceptos bsicos Pl / Sql

u.d. 1

Mtodos de tablas INDEX-BY


En PL/SQL 2.3, hay mtodos definidos que se pueden invocar en tablas INDEX-BY. Un
mtodo es un procedimiento o funcin PL/SQL que se puede invocar para realizar ciertas
tareas. Los mtodos permiten realizar ms fcilmente las operaciones en el cdigo, como
contar el nmero de elementos, suprimir alguna o todas las filas, o probar la existencia de
una fila particular.
En la siguiente tabla se muestran los mtodos:

Imagen1-2-3

Tablas INDEX-BY de registro


Hasta ahora, se han visto tablas con elementos de tipos escalares. Sin embargo, INDEX-BY
puede tener un registro PL/SQL como tipo de datos de sus elementos. Esto da lugar INDEXBY de registros, y esta caracterstica est disponible en PL/SQL 2.3.

Los pasos para definir Tablas INDEX-BY de registros:

1. Definir un tipo de registro.

2. Definir un tipo de la tabla del tipo de registro.

3. Definir una variable del tipo de la tabla.

/ 36

leccin 2: Conceptos bsicos Pl / Sql

u.d. 1

NIVEL II

Ejemplo:
DECLARE
TYPE hrc_org_rec IS RECORD
(hrc_org_id NUMBER,
hrc_descr VARCHAR2(20),
org_short_name VARCHAR2(30));
TYPE hrc_org_tab IS TABLE OF hrc_org_rec INDEX BY BINARY_INTEGER;
v_example_tab hrc_org_tab;
CURSOR csr_hrc_org IS
SELECT hrc_org_seq.nextval hrc_org_id, h.hrc_descr, o.org_short_name
FROM org_tab o, hrc_tab h
WHERE o.hrc_code = h.hrc_code
AND h.hrc_code = 1;
i BINARY_INTEGER := 1;
BEGIN
FOR idx IN csr_hrc_org LOOP
v_example_tab(i).hrc_org_id := idx.hrc_org_id;
v_example_tab(i).hrc_descr := idx.hrc_descr;
v_example_tab(i).org_short_name := idx.org_short_name;
i := i + 1;
END LOOP;
dbms_output.put_line(An example output: );
dbms_output.new_line;
FOR j IN 1..v_example_tab.COUNT LOOP
dbms_output.put_line(to_char(v_example_tab(j).hrc_org_id)|| ||
v_example_tab(j).hrc_descr|| ||
v_example_tab(j).org_short_name);
END LOOP;
END;
/

13. CURSORES
Un cursor es un manejador o apuntador para el rea de contexto. Por medio de ste un
programa PL/SQL puede controlar el rea de contexto.
Hay dos tipos de cursores:

Los cursores implcitos son creados por Oracle para manejar alguna instruccin SQL,
y no son declarados por el programador.

Los cursores explcitos son aquellos que se declaran, generalmente, por medio de
una consulta SQL.

Imagen1-2-4

Fases para procesar una instruccin SQL

/ 37

NIVEL II

leccin 2: Conceptos bsicos Pl / Sql

u.d. 1

13.4 CURSORES EXPLCITOS

Imagen1-2-5-

Sentencia del cursor


La consulta no debe contener la clusula INTO.
Se puede hacer referencia a variables dentro de la clusula WHERE.
La sintaxis es:
CURSOR nombre_cursor IS
instruccin_SELECT

Tambin es posible declarar una lista de parmetros:


CURSOR nombre_cursor(param1 tipo1, ..., paramN tipoN) IS
instruccin_SELECT

Cuando se utiliza un bloque PL/SQL, se necesita declarar un cursor explcito en la seccin


del sentencia despus de la palabra clave del DECLARE.

Ejemplo de un cursor explcito:


DECLARE
CURSOR csr_org IS
SELECT h.hrc_descr, o.org_short_name
FROM org_tab o, hrc_tab h
WHERE o.hrc_code = h.hrc_code
ORDER by 2;
v_hrc_descr VARCHAR2(20);
v_org_short_name VARCHAR2(30);
BEGIN
/* ... <Process the cursor resultset> ... */
null;
END;
/

Una vez que se haya definido un cursor, se puede utilizar para procesar las filas contenidas
en el resultset. Para ello, se siguen los siguientes pasos:

1. Abrir el cursor.

2. Traer los resultados en un registro PL/SQL o en variables PL/SQL individuales.

/ 38

leccin 2: Conceptos bsicos Pl / Sql

u.d. 1

NIVEL II

3. Cerrar el cursor.

4. Hay dos maneras de utilizar un cursor explcito una vez que se haya definido: usando
OPEN, FETCH, y CLOSE, y usando un cursor FOR LOOP. Se puede hacer esto en la
seccin de un bloque PL/SQL entre BEGIN y END.

La primera manera es:


Abrir el cursor
La sintaxis es:
OPEN nombre_cursor;

Se examinan los valores de las variables


Se determina el conjunto activo
El apuntador para el conjunto activo se establece en el primer registro.

Recuperar los resultados en variables PL/SQL


Tiene dos formas:
FETCH cursor_name INTO lista_variables;
o
FECTH cursor_name INTO registro_PL/SQL;

Cerrar el cursor
La sintaxis es:
CLOSE nombre_cursor;

Cuando se cierra el cursor, es ilegal tratar de usarlo.


Es ilegal tratar de cerrar un cursor que ya est cerrado o no ha sido abierto.
Ejemplo:
DECLARE
/* Declare a cursor explicitly */
CURSOR csr_org IS
SELECT h.hrc_descr, o.org_short_name
FROM org_tab o, hrc_tab h
WHERE o.hrc_code = h.hrc_code
ORDER by 2;
v_org_rec csr_org%ROWTYPE;
BEGIN
/* Open the cursor */
OPEN csr_org;
/* Format headings */
dbms_output.put_line(Organization Details with Hierarchy);
dbms_output.put_line(------------------------);
dbms_output.put_line(rpad(Hierarchy,20, )|| ||
rpad(Organization,30, ));
dbms_output.put_line(rpad(-,20,-)|| ||rpad(-,30,-));
/* Fetch FROM the cursor resultset in a loop and display the results
*/
LOOP
FETCH csr_org INTO v_org_rec;
EXIT WHEN csr_org%NOTFOUND;

/ 39

leccin 2: Conceptos bsicos Pl / Sql

u.d. 1

NIVEL II

dbms_output.put_line(rpad(v_org_rec.hrc_descr,20, )|| ||
rpad(v_org_rec.org_short_name,30, ));
END LOOP;
/* CLose the cursor */
CLOSE csr_org;
END;
/

La segunda manera es utilizando un cursor FOR LOOP:


Un cursor FOR LOOP toma el OPEN, FETCH, y CLOSE como implcito. Los pasos son:
Declarar un cursor FOR LOOP .
FOR idx in cursor_name LOOP
...
...
END LOOP;

El cursor_name es el nombre del cursor y el idx es el ndice del cursor FOR LOOP, y es de
tipo del cursor_name %ROWTYPE.
Procesar los datos en el sistema activo.
Ejemplo:
create or replace package EJEM_CURSOR is
procedure imprime_facturas;
end;
create or replace package body EJEM_CURSOR is
--- Este procedimiento genera un listado de proveedores
-- y las facturas que ha emitido
-procedure IMPRIME_FACTURAS is
cve_prov
proveedores.clave%type;
nom_prov
proveedores.nombre%type;
CURSOR c_proveedores IS
select clave, nombre FROM proveedores;
CURSOR c_facturas IS
select factura, fecha FROM facturas where
proveedor_clave=cve_prov order by fecha;
fact
c_facturas%rowtype;
begin
OPEN c_proveedores;
loop
FETCH c_proveedores INTO cve_prov, nom_prov;
exit when c_proveedores%notfound;
dbms_output.put_line(PROVEEDOR: || nom_prov);
for fact in c_facturas loop
dbms_output.put_line(
||
fact.factura || ( || fact.fecha || ));
end loop;
dbms_output.put_line( );
end loop;
CLOSE c_proveedores;
end;
end;

Atributos de los cursores explcitos


Cada cursor explcito tiene cuatro atributos asociados a l, que se pueden utilizar para determinar si un cursor est abierto o no y cuntas filas se han trado hasta ahora.
Toman los valores TRUE, FALSE o NULL, dependiendo de la situacin:

/ 40

u.d. 1

NIVEL II

leccin 2: Conceptos bsicos Pl / Sql

Imagen1-2-6

Nmero de registros que ha recuperado hasta el momento


**
Nmero de total de registros.

13.1 CLUSULA FOR UPDATE


Se utiliza para poder actualizar las filas recuperadas por un cursor. Se utiliza a menudo
cuando se necesita modificar cada fila recuperada por un cursor sin buscar filas.

Definir un cursor SELECT FOR UPDATE


Un cursor SELECT FOR UPDATE se define usando la clusula FOR UPDATE OF en el cursor
de la sentencia SELECT:
DECLARE
CURSOR csr_1 IS
SELECT * FROM sec_hrc_tab FOR UPDATE OF hrc_descr;
BEGIN
/* ... Open the cursor and process the resultset ... */
null;
END;
/

Una vez que se haya definido el cursor, se utiliza la clusula WHERE CURRENT OF para
procesar las filas devueltas. Se puede utilizar esta clusula en una sentencia UPDATE o
DELETE.
La sintaxis es:
WHERE CURRENT of cursor_name;

Donde cursor_name es el nombre del cursor, definido con la clusula FOR UPDATE.
El mecanismo de los cursores SELECT FOR UPDATE trabaja as:
SELECT FOR UPDATE pone bloqueo en las filas recuperadas por el cursor. Si no puede
obtener un bloqueo porque otra sesin ha bloqueado las filas especficas, espera hasta
que pueda ser bloqueado. Un COMMIT o ROLLBACK en la sesin correspondiente libera
los bloqueos mantenidos por otras sesiones.
Para cada fila identificada por el cursor, actualiza la columna especificada de esa fila. Esto es
parecido a una sentencia ordinaria UPDATE o CANCEL dentro de un bucle, donde el cursor
recorre la tabla actualizada otra vez para determinar la fila actual que se va a modificar.

/ 41

final de leccin
FINAL DE LA LECCIN 2
Notas de trabajo del alumno:

Conclusiones:

Temas clave a recordar:

El rea de contexto es la memoria designada


para procesar una instruccin SQL, la cual
incluye el nmero de registros procesados,
un apuntador a la representacin de la instruccin SQL analizada y, en el caso de una
consulta, el conjunto de registros que regresan de la consulta.

PL/SQL agrega construcciones propias de


lenguajes procedurales, obtenindose como
resultado un lenguaje estructural ms poderoso que SQL. La unidad de programacin
utilizada por PL/SQL es el bloque.

Los programas pueden emplear variables y


constantes para almacenar valores, dichos
identificadores son colocados en el rea de
declaraciones de un bloque.

Un registro es un tipo de dato compuesto, que


consiste en elementos individuales que son
lgicamente relacionados. Cada elemento del
registro se llama campo.

Un dato de tipo compuesto tiene componentes internos que se pueden manipular


individualmente. Estos datos son tambin
conocidos como colecciones, y pueden ser
de tipo TABLE, RECORD, NESTED TABLE Y
VARRAY.

/ 42

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

LECCIN 3. EXCEPCIONES, SUBPROGRAMAS PL/SQL Y


TRIGGERS
INTRODUCCION
14. EXCEPCIONES

Dentro de PL/SQL una condicin de advertencia o de error es llamada Excepcin, dichas


excepciones pueden ser definidas de manera interna o por el usuario.
Dentro de Oracle, cada error tiene un nmero, pero las excepciones deben ser manejadas
por su nombre.
Los errores pueden ser clasificados de acuerdo a la siguiente tabla:

Imagen1-3-1

Las excepciones estn diseadas para manejar errores en tiempo de ejecucin.


Cuando vez que ocurre un error, se lanza una excepcin y el control pasa al manejador de
la excepcin.

14.1 SENTENCIA DE EXCEPCIONES


Hay dos tipos de excepciones: las predefinidas y las definidas por el usuario.
Excepciones definidas por el usuario
Son errores que estn definidos en el programa, los cuales no son necesariamente errores
de Oracle. Las excepciones se declaran en la seccin declarativa de un bloque PL/SQL.
Las excepciones tienen un tipo (EXCEPTION) y un ambiente.
DECLARE
e_error1 EXCEPTION
BEGIN
.
.
.
END;

Excepciones predefinidas
Las excepciones predefinidas corresponden a errores comunes en SQL algunas de ellas
son:

/ 43

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

Imagen1-3-2

14.2 LANZAMIENTO Y MANEJO DE EXCEPCIONES


Las excepciones definidas por el usuario son lanzadas por medio de la instruccin RAISE,
mientras que las excepciones predefinidas son lanzadas cuando ocurre el error de Oracle
asociado.
Cuando la excepcin es lanzada, el control pasa a la seccin de excepciones de un bloque
PL/SQL. Si no existe esta seccin, en el caso de bloques anidados, el error se propaga al
bloque que contiene al que reporta el error.
DECLARE
-- Declaracion de la excepcion
a EXCEPTION;
BEGIN
...
RAISE a;
-- El resto del codigo de esta seccion
-- no es ejecutado
...
EXCEPTION
-- El control pasa al manejador cuando se lanza a
WHEN a THEN
-- Cdigo a ejecutar para
-- para manejar la excepcion
END;

La seccin de excepciones consiste de una serie de manejadores. Un manejador de excepcin


consiste en el cdigo, que es ejecutado cuando la excepcin es lanzada. La sintaxis es la
siguiente:
EXCEPTION
WHEN nombre_excepcion1 THEN
secuencia_de_instrucciones1;
WHEN nombre_excepcion2 THEN

/ 44

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

secuencia_de_instrucciones2;
WHEN OTHERS THEN
secuencia_de_instrucciones3;
END;

Cuando se usa WHEN OTHERS y se desea saber qu error ocurri, las funciones SQLCODE
y SQLERRM proporcionan esta informacin.

SQLCODE
Devuelve el cdigo del error que lanz la excepcin.

SQLERRM
Devuelve el mensaje de error correspondiente al error que lanz la excepcin.
Esta funcin tambin acepta un argumento numrico, el cual debe de corresponder al texto
asociado con ese nmero.

14.3 DEFINICIN DE MENSAJES DE ERROR PROPIOS


Para definir mensajes de error se usa la funcin RAISE_APPLICATION_ERROR, cuya sintaxis
es:
RAISE_APPLICATION_ERROR(numero_de_error,
mensaje_de_error [, mantener_error]);

numero_de_error
Es un nmero entre -20,000 y 20,999.
mensaje_de_error
Es el texto asociado con este error. Su longitud debe ser menor de 512 caracteres.
mantener_error

Es booleano y opcional. Si su valor es TRUE, el error es agregado a la lista de errores lanzados. Si es FALSE, el error reemplaza a la lista actual de errores.

14.4 PROPAGACIN DE EXCEPCIONES


Cuando se lanza una excepcin dentro de la seccin ejecutable de un bloque ocurre lo
siguiente:
Si el bloque actual tiene un manejador para la excepcin, se ejecutan las instrucciones
asociadas al manejador, y control pasa al bloque que engloba a ste.
Si no hay un manejador para la excepcin, ste se propaga lanzndola en el bloque que
engloba al actual. El primer paso se repite para el bloque que engloba.
Ejemplos:
Se aplica la regla 1 para manejar la excepcin:
DECLARE
A EXCEPTION;

/ 45

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

BEGIN
BEGIN
RAISE A;
EXCEPTION
WHEN A THEN
...
END;
END;

Se aplica la regla 2 al bloque interno:


DECLARE
A EXCEPTION;
B EXCEPTION;
BEGIN
BEGIN
RAISE B;
EXCEPTION
WHEN A THEN
... END;
EXCEPTION
WHEN B THEN
...
END;

La excepcin se propaga y el bloque no concluye exitosamente.


DECLARE
A EXCEPTION;
B EXCEPTION;
BEGIN
RAISE A;
EXCEPTION
WHEN A THEN
RAISE B;
WHEN B THEN
...
END;

Esta excepcin es inmediatamente propagada, sin ejecutar las instrucciones asociadas al


manejador WHEN OTHERS:
DECLARE
v1 NUMBER(3) := abc;
BEGIN
...
EXCEPTION
WHEN OTHERS THEN
...
END;

En este caso, el bloque interno lanza la excepcin, y el bloque externo la maneja.


BEGIN
DECLARE
v1 NUMBER(3):=abc;
BEGIN

EXCEPTION
WHEN OTHERS THEN

END;
EXCEPTION
WHEN OTHERS THEN
...
END;

/ 46

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

La excepcin A es lanzada y manejada, pero su manejador lanza B, y esta es propagada


hacia un bloque exterior, por lo que este bloque no termina exitosamente:
DECLARE
A EXCEPTION;
B EXCEPTION;
BEGIN
RAISE A;
EXCEPTION
WHEN A THEN
RAISE B;
WHEN B THEN
...
END;

En este caso, s se tiene una conclusin exitosa:


BEGIN
DECLARE
A EXCEPTION;
B EXCEPTION;
BEGIN
RAISE A;
EXCEPTION
WHEN A THEN
RAISE B;
WHEN B THEN
.
END;
EXCEPTION
WHEN B THEN
...
END;

Cuando RAISE no tiene argumento, la excepcin actual es propagada a un bloque


externo:
DECLARE
A EXCEPTION;
BEGIN
RAISE A;
EXCEPTION
WHEN A THEN
...
RAISE;
END;

Ejemplo de cmo manejar las excepciones:


CREATE OR REPLACE PROCEDURE bajas (nombre in varchar2) is
n prueba.sueldo%TYPE;
begin
htp.print(Nombre: ||==> ||nombre);
htp.nl;
select sueldo into n FROM prueba where nom=nombre;
htp.print(El empleado ||nombre|| tiene un sueldo de: ||to_char(n));
IF n > 1000 then
DELETE FROM prueba WHERE nom=nombre;
htp.nl;
htp.nl;
htp.print(Este registro ha sido borrado);
else
htp.nl;
htp.nl;

/ 47

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

htp.print(Este no es un registro valido para ser borrado);


END IF;
htp.nl;
htp.nl;
htp.anchor(http://isla.lania.mx:8900index.html, Listado de Pruebas);
exception
when no_data_found then
htp.nl;
htp.print(El empleado ||nombre|| no fue localizado);
htp.nl;
htp.nl;
htp.print(por lo tanto este registro no puede ser ELIMINADO);
htp.nl;
htp.nl;
htp.anchor(http://isla.lania.mx:8900index.html,Listado de Pruebas);
end;

15. SUBPROGRAMAS
Los subprogramas en PL/SQL pueden recibir parmetros y ser invocados. PL tiene dos tipos
de subprogramas llamados procedimientos y funciones. Generalmente, usamos un procedimiento para ejecutar una
accin y una funcin para
calcular un valor.

Imagen1-3-3

Las ventajas de utilizar subprogramas son varias:


Modularidad: Los subprogramas almacenados introducen el concepto de modular programando, el programa principal se analiza en mdulos lgicamente independientes y cada
mdulo cifrado por separado. El programa principal se puede escribir, llamando estos
procedimientos individuales con cualquier cdigo adicional que se requiera. Esto permite
escribir APIs adaptados hacia un uso especfico.
Encapsulacin: Los subprogramas almacenados permiten la encapsulacin de la lgica del
negocio, tal como reglas de negocio y lgica de la aplicacin en la base de datos.
Centralizacin del cdigo: Porque los subprogramas almacenados se almacenan en la base
de datos y el funcionamiento en el lado del servidor, son fciles de mantener. El cdigo est
disponible en una sola localizacin y las aplicaciones mltiples pueden utilizarla.
Reutilidad: Segn lo mencionado previamente, los programas pueden reutilizar el mismo
subprograma, y, cuando son necesarios, con diversos sistemas de datos.
Un funcionamiento mejor: Un subprograma permite que se agrupen juntos sistemas de

/ 48

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

declaraciones del SQL, que dan lugar a un mejor funcionamiento con pocas llamadas a la
base de datos, y reducen el trfico de red en arquitecturas de dos niveles y aplicaciones de
tres capas. Tambin, en esta versin de PL/SQL 9i, los subprogramas almacenados pueden
utilizar la compilacin nativa, la conversin subsecuente al cdigo de C, y el almacenamiento del cdigo automtico en comparacin con cdigo interpretado. Esto permite una
ejecucin ms rpida.

15.1 PROCEDIMIENTOS
La sintaxis es:
CREATE [ OR REPLACE] PROCEDURE nombre
[(parametro1, [parametro2, ....])]
IS | AS
[declaraciones locales]
BEGIN
[Estructuras Ejecutables]
[EXCEPTION]
Majenadores de Excepciones
END [nombre];

La opcin REPLACE indica que si el procedimiento ya existe, se borre y sea reemplazado


con la nueva versin creada por esta sentencia.
El bloque PL/SQL comienza con BEGIN o la sentencia de variables locales, y termina con
END o END[nombre del procedimiento]
Ejemplo de un procedimiento:
CREATE OR REPLACE PROCEDURE almacena (
ctrl in varchar2,
nom in varchar2,
direc in varchar2,
tele in varchar2,
xsue number,
xdias number) as
BEGIN
insert into agenda values (ctrl, nom, direc, tele);
insert into sueldos values (xsue, xdias, ctrl);
commit;
htp.print(Este es el final favor de
selecionar Back);
htp.nl;
END;

Un procedimiento se distribuye de la siguiente


manera:

/ 49

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

u.d. 1

NIVEL II

Imagen1-3-4

Existen tres tipos de parmetros:

IN (por defecto): Pasa un valor constante desde el entorno donde se llama al procedimiento.

OUT: Pasa un valor desde el procedimiento al entorno.

IN OUT: Para un valor desde el entorno que llama al procedimiento y un valor posible
diferente desde el procedimiento cuando regresa de la llamada, usando el mismo
parmetro.

Un procedimiento que contiene varios parmetros, se puede usar un nmero de mtodos


para especificar los valores de los parmetros.
Estos mtodos son:
Positional: Listas de valores en el orden en que se ha declarado los parmetros.
Named association: Listas de valores en orden arbitrario, asociado a cada uno de los parmetros, usando la sintaxis especial =>
Combination: Lista de los primeros valores posicionalmente, y el resto usando la sintaxis
especial del nombre del mtodo.

15.2 FUNCIONES
Una funcin es un subprograma que calcula un valor. Las funciones y los procedimientos
estn estructurados de la misma forma, excepto que las funciones cuentan con la clusula
RETURN.
La sintaxis es:
CREATE OR REPLACE FUNCTION nombre [(parametro1, [parametro2, ....])] RETURN tipo_de_dato
IS
[declaraciones locales]
BEGIN
[Estructuras Ejecutables]
[EXCEPTION]
Manejadores de Excepciones
END [nombre];

Las ventajas de utilizar funciones son:


Permitir clculos muy complejos, lentos o no disponibles con SQL.
Anlisis de datos complejos pueden realizarse dentro del servidor Oracle mejor que recuperando los datos dentro de una aplicacin. Esto incrementa la independencia de los datos.
Incrementa la eficiencia de las consultas, realizando funciones en la propia consulta en vez
de en la aplicacin.

/ 50

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

u.d. 1

NIVEL II

Manipular nuevos tipos de datos (por ejemplo


latitud o longitud), codificando cadenas de
caracteres, y utilizando funciones para operar
con las cadenas.

Una funcin se crea de la siguiente manera:

Imagen1-3-5

Situaciones para invocar a una funcin:

La lista de expresiones del comando SELECT.

Condiciones de las clusulas WHERE y HAVING.

La clusula VALUES de la sentencia INSERT.

La clusula SET de la sentencia UPDATE.

A la hora de utilizar funciones hay que tener en cuenta:


El cuerpo de la funcin inicia con la palabra IS y finaliza con la clusula RETURN, el cual
especifica el tipo de dato del resultado a devolver.
La estructura return completa inmediatamente la ejecucin del subprograma y regresa el
control al programa que la llam.
Esta estructura deber contener una expresin, la cual ser evaluada cuando la estructura
return sea ejecutada, sta deber estar presente en la sentencia de cualquier funcin, y
en caso de no estar presente ser invocada la excepcin PROGRAM_ERROR durante la
ejecucin.
Esta caracterstica est disponible desde ciertas versiones de PL/SQL (en concreto, desde
la 2.1). Herramientas que utilicen versiones anteriores de PL, no soportan esta funcionalidad.
Los argumentos que se pasan a una funcin PL/SQL desde SQL deben utilizar el mtodo
posicional. El mtodo nombrado no est soportado.
NO se puede invocar a una funcin PL/SQL desde la clusula CHECK de una vista.
Se debe ser el propietario de la funcin o tener el privilegio EXECUTE para invocar a una

/ 51

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

funcin desde una sentencia SQL.


Debe ser una funcin almacenada, no una funcin dentro de un Bloque PL/SQL annimo
o un subprograma.
Debe ser una funcin de fila nica y NO una funcin de columna (grupo). Esto ocurre porque
no se puede tomar el valor de todos los datos de una columna como argumento.
Todos los argumentos deben ser del tipo IN. No se admiten argumentos OUT o IN OUT.
Los tipos de datos de los argumentos deben ser tipos de datos internos del Servidor
Oracle, tales como CHAR, DATE o NUMBER, y NO tipo PL/SQL como BOOLEAN, RECORD
o TABLE.
El valor resultante de la funcin Tambin debe ser un tipo de dato Oracle.

Restricciones:
Las funciones no pueden modificar datos en las tablas. No pueden ejecutar INSERT, UPDATE
o DELETE.
Slo las funciones locales que se referencian en la lista de la SELECT, en la clusula VALUES
de un INSERT o en la clusula SET de un UPDATE pueden actualizar una variable definida
en un paquete.
No pueden actualizar variables dentro de un paquete las funciones referenciadas en las
clusulas CONNECT BY, START WITH, ORDER BY o GROUP BY.
Las funciones remotas no pueden leer ni escribir el estado de un paquete. Cada vez que se
accede a un enlace de base de datos, se establece una nueva sesin en la base de datos
remota.
Las funciones que leen o escriben en el estado de un paquete no pueden utilizar paralelismo.

15.3 PAQUETES
Un paquete es una unidad del programa almacenada, que agrupa objetos lgicamente
relacionados del PL/SQL, y los almacena en la base de datos como un solo objeto. Los
objetos relacionados PL/SQL pueden ser constantes, variables, cursores, excepciones,
procedimientos, y/o funciones. Un paquete PL/SQL tiene dos partes: la especificacin del
paquete y el cuerpo del paquete.
La especificacin del paquete consiste en las declaraciones de los objetos relacionados
que se incluirn en el paquete. En el caso de procedimientos y de funciones, solamente la
firma o la cabecera del procedimiento o de la funcin se incluye en la especificacin del
paquete. La puesta en prctica real de estos procedimientos y funciones se da en el cuerpo
del paquete. Adems, el cuerpo del paquete puede contener otras declaraciones, como
variables, constantes, cursores, e, incluso, procedimientos y funciones no definidos en la
especificacin del paquete.
Las declaraciones en la especificacin del paquete se llaman declaraciones Pblicas, pues su
alcance es la sesin entera de la base de datos, y todos los programas de aplicaciones que
tienen acceso a dicho paquete pueden referirse a ellos. Las declaraciones, los procedimientos
y las funciones adicionales definidos en el cuerpo del paquete se llaman Privadas, porque
son accesibles solamente para el creador del paquete. De esta manera, se puede referir a
ellos solamente en el cdigo contenido en el cuerpo del paquete, y no por otras aplicaciones

/ 52

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

PL/SQL. Los paquetes no pueden ser llamados o pasados como parmetros.


Ahora la pregunta es, por qu son necesarios dos objetos separados en una especificacin y
un cuerpo del paquete? La respuesta es doble: ocultar la informacin y mantenimiento fcil.
Separando los detalles de la puesta en prctica de la definicin, no se necesita recompilar ni
cambiar programas cuando se cambia. Si la lgica del negocio de un procedimiento o de una
funcin empaquetada cambia, el cambio se puede aplicar solamente al cuerpo del paquete.
De esta manera, las referencias a los programas no son afectadas. Tambin, as el paquete
es ms seguro, porque la cabecera del paquete sigue siendo igual. Y, definiendo objetos
privados dentro del cuerpo del paquete, hay informacin que oculta de otros usuarios del
paquete. Estos objetos siguen siendo privados al paquete particular.

La sintaxis es:
PACKAGE nombre IS
-- Declaraciones de tipos y objetos pblicos
-- especificaciones de los subprogramas
END [nombre];
PACKAGE BODY nombre IS
-- Declaraciones de tipos y objetos privados
-- Cuerpos de los subprogramas
[BEGIN
-- Estructura de Inicializacin ]
END [name];

Ejemplo:
CREATE OR REPLACE PACKAGE BODY orgMaster
IS
-- Procedimiento para crear un Nuevo registro en la tabla org_tab
PROCEDURE createOrg (ip_hrc_code NUMBER,
ip_org_id NUMBER,
ip_org_short_name VARCHAR2,
ip_org_long_name VARCHAR2,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
BEGIN
INSERT INTO org_tab VALUES
(ip_hrc_code, ip_org_id, ip_org_short_name, ip_org_long_name);
op_retcd := 0;
EXCEPTION WHEN DUP_VAL_ON_INDEX THEN
op_retcd := -1;
op_err_msg := Organization with Id ||TO_CHAR(ip_org_id)||
already exists.;
WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END createOrg;
-- Procedimiento para actualizar los nombres cortos y largos de un registro de la tablan
org_tab
-- Basado en la entrada org_id
PROCEDURE updateOrg(ip_org_id NUMBER,
ip_org_short_name VARCHAR2,
ip_org_long_name VARCHAR2,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
BEGIN
UPDATE org_tab

/ 53

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

SET org_short_name = ip_org_short_name,


org_long_name = ip_org_long_name
WHERE org_id = ip_org_id;
IF (SQL%NOTFOUND) THEN
op_retcd := -1;
op_err_msg := Organization with Id ||TO_CHAR(ip_org_id)||
does not exist.;
RETURN;
END IF;
op_retcd := 0;
EXCEPTION WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END updateOrg;
-- Procedimiento que borra un registro en org_tab
PROCEDURE removeOrg(ip_org_id NUMBER,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
BEGIN
DELETE org_tab WHERE org_id = ip_org_id;
IF (SQL%NOTFOUND) THEN
op_retcd := -1;
op_err_msg := Organization with Id ||TO_CHAR(ip_org_id)||
does not exist.;
RETURN;
END IF;
op_retcd := 0;
EXCEPTION WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END removeOrg;
-- Funcin que devuelve una fila de org_tab .
-- Devuelve un conjunto de resultados del tipo REF CURSOR definido en la especificacin
del paquete
FUNCTION getOrgInfo(ip_org_id NUMBER) RETURN rc
IS
v_rc rc;
BEGIN
OPEN v_rc FOR SELECT * FROM org_tab WHERE org_id = ip_org_id;
RETURN (v_rc);
EXCEPTION WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20001, SQLERRM);
END getOrgInfo;
-- Funcin que devuelve todas las filas de org_tab.
-- Devuelve un conjunto de resultados del tipo REF CURSOR definido en la especificacin
del paquete
FUNCTION getAllOrgs(ip_hrc_code NUMBER) RETURN rc
IS
v_rc rc;
BEGIN
OPEN v_rc FOR SELECT * FROM org_tab WHERE hrc_code = ip_hrc_code;
RETURN (v_rc);
EXCEPTION WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20002, SQLERRM);
END getAllOrgs;
-- Procedimiento para insertar un registro en la tabla org_site_tab based PROCEDURE
assignSiteToOrg(ip_org_id NUMBER,
ip_site_no NUMBER,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
v_num NUMBER;
BEGIN
BEGIN

/ 54

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

u.d. 1

NIVEL II

SELECT 1
INTO
v_num
FROM
org_site_tab
WHERE org_id = ip_org_id
AND site_no = ip_site_no;
IF (v_num = 1) THEN
op_retcd := 0;
RETURN;
END IF;
EXCEPTION WHEN NO_DATA_FOUND THEN
INSERT INTO org_site_tab VALUES (ip_org_id, ip_site_no);
END;
op_retcd := 0;
EXCEPTION WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END assignSiteToOrg;
END orgMaster;
/

Identificar paquetes
Para identificar a los tipos, objetos y subprogramas declarados dentro de un paquete debe
emplearse la notacin siguiente:

package_nombre.type_name

package_nombre.objeto_name

package_nombre.subprograma_name

Ejemplo:
DECLARE
v_retcd NUMBER;
v_err_msg VARCHAR2(1000);
BEGIN
orgMaster.createOrg(3, 1011,Office of Dir. SSL,Office of Dir. SSL,
v_retcd, v_err_msg);
IF (v_retcd <> 0) THEN
DBMS_OUTPUT.PUT_LINE(ERR: ||v_err_msg);
END IF;
END;
/

La salida del programa es:


SQL> select * FROM org_tab where org_id = 1011;
HRC_CODE
ORG_ID ORG_SHORT_NAME
--------------------------------ORG_LONG_NAME
--------------------------------3
1011 Office of Dir. SSL
Office of Dir. SSL

Objetos privados
Estos objetos son accesibles solamente al cuerpo del propio paquete y tambin puede
referirse a ellos sin la notacin del punto.

Instanciation e inicializacin del paquete

/ 55

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

La primera vez que se refiere una variable empaquetada, o se llama a un procedimiento o


una funcin empaquetada, el paquete se carga en la memoria (pool compartido) del disco y
permanece all durante toda la sesin. Este proceso se llama instanciacin del paquete. Para
cada usuario, se asigna una posicin de memoria en el pool compartido para el paquete, y se
hace una copia de las variables empaquetadas en la memoria de la sesin, as las variables
empaquetadas persisten durante toda la sesin. Estas variables constituyen el estado del
paquete en tiempo de ejecucin. As que, cualquier inicializacin de variables o cdigo se
ejecutar una vez realizada esta ejecucin. Este proceso de inicializacin se puede especificar
por medio de una seccin de inicializacin en el cuerpo del paquete.

La sintaxis es:
[BEGIN
sequence_of_statements ... ]

En este ejemplo, se muestra el cuerpo del paquete orgMaster, con una seccin de inicializacin incluida:
CREATE OR REPLACE PACKAGE BODY orgMaster
IS
-- Proc para borrar filas de org_site_tab table
-- Primero es necesario borrar las filas de org_tab.
-- Este proc llama a removeOrg
PROCEDURE removeOrgSites(ip_org_id NUMBER,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
BEGIN
DELETE org_site_tab WHERE org_id = ip_org_id;
op_retcd := 0;
EXCEPTION WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END removeOrgSites;
- Proc para crear un Nuevo registro en in org_tab
PROCEDURE createOrg (ip_hrc_code NUMBER,
ip_org_id NUMBER,
ip_org_short_name VARCHAR2,
ip_org_long_name VARCHAR2,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
BEGIN
INSERT INTO org_tab VALUES
(ip_hrc_code, ip_org_id, ip_org_short_name, ip_org_long_name);
op_retcd := 0;
EXCEPTION WHEN DUP_VAL_ON_INDEX THEN
op_retcd := -1;
op_err_msg := Organization with Id ||TO_CHAR(ip_org_id)||
already exists.;
WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END createOrg;
-- Proc para actualizar los nombres cortos y largos de org_tab
-- basados en la entreada de org_id
PROCEDURE updateOrg(ip_org_id NUMBER,
ip_org_short_name VARCHAR2,
ip_org_long_name VARCHAR2,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)

/ 56

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

IS
BEGIN
UPDATE org_tab
SET org_short_name = ip_org_short_name,
org_long_name = ip_org_long_name
WHERE org_id = ip_org_id;
IF (SQL%NOTFOUND) THEN
op_retcd := -1;
op_err_msg := Organization with Id ||TO_CHAR(ip_org_id)||
does not exist.;
RETURN;
END IF;
op_retcd := 0;
EXCEPTION WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END updateOrg;
-- Proc para borrar un registro en org_tab
PROCEDURE removeOrg(ip_org_id NUMBER,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
BEGIN
removeOrgSites(ip_org_id, op_retcd, op_err_msg);
IF (op_retcd <> 0) then
RETURN;
END IF;
DELETE org_tab WHERE org_id = ip_org_id;
IF (SQL%NOTFOUND) THEN
op_retcd := -1;
op_err_msg := Organization with Id ||TO_CHAR(ip_org_id)||
does not exist.;
RETURN;
END IF;
op_retcd := 0;
EXCEPTION WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END removeOrg;
-- Funcin que devuelve una fila de org_tab.
-- Devuelve un conjunto de resultados del tipo REF CURSOR, definido en la especificacin
del paquete
FUNCTION getOrgInfo(ip_org_id NUMBER) RETURN rc
IS
v_rc rc;
BEGIN
OPEN v_rc FOR SELECT * FROM org_tab WHERE org_id = ip_org_id;
RETURN (v_rc);
EXCEPTION WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20001, SQLERRM);
END getOrgInfo;
-- Funcin que devuelve todas las filas de org_tab.
-- Devuelve un conjunto de resultados del tipo REF CURSOR, definido en la especificacin
del paquete
FUNCTION getAllOrgs(ip_hrc_code NUMBER) RETURN rc
IS
v_rc rc;
BEGIN
OPEN v_rc FOR SELECT * FROM org_tab WHERE hrc_code = ip_hrc_code;
RETURN (v_rc);
EXCEPTION WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20002, SQLERRM);
END getAllOrgs;
-- Procedimiento para insertar un registro en la tabla org_site_tab based

/ 57

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

PROCEDURE assignSiteToOrg(ip_org_id NUMBER,


ip_site_no NUMBER,
op_retcd OUT NUMBER,
op_err_msg OUT VARCHAR2)
IS
v_num NUMBER;
BEGIN
BEGIN
SELECT 1
INTO
v_num
FROM
org_site_tab
WHERE org_id = ip_org_id
AND site_no = ip_site_no;
IF (v_num = 1) THEN
op_retcd := 0;
RETURN;
END IF;
EXCEPTION WHEN NO_DATA_FOUND THEN
INSERT INTO org_site_tab VALUES (ip_org_id, ip_site_no);
END;
op_retcd := 0;
EXCEPTION WHEN OTHERS THEN
op_retcd := SQLCODE;
op_err_msg := SQLERRM;
END assignSiteToOrg;
-- Esta es la seccin de inicializacin que se ejecuta
-- la primera vez que se llama al subprograma
-- o se referencia a una variable empaquetada
BEGIN
max_sites_for_an_org := 4;
END orgMaster;
/

15.4 FUNCIONES EMPAQUETADAS.


Se puede especificar el nivel de depuracin de una funcin empaquetada cuando se crea
el paquete. El nivel de depuracin determina qu operaciones puede realizar la funcin en
la base de datos. Para especificar en nivel de depuracin se utiliza el paquete predefinido
RESTRICT_REFERENCES.
Sintaxis
PRAGMA RESTRICT_REFERENCES (nombre_funcin, WNDS,
[,WNPS] [,RNDS] [,RNPS]);

Donde:
WNDS: Si se aplica esta opcin, la funcin no puede modificar tablas de la base de datos.
(Writes No Database State).
WNPS: Si se aplica esta opcin, la funcin no puede cambiar los valores de variables de un
paquete pblico. (Writes No Package Status).
RNDS: Si se aplica esta opcin, la funcin no puede consultar ninguna tabla de la base de
datos. (Reads No Database State).
RNPS: Si se aplica esta opcin, la funcin no puede referenciar los valores de las variables
de un paquete pblico. (Reads No Database Status).
Este paquete sirve para alertar a los desarrolladores de aplicaciones con cdigo procedural,
que incumplen las restricciones de las funciones PL/SQL dentro de sentencias SQL.
Este paquete predefinido indica al compilador PL/SQL qu tipo de acciones pueden realizar
las funciones. Las sentencias SQL que incumplan estas reglas producen un error de com-

/ 58

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

u.d. 1

NIVEL II

pilacin.
El argumento WNDS debe indicarse SIEMPRE que se utilice RESTRICT_REFERENCES.
El propsito de indicar un nivel de depuracin en las funciones es identificar los errores en
tiempo de compilacin, en vez de esperar a la ejecucin.

Ejemplo:
Crear una funcin llamada COMP, dentro del paquete FINANZAS. La funcin ser invocada
desde sentencias SQL en bases de datos remotas. Por lo tanto, ser necesario indicar los
niveles de depuracin RNPS y WNPS, porque las funciones remotas no pueden nunca escribir
o leer el estado del paquete cuando se le invoca desde una sentencia SQL.
CREATE PACKAGE finanzas AS -- especificacin del paquete
interes REAL;
-- variable pblica del paquete
...
FUNCTION comp
(anos
IN NUMBER
cant
IN NUMBER
porc
IN NUMBER) RETURN NUMBER;
...
PRAGMA RESTRICT_REFERENCES(comp, WNDS, RNPS, WNPS);
END finanzas;
CREATE PACKAGE BODY finanzas AS -- cuerpo del paquete
FUNCTION comp
(anos
IN NUMBER
cant
IN NUMBER
porc
IN NUMBER) RETURN NUMBER IS
BEGIN
RETURN cant * POWER((porc/100) + 1, anos);
END comp;
...
END finanzas;

Se debe fijar el nivel de depuracin de una funcin en la zona de especificacin del paquete.
Si el paquete contiene varias funciones con el mismo nombre, el nivel de depuracin se
aplica a la ltima.

16. DISPARADORES O TRIGGERS DE LA BASE DE DATOS


Adems de los tipos de subprograma mencionados anteriormente, PL/SQL permite un cuarto
tipo de subprograma almacenado, llamado un TRIGGER de la base de datos. Un TRIGGER
de la base de datos es un subprograma almacenado, que se almacena en la base de datos
y se ejecuta implcito cuando ocurre un evento. El evento puede ser una operacin DDL, tal
como una creacin de objeto, una alteracin, una operacin DML, como INSERT, UPDATE,
o DELETE en una tabla o una vista; un evento del sistema, puede ser un arranque y parada
de la base de datos, conexin, y trmino de sesin; o un evento de usuario, como conexin
del esquema y trmino de sesin.
Los Triggers de la base de datos permiten realizar varias funciones que, de otra forma,
seran muy tediosas. Las aplicaciones ms comunes de los triggers de la base de datos son
las siguientes:

Para la revisin de DDL y de DML.

Para hacer cumplir reglas complejas de validacin, para evitar que se introduzcan
datos errneos o inadecuados en la base de datos.

Para realizar acciones relacionadas cuando ocurre una accin particular.

Para hacer cumplir las relaciones complejas de la integridad de los datos que no se
/ 59

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

pueden especificar de
otra manera declaradamente; por ejemplo, una operacin de
conexin en cascada
de UPDATE en una
tabla hijo, siempre
que una fila del padre
sea actualizada.

Para
generar automticamente valores derivados.

Imagen1-3-6

Triggers PL/SQL: Definicin y Tipos


Un trigger de la base de datos es un programa almacenado, ejecutado en respuesta a un
evento de la base de datos. Este evento se llama el evento disparador, y puede ser uno de
los siguientes:
Una operacin DDL por ejemplo CREATE, ALTER, o DROP.
Una operacin de DML como INSERT, UPDATE, o DELETE.
Un evento del sistema como STRATUP, SHUTDOWN, o SERVERERROR de la base de
datos.
Un evento del usuario como LOGON o LOGOOFF.

16.1 DEFINIR TRIGGERS


Un trigger de la base de datos se define usando la declaracin CREATE O REPLACE TRIGGER y su sintaxis es:
CREATE [OR REPLACE] TRIGGER trigger_name
[BEFORE|AFTER|INSTEAD OF] triggering_event
[referencing_clause]
[WHEN trigger_restriction]

/ 60

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

u.d. 1

NIVEL II

[FOR EACH ROW]


trigger_body;

Donde trigger_name es el nombre del trigger que es creado, triggering_event especifica un


evento particular que dispara el trigger, y trigger_body es un bloque PL/SQL que especifica
la accin que el trigger realiza cuando se dispara. En vez de un bloque del PL/SQL, el cuerpo
del trigger puede ser una sentencia CALL que invoca un procedimiento o una funcin PL/SQL
o un procedimiento almacenado Java, publicado en PL/SQL. La clusula REFERENCING se
ve ms adelante.
Ejemplo:
CREATE OR REPLACE TRIGGER ai_org_trig
AFTER INSERT ON org_tab
FOR EACH ROW
BEGIN
UPDATE sec_hrc_audit
SET num_rows = num_rows+1
WHERE hrc_code = :NEW.hrc_code;
IF (SQL%NOTFOUND) THEN
INSERT INTO sec_hrc_audit VALUES (:NEW.hrc_code, 1);
END IF;
END;
/

Tiene tres partes distintas: el evento que lo acciona, la restriccin que acciona, y el cuerpo
del trigger. Dependiendo del tipo de trigger, el evento que acciona puede ser un evento
DML, un evento del sistema, o un evento del usuario que causa el disparo del trigger. En el
trigger del ejemplo, el evento que acciona es la sentencia.
AFTER INSERT ON org_tab

En este caso, el evento es la operacin de INSERT en la tabla del org_tab, y este trigger se
dispara siempre que una operacin INSERT se ejecute en la tabla org_tab, despus de que
se escriba la nueva fila en la tabla del org_tab. La sentencia INSERT que causa el evento
del trigger se llama la sentencia disparadora. La restriccin que acciona es una condicin
opcional especificada como clusula WHEN, que hace que el cuerpo del trigger se ejecute
solamente cuando la condicin es TRUE. El cuerpo del trigger especifica el cdigo que se
ejecutar (es decir, la secuencia de las acciones que se realizarn) cuando l se dispare.

Ejemplo:
BEGIN
UPDATE sec_hrc_audit
SET num_rows = num_rows+1
WHERE hrc_code = :NEW.hrc_code;
IF (SQL%NOTFOUND) THEN
INSERT INTO sec_hrc_audit VALUES (:NEW.hrc_code, 1);
END IF;
END;

Un trigger no acepta parmetros, no incluye una seccin ejecutable con BEGIN y END, y
puede incluir una seccin opcional de sentencia y una seccin de la direccin de excepcin.
La seccin del BEGIN END puede incluir declaraciones de SQL y/o PL/SQL, llamadas a
procedimientos PL/ SQL y a las funciones (independientes o empaquetadas). Tambin, el
cuerpo del trigger puede ser una sola sentencia CALL, que invoca un procedimiento PL/SQL,
funcin o un procedimiento almacenado Java, publicado en PL/SQL.

/ 61

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

16.2 TIPOS DE TRIGGERS


Los triggers se clasifican segn el evento que los dispara. Se puede fijar para disparar cualquier tirgger antes o despus del evento particular. Los triggers se dividen en tres categoras
principales: Triggers DML, Triggers INSTEAD-OF, y Triggers de eventos del sistema y del
usuario.

Triggers DML
Una DML acciona un trigger cuando una sentencia INSERT, UPDATE, o DELETE se ejecuta
en una tabla de la base de datos. Pueden ser clasificados ms a fondo como triggers de la
FILA o SENTENCIA, y especifican cuntas veces debe ser ejecutado el cuerpo del trigger.

Triggers INSTEAD-OF
INSTEAD-OF acciona el trigger en las declaraciones DML publicadas contra una vista relacionada o un objeto view. (Se vern mas adelante punto 3.11)

Triggers en eventos del sistema y del usuario


Se disparan cuando se produce un evento en el sistema, por ejemplo arranque y parada de
la base de datos, siempre que ocurra un error del servidor, o cuando ocurre un evento de
usuario como login y logoff de sesin del usuario o se ejecuta un comando DDL. (Se vern
mas adelante punto 3.12)
Una segunda clasificacin de Triggers se basa en el momento en que se produce el evento.
stos son triggers BEFOR y UPDATE. El trigger debe dispararse antes o despus de que
suceda el evento que lo dispara. Estos triggers pueden pertenecer a los triggers DML o a
los triggers en eventos del sistema y del usuario.

16.3 TRIGGERS DML


Para definir triggers DML con la sentencia CREATE O REPLACE del trigger se realiza:
CREATE [OR REPLACE] TRIGGER trigger_name
[BEFORE|AFTER] triggering_event [OF column_name] ON table_name
[referencing_clause]
[WHEN trigger_restriction]
[FOR EACH ROW]
trigger_body ;

Donde trigger_name es el nombre del trigger de DML que es creado; triggering_event es una
combinacin INSERT, UPDATE, y/o DELETE; y el table_name es la tabla en la cual se est
ejecutando el INSERT, UPDATE; y/o DELETE. [OF column_name] la clusula que especifica
el column_name, que es actualizado en el caso de que una operacin UPDATE sea el evento
que lo acciona. BEFORE o AFTER especifica cundo se dispara el trigger (es decir, antes
o despus de que se ejecuta la sentencia DML); trigger_body es la secuencia de acciones
que se realizarn cuando se enciende el trigger, y la clusula [WHEN condicin] especifica
cualquier condicin que evala el cuerpo del trigger para ejecutarse.

Ejemplo:

/ 62

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

CREATE OR REPLACE TRIGGER ai_org_trig


AFTER INSERT ON org_tab
FOR EACH ROW
BEGIN
UPDATE sec_hrc_audit
SET num_rows = num_rows+1
WHERE hrc_code = :NEW.hrc_code;
IF (SQL%NOTFOUND) THEN
INSERT INTO sec_hrc_audit VALUES (:NEW.hrc_code, 1);
END IF;
END;
/

Los triggers DML pueden ser de dos tipos:


A nivel de FILA (ROW TRIGGER): Se dispara cada vez que se ejecuta una operacin sobre
una fila, se pueden especificar con la clusula FOR EACH ROW.
A nivel de SENTENCIA (STATEMENT TRIGGER): Se dispara cada vez que se ejecuta una
sentencia.
Esto significa que si una sola sentencia UPDATE afecta a diez filas, un trigger a nivel de fila
se dispara diez veces, mientras que un trigger a nivel de sentencia se dispara solamente
una vez.
La siguiente tabla muestra una comparacin entre ambos tipos de trigger.
NIVEL DE LA FILA
Se dispara para cada fila afectada por la
sentencia que acciona.
No se dispara, si el evento que acciona no
afecta ninguna fila.
Se puede especificar BEFORE y AFTER
El cuerpo del trigger tiene acceso a los
datos de la fila.
Afectado actualmente por el evento que
acciona.
AFTER ROW dispara el bloqueo de los datos
de la fila.

NIVEL DE LA SENTENCIA
Se dispara una vez para la sentencia que
acciona.
Se dispara, aunque el evento que acciona no
afecte a ninguna fila.
Se puede especificar BEFORE y AFTER
El cuerpo del TRIGGER no tiene acceso a los
datos de la fila.
Afectado actualmente por el evento que
acciona.
No bloquea las filas.

En el ejemplo del trigger ai_org_trig, el nuevo valor del hrc_code que se inserta se refiere
al cuerpo del trigger como:NEW.hrc_code, y lo hace a nivel de fila; pero, tb se puede hacer
cambiar este trigger a nivel de sentencia.
CREATE OR REPLACE TRIGGER ai_org_trig_statement
AFTER INSERT ON org_tab
BEGIN
FOR idx IN (SELECT hrc_code, COUNT(*) cnt
FROM org_tab
GROUP BY hrc_code) LOOP
UPDATE sec_hrc_audit
SET num_rows = idx.cnt
WHERE hrc_code = idx.hrc_code;
IF (SQL%NOTFOUND) THEN
INSERT INTO sec_hrc_audit VALUES (idx.hrc_code, idx.cnt);
END IF;
END LOOP;
END;

/ 63

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

u.d. 1

NIVEL II

16.4 CLUSULA REFERENCING


Esta clusula especifica cmo se deben identificar dentro del cuerpo del trigger los datos
que son modificados por el evento que lo acciona. Por defecto, los datos modificados
estn disponibles dentro del cuerpo del trigger en el caso de un ROW trigger, y son identificados por los identificadores: NEW y :OLD. Estos identificadores actan como variables
enlazadas, y mantienen los datos de la fila actual como un registro del tipo % ROWTYPE,
donde table_name es el nombre de la tabla de la base de datos en la cual se define el trigger DML. Sin embargo, :NEW y :OLD son solamente pseudo-records, no son los registros
reales. Dentro del cuerpo del trigger, los valores de la columna se pueden identificar como:
NEW.column_name o :OLD.column_name, donde column_name es una columna vlida en
la tabla en la que se dispara el ROW trigger.
En el ejemplo del trigger ai_org_trig, el nuevo valor de la columna hrc_code que se inserta
se identifica en el cuerpo del trigger como :NEW.hrc_code.
La clusula REFERENCING permite que se identifique a las columnas de la fila que se modifica, utilizando los nombres personalizados en vez de :NEW y :OLD. La sintaxis es:
[REFERENCING [OLD AS custom_name_for_old] [NEW AS custom_name_for_new]]

Donde custom_name_for_old y el custom_name_for_new son los nombres personalizados


definidos :OLD y :NEW, respectivamente.
Ejemplo:
CREATE OR REPLACE TRIGGER ai_org_trig
AFTER INSERT ON org_tab
REFERENCING NEW AS new_org
FOR EACH ROW
BEGIN
UPDATE sec_hrc_audit
SET num_rows = num_rows+1
WHERE hrc_code = :new_org.hrc_code;
IF (SQL%NOTFOUND) THEN
INSERT INTO sec_hrc_audit VALUES (:new_org.hrc_code, 1);
END IF;
END;
/
Nota:
Se utiliza new_org en vez de :NEW.

Los valores de :OLD y :NEW son diferentes para los eventos triggers del INSERT, UPDATE,
y DELETE. En el caso de la sentencia INSERT, solamente se deinfe :NEW. Para UPDATE
se definen los dos, :OLD y :NEW. Y en el caso de DELETE, solamente se define :OLD. Los
valores que se identifican con :OLD.column_name o :NEW.column_name son los resultados
indefinidos en los valores NULL.

16.5 CLUSULA WHEN


Esta clusula especifica cualquier condicin WHERE que se especifique en la ejecucin
del cuerpo del trigger. Esta condicin WHERE se aplica a las filas que son afectadas por el
evento que se dispara. Si la condicin evaluada es TRUE para una fila, se ejecuta el cuerpo

/ 64

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

del trigger. La sintaxis es:


WHEN trigger_restriction

Donde el trigger_restriction es la condicin que evala a un valor BOOLEAN, TURE o


FALSE.

Ejemplo.
CREATE OR REPLACE TRIGGER ai_org_trig
AFTER INSERT ON org_tab
REFERENCING NEW AS new_org
FOR EACH ROW
WHEN (new_org.hrc_code <> 1)
BEGIN
UPDATE sec_hrc_audit
SET num_rows = num_rows+1
WHERE hrc_code = :new_org.hrc_code;
IF (SQL%NOTFOUND) THEN
INSERT INTO sec_hrc_audit VALUES (:new_org.hrc_code, 1);
END IF;
END;
/

16.6 VARIOS EVENTOS QUE DISPARAN UN TRIGGER DML


Segn lo dicho anterior, se pueden especificar varias operaciones DML para el evento que
las dispara, separndolas con la palabra clave OR. Para distinguir entre las tres operaciones, PL/SQL proporciona predicados del trigger. PL/SQL define tres predicados llamados
INSERTING, UPDATING, y DLETRING para aplicar operaciones INSERT, UPDATE, y DELETE,
respectivamente. Estos predicados se utilizan como condiciones booleanas en sentencias
IF en el cuerpo del trigger.
Ejemplo:
IF INSERTING THEN
...
ELSIF UPDATING THEN
...
ELSIF DELETING THEN
...
END IF;

Considerar el trigger ai_org_trig que se ha avisto anteriormente. Este trigger actualiza la


tabla sec_hrc_audit, siempre que se inserte una nueva fila en la tabla org_tab. Pero qu
pasa cuando se DELETE una fila en la tabla orc_tab? La columna num_rows en la tabla
sec_hrc_audit se decrementa. Para esto, es suficiente escribir un nuevo trigger con DELETE
como el evento que lo dispara. Sin embargo, con los predicados del trigger, con un solo
trigger puede alcanzar la misma funcionalidad para las operaciones INSERT y DELETE.
Ejemplo del trigger ai_org_trig modificado:
CREATE OR REPLACE TRIGGER ai_org_trig
AFTER INSERT OR DELETE ON org_tab
FOR EACH ROW
BEGIN
IF INSERTING THEN
UPDATE sec_hrc_audit
SET num_rows = num_rows+1
WHERE hrc_code = :NEW.hrc_code;
IF (SQL%NOTFOUND) THEN
INSERT INTO sec_hrc_audit VALUES (:NEW.hrc_code, 1);

/ 65

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

END IF;
ELSIF DELETING THEN
UPDATE sec_hrc_audit
SET num_rows = num_rows1
WHERE hrc_code = :
OLD.hrc_code;
END IF;
END;
/

16.7 NMERO Y TIPO DE TRIGGERS DML QUE SE PUEDEN


DEFINIR EN UNA SOLA
TABLA
Como se ha dicho anteriormente, los triggers DML
pueden ser BEFORE o AFTER,
y pueden estar a nivel de FILA
(ROW TRIGGER) o de SENTENCIA (STATEMENT TRIGGER).
Considerando estos dos factores, se puede definir un total de cuatro triggers DML en una
tabla: BEFORE STATEMENT, BEFORE ROW, AFTER ROW, y AFTER STATEMENT.
Tambin, los triggers DML se pueden disparar cuando una sentencia INSERT, UPDATE, o
DELETE se ejecuta en la tabla en la cual se define el trigger. Teniendo todo esto en cuenta,
hay un total de 12 combinaciones posibles. La tabla siguiente resume esas combinaciones
posibles.

Imagen1-3-8

Aunque hay 12 combinaciones posibles, se pueden definir varios triggers del mismo tipo
en la misma tabla. (Esto es posible a partir e PL/SQL 2.1.) Otra cosa importante es el orden
en la cual se disparan triggers.

El orden es:
BEFORE STATEMENT (se dispara una vez por sentencia DML, no importa a cuntas filas
afecta).
BEFORE ROW (se dispara una vez por cada fila afectada por la sentencia DML).

Ejecutar la sentencia que se dispara s mismo.


AFTER ROW (se dispara una vez por cada fila afectada por la sentencia DML).

/ 66

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

AFTER STATEMENT (se dispara una vez por cada sentencia DML, no importa a cuantas
filas afecta).

16.8 OTROS CONCEPTOS DEL TRIGGER


Habilitar y deshabilitar triggers
Un trigger est habilitado por defecto, con tal de que se encuentre cualquier condicin especificada en el trigger. Un trigger est deshabilitado, cuando no se dispara en la ejecucin de
la sentencia que lo acciona, aunque la condicin del trigger evaluada sea TRUE. Un ejemplo
de cundo inhabilitar un trigger es cuando se estn cargando cantidades grandes de datos
de fuentes externas. Se inhabilita los triggers en una tabla particular, y despus de la carga
de datos se habilita de nuevo.
Para habilitar o deshabilitar triggers se usa la sentencia ALTER TRIGGER.
La sintaxis es:
ALTER TRIGGER ai_org_trig DISABLE;

Donde trigger_name es el nombre del trigger que se habilita o deshabilita.


Ejemplo:
ALTER TRIGGER ai_org_trig DISABLE;

Tambin es posible habilitar o deshabilitar todos los triggers en una tabla particular. Esto
se hace con la sentencia ALTER TABLE. La sintaxis es:
ALTER TABLE table_name ENABLE| DISABLE ALL TRIGGERS;

Ejemplo:
ALTER TABLE org_tab DISABLE ALL TRIGGERS;

La columna STATUS en las vistas USER_TRIGGERS y ALL_TRIGGERS indica si un trigger


est habilitado o deshabilitado.
Adems de estos triggers, se puede borrar (DROP) un trigger en concreto de una tabla. Esto
es parecido a los subprogramas que borran. Cuando se borra un trigger, deja de existir, y
todas sus referencias se quitan de las vistas correspondientes del diccionario de los datos.
La sintaxis es:
DROP TRIGGER trigger_name;

Privilegios requeridos para crear Triggers


Para crear un trigger en el esquema actual, se debe conceder el privilegio CREATE TRIGGER
al propietario.
Para crear un trigger en cualquier esquema, se debe conceder el privilegio CREATE ANY
TRIGGER. Esto permite la creacin de un trigger en cualquier esquema, y en cualquier tabla
de ese esquema.
Para modificar un trigger en cualquier esquema para habilitar, deshabilitar, o compilar se
debe conceder el privilegio ALTER ANY TRIGGER.

/ 67

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

u.d. 1

NIVEL II

Para borrar un trigger en cualquier esquema, se debe conceder el privilegio DROP ANY
TRIGGER.
Para crear triggers del sistema a nivel de base de datos, adems del privilegio CREAT
TRIGGER o CREATE ANY TRIGGER, se debe conceder el privilegio ADMIN DATABASE
TRIGGER.
Todos los privilegios sobre los triggers se tienen que dar explcitamente, y no mediante una
regla. CREATE ANY TRIGGER, ALTER ANY TRIGGER y DROP ANY TRIGGER trabajan sobre
esquemas, con excepcin del sistema. Se debe conceder a todos los objetos los privilegios
apropiados. Las declaraciones en el cuerpo del trigger se ejecutan bajo los privilegios del
propietario del trigger, no bajo privilegios del usuario que publica la sentencia que los
dispara.

16.9 COMPILACIN DE TRIGGERS


Un trigger se compila la primera vez cuando se crea. La compilacin de un trigger implica
la resolucin de sintaxis, de referencias semnticas y de la generacin del p-cdigo. Un
trigger con errores en la compilacin se crea, pero, en el tiempo de ejecucin, la sentencia
que lo dispara falla. Sin embargo, su estado puede ser invalidado, si se alteran cualquiera
de sus objetos subordinados. En este caso, es necesario recompilar el trigger. Se puede
recompilar el trigger de dos maneras:

1. Automticamente: Se hace cuando un trigger que es invalidado, debido a las dependencias, cuando se invoca la prxima vez.

2. Declarativamente: Se hace con la sentencia ALTER TRIGGER. La sintaxis es:

ALTER TRIGGER trigger_name COMPILE;

16.10 RESTRICCIONES EN TRIGGERS


Hay varias restricciones para usar Triggers, como el tamao mximo del cuerpo del trigger
y el tipo de declaraciones DML y DCL que se puede utilizar. Tambin hay restricciones referentes a la mutacin y el constraint de las tablas. La lista de restricciones que hay son:
Un trigger no puede exceder 32KB de tamao.
No se pueden utilizar declaraciones DDL. En el caso de DML, se puede utilizar solamente
INSERT, UPDATE, DELETE, y SELECT INTO o un cursor SELECT. No se puede utilizar
COMMIT, ROLLBACK, y SAVEPOINT.
No se pueden declarar variables LONG ni LONG RAW. Tampoco se puede utilizar :NEW y :
OLD en columnas LONG y LONG RAW de la tabla que lo dispara.
Las columnas LOB solamente se pueden leer dentro del cuerpo de un trigger. Esto significa
que se no puede asignar un valor :NEW.lob_column dentro del cuerpo del trigger.
Las restricciones de la tabla de mutacin dicen qu tablas y columnas pueden tener acceso
un cuerpo del trigger. Se llama una tabla de mutacin (mutating), si est siendo modificada
actualmente por un trigger o una sentencia INSERT, UPDATE, o DELETE. Tambin, una tabla
que se modifica como resultado de la constrain de integridad referencial en un borrado en
cascada, mutating. Una tabla limitada (Constraining) es una tabla que se especifica en la
clusula REFERENCING en la definicin de una constraint de clave externa. El concepto de
tablas mutating se aplica a los ROW triggers, con la excepcin de que cuando un STATEMENT trigger se dispara como resultado del efecto de borrado en cascada se considera
tambin mutating.

/ 68

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

Hay dos restricciones en las tablas mutating y constraining de un trigger:


El cuerpo del trigger no puede leer (consulta) o modificar una tabla mutating de la sentencia
que lo dispara.
El cuerpo del trigger no puede leer o modificar las columnas de claves primarias, nicas, o
externas de una tabla que est restringida. Las otras columnas s pueden ser modificadas.
En el caso de las tablas mutating, el trigger se dispara, pero el cuerpo del trigger no se
ejecuta, y el control se transfiere fuera del trigger con el siguiente error:
ORA-04901: table schema_name.table_name is mutating, trigger/function
may not see it

Este error salta durante la ejecucin del trigger, y no durante la creacin ni la compilacin
del trigger.
El nico caso en el que un trigger a nivel de fila puede leer o modificar la tabla que los
dispara es cuando la sentencia que acciona el trigger es una sentencia INSERT, que afecta
solamente a una fila. La sentencia INSERT SELECT no est permitida, aunque afecte a
una sola fila.
Para evitar errores mutating, se crea un ROW trigger que lea los nuevos valores de la fila
actual, y un STATEMENT trigger que pregunte o modifique la tabla mutating, basada en el
nuevo valor de la fila leda. Esto requiere un paquete PL/SQL para almacenar los nuevos valores ledos en el ROW trigger. Esta es una manera de manejar errores mutating. Un mtodo
alternativo para manejar las tablas mutating que implican errores es usando transacciones
autnomas. Sin embargo, este mtodo se debe utilizar con cuidado. El panorama perfecto para usar transacciones
autnomas para evitar errores
mutating es cuando la lgica
del trigger no es afectada por el
hecho de que los cambios realizados a la tabla que acciona
(es decir, la transaccin principal) no son visibles a la transaccin autnoma, hasta que
la transaccin principal est
confirmada. Los errores de la
tabla de Mutating son muy
inverosmiles en situaciones
normales, pero se debe tener
cuidado para evitarlos, si es
posible.

16.2 TRIGGERS INSTEAD OF


Estos triggers se usan para modificar los datos en los que las sentencias DML, cuestionadas
como resultados de las vistas, no son heredadas ni actualizables. Estos triggers se llaman
as porque no se parecen a los otros tipos de trigger que se han visto, el servidor de Oracle
dispara un trigger INSTEDA OF para ejecutar sentencias disparadoras. Se usa para llamar
INSERT, UPDATE o DELTE directamente en las tablas principales.

/ 69

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

Imagen1-3-9

Una vista no puede ser modificada por una sentencia DML normal si la consulta de la vista
contiene operadores SET, grupos de funciones, clusulas como GROUP BY, CONNECT BY,
START, el operador DISTINCT o joins. Por ejemplo, si una vista consiste en ms de una tabla,
un insert a la vista implica una insercin en una tabla y la actualizacin de otra. As que, se
escribe un trigger INSTEAD OF que se dispara cuando se escribe un insert contra la tabla
vista. En vez de una insercin normal, el cuerpo del trigger se ejecuta, y, como resultado,
se inserta en una tabla y se actualiza en otra.
La sintaxis es:
CREATE [OR REPLACE] TRIGGER trigger_name
INSTEAD OF triggering_event [OF column_name] ON view_name
[referencing_clause]
[FOR EACH ROW]
trigger_body ;

Ejemplo:
Lo primero, crear la vista hrc_org_site
CREATE VIEW hrc_org_site
AS
SELECT h.hrc_code, hrc_descr,
o.org_id, org_short_name,
org_long_name, os.site_no, site_descr
FROM
org_site_tab os, org_tab o, hrc_tab h, site_tab s
WHERE os.org_id = o.org_id
AND o.hrc_code = h.hrc_code
AND os.site_no = s.site_no;

Lo siguiente, crear un trigger INSTEAD-OF para esta vista:


CREATE OR REPLACE TRIGGER hrc_org_site_trig
INSTEAD OF INSERT OR UPDATE OR DELETE on hrc_org_site
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO hrc_tab VALUES (:NEW.hrc_code, :NEW.hrc_descr);
INSERT INTO org_tab VALUES (:NEW.hrc_code, :NEW.org_id,
:NEW.org_short_name,
:NEW.org_long_name);
INSERT INTO org_site_tab VALUES (:NEW.org_id, :NEW.site_no);
ELSIF UPDATING THEN
IF (:NEW.hrc_descr != :OLD.hrc_descr) THEN
UPDATE hrc_tab
SET
hrc_descr = :NEW.hrc_descr
WHERE hrc_code = :OLD.hrc_code;
END IF;
IF (:NEW.org_short_name != :OLD.org_short_name) THEN
UPDATE org_tab
SET
org_short_name = :NEW.org_short_name
WHERE hrc_code = :OLD.hrc_code
AND org_id = :OLD.org_id;

/ 70

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

NIVEL II

ELSIF (:NEW.org_long_name != :OLD.org_long_name) THEN


UPDATE org_tab
SET
org_long_name = :NEW.org_long_name
WHERE hrc_code = :OLD.hrc_code
AND org_id = :OLD.org_id;
END IF;
UPDATE org_site_tab
SET
site_no = :NEW.site_no
WHERE org_id = :NEW.org_id;
IF (SQL%NOTFOUND) THEN
INSERT INTO org_site_tab VALUES (:NEW.org_id, :NEW.site_no);
END IF;
ELSIF DELETING THEN
DELETE org_site_tab WHERE org_id = :OLD.org_id;
DELETE org_level WHERE org_id = :OLD.org_id;
DELETE org_tab WHERE hrc_code = :OLD.hrc_code
AND org_id = :OLD.org_id;
END IF;
EXCEPTION WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20010, ERR occurred in trigger hrc_org_site_trig ||
SQLERRM);
END;
/

Para probar este trigger, se usa un INSERT, UPDATE, y DELETE contra la vista hrc_org_
site:
INSERT INTO hrc_org_site VALUES (11, ANALYST,1012, Office of Analyst,
Office of Analyst, 4, null);
UPDATE hrc_org_site SET org_short_name = Office of Analyst ABC Inc.,
org_long_name = Office of Analyst ABC Inc., site_no = 4
WHERE hrc_code = 11
AND org_id = 1012;
DELETE hrc_org_site WHERE org_id = 1012;

Ahora, se prueba la salida de este cdigo:


SQL> SELECT * FROM hrc_tab WHERE hrc_code = 11;
no rows selected
SQL> UPDATE hrc_org_site SET org_short_name = Office of Analyst ABC Inc.,
2 org_long_name = Office of Analyst ABC Inc., site_no = 4
3 WHERE hrc_code = 11
4
AND org_id = 1012;
1 row updated.
SQL> INSERT INTO hrc_org_site VALUES (11, ANALYST,1012, Office of Analyst,
2 Office of Analyst, 4, null);
1 row created.
SQL> SELECT * FROM hrc_tab WHERE hrc_code = 11;
HRC_CODE
----------11

HRC_DESCR
----------------------ANALYST

SQL> SELECT * FROM org_tab WHERE org_id = 1012;


HRC_CODE
ORG_ID
------------------------11
1012

ORG_SHORT_NAME
ORG_LONG_NAME
--------------------------------------Office of Analyst

-------------

Office of Analyst

SQL> SELECT * FROM org_site_tab WHERE org_id = 1012;

/ 71

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers

u.d. 1

NIVEL II

ORG_ID SITE_NO
--------- ----------1012
4
SQL> DELETE hrc_org_site WHERE org_id = 1012;
1 row deleted.

16.3 TRIGGERS EN EVENTOS DE SISTEMA Y DE USUARIO


Hasta Oracle 8.0.x, la definicin de los triggers fue limitada solamente a las tablas de la
base de datos y DML como operaciones INSERT, UPDATE, y DELETE. Oracle8i ha prolongado el alcance de los triggers de la base de datos, levantando estas restricciones. Ahora,
se puede definir triggers de base de datos independientes de las tablas y de las sentencias
DML. Adems de estos triggers, a partir de PL/SQL 8i se permite crear triggers de la base
de datos durante eventos del sistema, como:

Arranque y parada de la base de datos

LOGON y LOGOFF de sesin de la base de datos

Ocurrencias de error del lado del servidor

Tambin, permite crear triggers de base de datos durante eventos de usuario, como:
Logon y logout de sesin
Eventos de usuario como ejecucin de DDL (es decir, creacin, alteracin, y el borrado de
objetos de la base de datos)
La sintaxis para crear triggers en eventos del sistema y eventos de usuario:
CREATE [OR REPLACE] TRIGGER trigger_name
[BEFORE|AFTER] {triggering_event} ON [DATABASE|[schema.]SCHEMA]
[WHEN trigger_restriction]
trigger_body ;

Donde trigger_name es el nombre del trigger que se crea; triggering_event es un o una


combinacin vlida de los eventos STARTUP, SHUTDOWN, SERVERERROR, LOGON, y/o
LOGOFF del sistema, o un o una combinacin vlida de los eventos del usuario LOGON y
LOGOFF, CREATE, ALTER, y/o DROP. BEFORE o AFTER especifica el momento en el que el
trigger se debe disparar (es decir, antes o despus de que ocurra el evento). trigger_body es
la secuencia de acciones que se realizarn cuando se dispare el trigger, y la clusula [WHEN
condicin] especifica cualquier condicin, que cuando se evala TRUE el cuerpo del trigger
ejecuta. DATABASE o SCHEMA especifica el alcance del trigger (es decir, en el nivel de la
base de datos) para todos los esquemas o para un esquema especfico.
En la siguiente tabla se muestran los triggers para eventos del sistema:
NOMBRE
SINCRONI- DESCRIPCIN
DEL EVENTO ZACIN
STARTUP
AFTER
Durante el arranque de la base de datos. Solo a nivel de
base de datos
SHUTDOWN
ANTES
Durante parada de la base de datos. Solamente a nivel de
la base de datos.
SERVEREAFTER
Una vez que ocurre una excepcin. Puede ser a nivel de base
RROR
de datos o a nivel de esquema.
LOGON
AFTER
Despus de que una aplicacin cliente acceda a la base
de datos. Puede ser a nivel de base de datos o a nivel del
esquema.

/ 72

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers


LOGOFF

BEFORE

NIVEL II

Antes salir de una aplicacin cliente, momentos antes del


comienzo del trmino de sesin. Puede estar en la base de
datos o a nivel de esquema.

En esta tabla se muestran los triggers para eventos de usuario:


NOMBRE
SINCRONI- DESCRIPCIN
DEL EVENTO ZACIN
LOGON
AFTER
Despus de iniciar en una sesin. Puede estar en la base de
datos o a nivel del esquema.
LOGOFF
BEFORE
Antes de salir de una sesin, momentos antes de que
comience el fin de sesin del usuario. Puede estar en la
base de datos o a nivel de esquema.
SERVEREAFTER
En respuesta a un error del servidor. Puede estar en la base
RROR
de datos o a nivel de esquema.
CREATE
BEFORE Y Siempre que se cree un nuevo objeto de la base de datos.
AFTER
Puede ser creado a nivel de esquema o para una base de
datos entera.
ALTER
BEFORE y Antes o despus de modificar un objeto de la base de
AFTER
datos. Puede ser creado a nivel de esquema o de la base
de datos.
DROP
BEFORE y Antes o despus de borrar un objeto de la base de datos.
AFTER
Puede ser creado a nivel de esquema o para una base de
datos entera.

Atributos para los eventos a nivel de la base de datos


La siguiente tabla muestra los atributos de los eventos para la aplicacin de triggers de
evento de sistema y de usuario.
ATRIBUTO
Sys.sysevent
Sys.instance_
num
Sys.database_
name
Sys.server_error
Sys.is_servererror
Sys.login_user

TIPO
VARCHAR2
(20)
NMERO

DESCRIPCIN
Evento del sistema que dispara el trigger. El nombre del
evento identifica a uno de los eventos del sistema.
Nmero de la instancia

VARCHAR2
(50)
NMERO

Nombre de la base de datos.

BOLEANO
VARCHAR2
(30)

Devuelve el nmero del error en una posicin dada respecto a la pila de errores: @@@1 tope de la pila.
Devuelve TRUE si el error est en la pila de errores; si
no, Devuelve FALSE.
Nombre del usuario de la conexin.

Atributos para los eventos a nivel de usuario.


ATRIBUTO
Sys.dictionary_
obj_Type

TIPO
VARCHAR
(20)

DESCRIPCIN
Tipo de objeto diccionario en el que se ejecut la operacin DDL

/ 73

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers


Sys.dictionary_
obj_Name
Sys.dictionary_
obj_Owner
Sys.des_encrypted_Password

VARCHAR
(30)
VARCHAR
(30)
VARCHAR (2)

NIVEL II

Nombre del objeto diccionario en el que se ejecut la


operacin DDL
Propietario del objeto diccionario en el que se ejecut
la operacin DDL
La contrasea del usuario desencriptada que se crea o
altera

16.4 LISTA DE EVENTOS


Hay dos tipos:

Eventos del sistema


Los eventos del sistema se relacionan con los eventos de mensaje de arranque y parada, y
eventos de mensajes de error del sistema.
EVENTO
STARTUP
SHUTDOWN
SERVERERROR

ATRIBUTOS
Sys.Sysevent Sys.login_user Sys.Instance_num Sys.Database_name
Sys.sysevent Sys.login_user Sys.instance_num Sys.database_name
Sys.sysevent Sys.login_user Sys.instance_num Sys.database_name
Sys.server_error Sys.is_servererror

Ejemplo:
CREATE OR REPLACE TRIGGER ON_SHUTDOWN
BEFORE SHUTDOWN
ON DATABASE
BEGIN
<Enva una alerta a la base de datos de todos los accesos de los usuarios que usan
Advanced Queuing>
END;
/

Se puede poner el mtodo en ejecucin precedente, usando el acontecimiento que publica


a todos los usuarios suscritos. Se hace esto que usa hacer cola avanzado.

Eventos de usuario
Los eventos de usuario son los eventos asociados a la conexin del usuario o de inicio y
trmino de una sesin, respuesta a un error del servidor, y a las operaciones DDL y DML.
EVENTO
LOGON
LOGOFF
BEFORE CREATE
AFTER CREATE

ATRIBUTOS
Sys.sysevent Sys.login_user
Sys.instance_num Sys.database_name
Sys.sysevent Sys.login_user
Sys.instance_num Sys.database_name
Sys.sysevent Sys.login_user Sys.instance_num
Sys.Database_name Sys.Dictionary_obj_type
Sys.Dictionary_obj_name Sys.Dictionary_obj_owner

/ 74

u.d. 1

leccin 3: Excepciones, subprogramas Pl / Sql y Triggers


BEFORE ALTER
AFTER ALTER
BEFORE DROP
ALTER DROP

NIVEL II

Sys.Sysevent Sys.Login_user Sys.Instance_num


Sys.database_name Sys.dictionary_obj_type
Sys.dictionary_obj_name Sys.dictionary_obj_owner
Sys.Sysevent Sys.Login_user Sys.Instance_num
Sys.Database_name Sys.dictionary_obj_type
Sys.Dictionary_obj_name Sys.Dictionary_obj_owner

Ejemplo:
CREATE OR REPLACE TRIGGER On_Logon
AFTER LOGON
ON SCHEMA
BEGIN
DBMS_UTILITY.ANALYZE_SCHEMA(sys.login_user, ESTIMATE);
END;
/

Se puede hacer una DDL que revise el uso de los triggers AFTER CREATE, ALTER y DROP,
de la misma manera que se revis los triggers AFTER ROW INSERT, UPDATE y DELETE.

Ejemplo: Se tiene una tabla DDL_audit


CREATE TABLE DDL_AUDIT
(object_name VARCHAR2(30) NOT NULL,
Object_type VARCHAR2(30) NOT NULL,
WHEN_CREATED DATE NOT NULL,
WHO_CREATED VARCHAR2(30) NOT NULL,
WHEN_UPDATED DATE,
WHO_UPDATED VARCHAR2(30) );

/ 75

final de leccin
Se puede crear un trigger AFTER CREATE de la siguiente manera, y rellenar la tabla siempre
que un objeto de la base de datos se cree en el esquema actual que el usuario ha registrado.
El cdigo es:
CREATE OR REPLACE TRIGGER after_ddl_creation
AFTER CREATE ON SCHEMA
BEGIN
INSERT INTO ddl_audit VALUES
(SYS.DICTIONARY_OBJ_NAME, SYS.DICTIONARY_OBJ_TYPE, SYSDATE, USER, NULL, NULL);
END;
/

Despus, se crea un procedimiento simulado para probar la ejecucin automtica de este


trigger. El cdigo del procedimiento es:
CREATE OR REPLACE PROCEDURE p_dummy
IS
BEGIN
NULL;
END;
/

Para probar los resultados, se consulta la tabla ddl_audit:


SELECT * FROM ddl_audit;

La salida es:

SQL> SELECT * FROM ddl_audit;


OBJECT_NAME OBJECT_TYPE WHEN_CREA WHO_CREATED WHEN_UPDA
--------------------------------------------------------------------------------------------------------------P_DUMMY
PROCEDURE
21-APR-02
WHO_UPDATED
------------------------

FINAL DE LA LECCIN 3
Notas de trabajo del alumno:

Conclusiones:

/ 76

PLSQL 9i/ u.d. 1 / ejercicios de repaso

NIVEL II

ENUNCIADOS EJERCICIOS DE REPASO.


Tabla CENTROS:
Numero

Number(5)

Nmero identificativo del centro

Nombre

varChar(50)

Nombre del centro

Direccion

varChar(50)

Direccin del local

Tabla DEPARTAMENTOS:
Numero

Number(5)

Nmero identificativo del departamento

Centro

Number(5)

Nmero centro de trabajo donde est el departamento

Todo departamento est en un centro de trabajo, que es un edificio o local, que puede
albergar ms de un departamento.
Director

Number(5)

Nmero empleado que es director del departamento.

Todo departamento tiene un solo director. Puede ser un director en propiedad o en funciones.
Un empleado slo puede ser director en propiedad de un nico departamento, pero puede
ser director provisional en funciones de varios.
Tipo_dir

Char(1)

Tipo de director: P, en propiedad y F, en funciones.

Presuesto

Integer

Presupuesto anual departamento, en miles de euros.

Depto_jefe

Number(5)

Nmero del departamento del que depende.

Todo departamento depende de otro, excepto el de ms alto nivel, que no depende de


ninguno.
Un departamento puede tener varios, dependiendo de l. Esta dependencia expresa la
jerarqua de mando. Admite un valor nulo.

Nombre

varChar(50)

Nombre del departamento.

Tabla EMPLEADOS:
Cod

Number(5)

Nmero identificativo del empleado

Departamento

Number(5)

Nmero departamento asignado al empleado

Telefono

Number(4)

Extensin telefnica del empleado

Fecha_nacimiento Date

Fecha de nacimiento

Fecha_ingreso

Date

Fecha de ingreso en la empresa

Salario

Integer

Salario mensual en euros

Comision

Integer

Comisin mensual en euros.

Slo es aplicable a los empleados que son vendedores o directores de vendedores, incluyendo hasta el director comercial. En el resto de empleados toma el valor nulo.
Son vendedores los que pertenecen al departamento de Direccin Comercial.
Num_hijos

Number(2)

Nmero de hijos

Nombre

varChar(50)

Nombre del empleado


/77

PLSQL 9i/ u.d. 1 / ejercicios de repaso


Direccion

varChar(50)

NIVEL II

Direccin del empleado

Utilizando esta estructura de la BD EMPRESA


1. Programar un Procedimiento para calcular:

A. Salario medio de aquellos n empleados que tienen menor sueldo, siendo n el primer
argumento.

B. Porcentaje que suponen estos n empleados respecto al total de empleados de la


base de datos.

2. Programar una Funcin que tenga como argumento el DNI de un Empleado.


La funcin devolver:

La diferencia entre su Salario y el Salario ms grande de entre todos los empleados


de su departamento.

La funcin devolver -1, si no existe ese empleado

3. Procedimiento para cambiar de Dpto. a un empleado, dando su DNI y su Dpto.


de destino. Si en el nuevo Dpto. hay ms de 20 empleados o no existe dicho
empleado, generar sendos errores.
4. Cree una vista llamada INF_GENERAL que contiene el nmero total de empleados, el de departamentos, el de centros, el nmero de jefes, la fecha en que se
incorpor el primer empleado a la empresa y la fecha del ltimo que lo ha hecho
y el total de lo gastado por la empresa en el pago de comisiones.
Ahora cree una tabla INF_GRAL_FISICA que sirva para almacenar estos datos. Cree un
bloque PL/SQL que realice una consulta a la base de datos para cada uno de estos atributos
y vaya almacenando los valores en variables para, finalmente hacer una insercin de todos
los datos en la tabla.

5. Cree una vista llamada INF_EMPLEADOS, que contiene la informacin del


nombre de cada empleado, su fecha de nacimiento y el cdigo de su departamento.
Haga lo mismo, creando fsicamente una tabla, llamada INF_EMP_FISICA, y volcando la
informacin mediante la sentencia INSERT INTO SELECT ;
Compruebe que la informacin de la tabla y la vista es la misma, usando el operador
MINUS.
Por ltimo, borre todas las tuplas que hay en INF_EMP_FISICA, y disee un bloque PL/SQL
que realice la misma funcin que el INSERT anterior, pero usando un cursor de lectura que
lee sobre la tabla empleados. Vuelva a comprobar que existe la misma informacin en la
tabla y en la vista.

6. Se quiere obtener el valor de los cdigos de departamentos que tienen el mayor


nmero de empleados. Esto se puede realizar con la siguiente consulta SQL:
SELECT DISTINCT Departamento

/78

PLSQL 9i/ u.d. 1 / ejercicios de repaso

NIVEL II

FROM Empleados
GROUP BY Departamento
HAVING COUNT(*) >= ALL (SELECT COUNT(*)
FROM Empleados
GROUP BY Departamento);

Dicha consulta tiene un coste bastante elevado y, por ello, se propone realizarla de dos
formas distintas, creando dos bloques PL/SQL, que cubren los siguientes razonamientos:
A. Creando una tabla: Crear una tabla llamada INFO_DPTOS, que contenga los valores de
cdigo de los departamentos y nmero de empleados en cada uno (sacar estos datos de
la tabla de empleados). A continuacin, se puede obtener el valor mximo de nmero de
empleados (consultando la tabla INFO_DPTOS), y recorrer la misma tabla para encontrar
qu departamentos coinciden con ese valor de nmero de empleados.
B. Sin crear ninguna tabla: Se pueden anidar dos cursores. El primero recorre la tabla
EMPLEADOS agrupada por el valor de departamento, y busca los valores de nmero de
empleados (N_EMP) y cdigo del departamento (COD_DPTO). A continuacin, se abre un
segundo cursor, que busca una tupla en EMPLEADOS agrupada por departamento, que
tenga un valor mayor de nmero de empleados que el que est en N_EMP. Si este cursor tiene
alguna tupla, entonces el departamento COD_DPTO no tiene el valor mximo de nmero
de empleados, por lo que se rechaza y seguimos buscando (se hace un nuevo FETCH del
primer cursor). En caso contrario, se selecciona ese departamento y seguimos buscando.
Realizar las dos opciones anteriores.

7. Crear un procedimiento que, mediante cursores, recorra la tabla Empleados


y busque el salario de cada empleado; si el salario es menor de 100, actualizarlo
con un 20% ms.

/79

PLSQL 9i/ u.d. 1 / soluciones

NIVEL II

SOLUCIONES EJERCICIOS DE REPASO.


Solucin 1:
Se declara el Procedimiento SalarioMedio, que extrae de la tabla EMPLEADOS los n primeros
registros, ordenados de menor a mayor salario, calcula la media y el porcentaje:
PROCEDURE SalarioMedio (n IN NUMBER (3), salario_med OUT NUMBER (7),
porcentaje OUT NUMBER (3)) IS
V_cont BINARY_INTEGER
/*Se declara un cursor que coja los registros de EMPLEADOS, ordenados de forma
ascendente por el Salario */
CURSOR cur1 IS SELECT * FROM EMPLEADOS ORDER BY Salario ASC
V_cur1 cur1;
salarioTotal NUMBER (7);
num_emp NUMBER (5);
BEGIN
V_cont := 1;
salarioTotal := 0;
OPEN cur1; -- Se abre el cursor
/*Se recorre el cursor con un bucle, que acaba cuando el contador vale n
Se cogen los n primeros registros del cursor (los que tienen menor salario) */
LOOP
FETCH cur1 INTO v_cur1
EXIT WHEN v_cont = n;
salarioTotal := salarioTotal + v_cur1.Salario
v_cont := v_cont + 1;
END LOOP;
CLOSE cur1;
salarioMed := salarioTotal / n;
-- Se calcula el salario medio
--Se coge el nmero total de empleados, que es el nm. de filas obtenidas
num_emp := cur1%ROWCOUNT;
porcentaje := n * 100 / num_emp
-- Se calcula el porcentaje
END SalarioMedio;

En el programa principal se solicita la entrada de un nmero, y se ejecuta el procedimiento


anterior:
ACCEPT N PROMPT Introduce un nmero : ;
DECLARE --Se declaran las variables necesarias
v_n NUMER (3) := &N;
salario_med NUMBER (7);
porcentaje NUMBER (3);
BEGIN
SalarioMedio (v_n, salario_med, porcentaje); -- Se llama al procedimiento
-- Se muestra por pantalla los resultados
DBMS_OUTPUT.PUTLINE (El salario medio de los || v_n || primeros empleados es
|| salario_med);
DBMS_OUTPUT.PUTLINE (El porcentaje es || porcentaje);
END

Solucin 2:
Declaramos la funcin DiferenciaSalario, que ordena los registros de la tabla de mayor a
menor salario, por lo que el primer registro ser el que tenga el mayor salario:
FUNCTION DiferenciaSalario (DNI IN NUMBER (8)) RETURN NUMBER (5) IS
Diferencia NUMBER (5);
/*El primer cursor extrae el registro con cdigo de empleado igual al DNI que se
introduce */
CURSOR cur_emp IS SELECT * FROM EMPLEADOS WHERE EMPLEADOS.Cod = DNI;

/80

PLSQL 9i/ u.d. 1 / soluciones

NIVEL II

/*El segundo cursor extrae los registros con el mismo cdigo de departamento que el del
empleado anterior, ordenados de forma descendente por el Salario, de forma que el primer
registro tendr el salario mayor */
CURSOR cur1 IS SELECT * FROM EMPLEADOS EMP ORDER BY Salario DESC
WHERE
EMP.Departamento = cur_emp.Departamento;
V_cur1 cur1;
V_emp cur_emp;
BEGIN
OPEN cur_emp;
FETCH cur_emp INTO v_emp; --Se coge el registro del empleado
IF cur_emp%NOTFOUND THEN --No se ha encontrado el empleado
RETURN -1
ELSE
OPEN cur1;
FETCH cur1 INTO v_cur1; --Se cogen el registro del departamento
/* Se coge la primera fila, que es la que tiene el mayor salario */
diferencia := v_cur1.Salario v_emp.Salario
RETURN diferencia;
END DiferenciaSalario;

Solucin 3:
Se declara el procedimiento CambiarDepto:
PROCEDURE CambiarDepto (DNI IN NUMBER (8),deptoDestino IN NUMBER(5))
IS
v_cont BINARY_INTEGER
/*Se declara un cursor FOR UPDATE que coja el empleado con Cdigo igual al DNI
introducido*/
CURSOR cur_emp IS SELECT * FROM EMPLEADOS WHERE EMPLEADOS.Cod = DNI FOR UPDATE OF
Departamento;
/*Se declara otro cursor que coja los registros de todos los empleados del departamento
destino*/
CURSOR cur_dep IS SELECT * FROM EMPLEADOS WHERE EMPLEADOS.Departamento =
deptoDestino;
V_emp cur_emp;
V_dep cur_dep;
BEGIN
OPEN cur_emp; -- Se abre el cursor del empleado
FETCH cur_emp INTO v_emp;
IF cur_emp%NOTFOUND THEN --No se ha encontrado el empleado
DBMS_OUTPUT.PUTLINE (ERROR: No se ha encontrado el empleado);
ELSE
OPEN
cur_dep; --Se abre el cursor del departamento
FETCH cur_dep INTO v_dep;
IF cur_dep%FOUND THEN
IF cur_dep%ROWCOUNT > 20 THEN
/*hay ms de 20 empleados en ese departamento */
DBMS_OUTPUT.PUTLINE (ERROR: Este departamento tiene ms
de 20 empleados);
ELSE
--Se cambia el cdigo del empleado con un UPDATE
UPDATE EMPLEADOS SET Departamento = deptoDestino WHERE Cod = DNI;
END IF;

/81

NIVEL II

PLSQL 9i/ u.d. 1 / soluciones


END IF;
END CambiarDepto;

Solucin 4:
CREATE VIEW INF_GENERAL AS SELECT COUNT (E.Cod), COUNT (D.Numero), COUNT
(C.Numero), count(D.director), (Con esto tendras el numero total de jefes)
MIN (E.Fecha_ingreso), MAX (E.Fecha_ingreso), SUM (E.Comision)
FROM (centros INNER JOIN departamentos ON centros.numero=departamentos.numero)
INNER JOIN empleados ON departamentos.numero=empleados.departamento;

Ahora, cree una tabla INF_GRAL_FISICA que sirva para almacenar estos datos.
CREATE TABLE INF_GRAL_FISICA (
Num_emp
NUMBER(3),
Num_dep
NUMBER(3),
Num_centros
NUMBER(3),
Num_jefes
NUMBER(3),
Fecha_primero DATE,
Fecha_ultimo
DATE,
Comisiones
INTEGER)

Cree un bloque PL/SQL que realice una consulta a la base de datos para cada uno de estos
atributos y vaya almacenando los valores en variables para, finalmente hacer una insercin
de todos los datos en la tabla.
DECLARE
V_num_emp
V_num_dep
V_num_centros
V_num_jefes
V_fecha_prim
V_fecha_ult
V_comisiones

NUMBER (3);
NUMBER(3);
NUMBER(3);
NUMBER(3);
DATE;
DATE;
INTEGER;

BEGIN
--Se obtienen los valores de las tablas
SELECT *
INTO V_num_emp, V_num_dep, V_num_centros, V_num_jefes,
fecha_ult,
V_comisiones
FROM INF_GENERAL

V_fecha_prim, V_

No hace falta hacer la consulta de la tabla porque esa informacin ya la tenemos en la vista
INF_GENERAL

--Se insertan los valores obtenidos en la nueva tabla


Si se insertan los valores en el orden en el que estn definidos en la tabla, no hace falta
poner los nombres de los campos, pero si no se hace as se tienen que poner los nombres
de los campos.
INSERT INTO INF_GRAL_FISICA (Num_emp,Num_dep,
Num_centros,
Num_jefes, Fecha_
primero,
Fecha_ultimo,
Comisiones) VALUES (V_num_emp, V_num_dep, V_num_centros, V_num_jefes, V_fecha_
prim, V_fecha_ult, V_comisiones)
END

/82

NIVEL II

PLSQL 9i/ u.d. 1 / soluciones


Solucin 5:

CREATE OR REPLACE VIEW INF_EMPLEADOS (nombre_empleados, fecha_nac_empleados,


departamento_empleados) AS SELECT NOMBRE, FECHA_NACIMIENTO, DEPARTAMENTO
FROM EMPLEADOS;
Vista creada.
SELECT * FROM INF_EMPLEADOS;
NOMBRE
-------------------------------------------------EMPLEADO1
EMPLEADO2
EMPLEADO3
EMPLEADO4
EMPLEADO5
EMPLEADO6

FECHA_NA DEPARTAMENTO
-------- -----------02/12/65
21
02/12/70
22
02/02/70
23
02/01/71
23
02/02/70
22
02/02/70
21

6 filas seleccionadas
Se prescinde en la creacin de la tabla de los parmetros de almacenamiento STORAGE
(INITIAL, NEXT, PCTINCREASE) y del tablespace de destino.
CREATE TABLE INF_EMP_FSICA
(
NOMBRE
VARCHAR(50),
FECHA_NACIMIENTO
DATE,
DEPARTAMENTO
NUMBER(5)
);
Tabla creada.

Solucin 6:
A. Se prescinde en la creacin de la tabla de los parmetros de almacenamiento STORAGE
(INITIAL, NEXT, PCTINCREASE) y del tablespace de destino.
CREATE TABLE INFO_DPTOS
(
N_EMP
NUMBER(5),
COD_DPTO
NUMBER(5)
);
Tabla creada.
INSERT INTO INFO_DPTOS (COD_DPTO, N_EMP) SELECT DISTINCT DEPARTAMENTO, COUNT(DISTINCT
COD) FROM EMPLEADOS GROUP BY DEPARTAMENTO;

3 filas creadas.
COMMIT;
Validacin terminada.
DECLARE
MAX_EMPLE := SELECT MAX(N_EMP) FROM INFO_DPTOS;
BEGIN
SELECT COD_DPTO DEPARTAMENTO FROM INFO_DPTOS WHERE N_EMP = MAX_EMPLE;
END;
/
DEPARTAMENTO
-------------------------21
22
23

/83

PLSQL 9i/ u.d. 1 / soluciones

NIVEL II

B. DECLARE
CURSOR CURS1 IS
SELECT DEPARTAMENTO COD_DEPTO, COUNT(*) NUM_EMPLEADOS
FROM EMPLEADOS
GROUP DEPARTAMENTO;
CURSOR CURS2(valor_num_empl NUMBER) IS
SELECT DEPARTAMENTO FROM EMPLEADOS
GROUP BY DEPARTAMENTO
HAVING COUNT(*) > valor_num_empl;
v_reg CURS1%ROWTYPE;
v_reg_aux CURS2%ROWTYPE;
BEGIN
FOR v_reg IN CURS1
LOOP
OPEN CURS2(v_reg.NUM_EMPLEADOS);
FETCH CURS2 INTO v_reg_aux;
IF CURS2%NOTFOUND
THEN
/* SELECCIONAMOS EL REGISTRO (ESCRIBIENDOLO POR PANTALLA) Y
SEGUIMOS BUSCANDO CONTINUANDO CON EL LOOP*/
DBMS_OUTPUT.PUT_LINE(Codigo de departamento: || v_reg.COD_
DEPTO);
END IF;
/* SI HAY ALGN REGISTRO ENCONTRADO EN EL CURSOR NO HACEMOS NADA,
SE RECHAZA EL REGISTRO v_reg Y SE HACE UN NUEVO FETCH CONTINUANDO CON EL LOOP*/
CLOSE CURS2;
END LOOP;
END;
Codigo de departamento: 21
Codigo de departamento: 22
Codigo de departamento: 23

Solucin 7:
DECLARE
CURSOR busqueda salario IS
SELECT codigo empleado, salario FROM EMPLEADOS
FOR UPDATE OF salario;
codigo empleados.codigo empleado%TYPE;
salario empleados.salario empleado%TYPE;
BEGIN
OPEN busqueda salario;
LOOP
FETCH busqueda salario INTO codigo, salario;
EXIT WHEN busqueda salario%NOTFOUND;
IF salario < 100 THEN
UPDATE empleados SET salario=salario*0,2 ;
WHERE CURRENT OF busqueda salario ;
END IF;
END LOOP;
CLOSE busqueda salario ;
COMMIT;
END;

/84

glosario general de trminos

GLOSARIO
3GL. LENGUAJES DE TERCERA GENERACIN.
Lenguaje que se dise para que fuera ms fcil de entender incluyendo cosas como el
nombre a las variables. Por ejemplo, FORTRAN y COBOL.

4GL. LENGUAJES DE CUARTA GENERACIN


Este trmino se invent para referirse a lenguajes de alto nivel de proceso, construidos
sobre bases de datos. Las primeras tres generaciones fueron desarrolladas bastante rpidamente, pero eran lentas y con muchos errores, conduciendo a una crisis, primero de
programacin, en la cual la cantidad de trabajo asignada a los programadores exceda
mucho de la cantidad de tiempo que el programador dispona para hacerla.

ANSI
American National Standards Institute

API
Application Program Interface.
Application Program Interface (API)
Un sistema de interfaces programados pblicos, que consisten en un formato del lenguaje
y del mensaje para comunicarse con el sistema operativo o en otro entorno programtico,
tal como bases de datos, servidores Web, JVMs, y as sucesivamente. Estos mensajes llaman
las funciones y los mtodos disponibles para el desarrollo de la aplicacin.
Servidor de la aplicacin
Un servidor dise recibir usos y sus ambientes, permitiendo que los usos del servidor
funcionen. Un ejemplo tpico es OAS, que puede recibir los usos de Java, de C, de C++, y
del PL/del SQL, en caso de que un cliente del telecontrol controle el interfaz. Vea tambin
el servidor de la aplicacin del Oracle.

AT
Autonomous Transaction

Atributo
Una propiedad de un elemento, que consiste en un nombre y un valor separados por un
igual, y contenidos dentro de las etiquetas del comienzo despus del nombre del elemento.
En este ejemplo, el <Price units=USD>5</Price>, unidades es el atributo y los USD son su
valor, que debe estar en cotizaciones simples o dobles. Los atributos pueden residir en el
documento o en el DTD. Los elementos pueden tener muchos atributos, pero su orden de
recuperacin no se define.

BFILES
Archivos binarios externos, que existen fuera de los tablespaces de la base de datos que

/85

glosario general de trminos


residen en el sistema operativo. BFILES se refieren de la semntica de la base de datos, y
tambin se conocen como pelotas altas externas.

Binary Large Object (BLOB)


Un datatype grande del objeto contenido, que consiste en datos binarios. Adems, estos
datos se consideran crudos, pues su estructura no es reconocida por la base de datos.

Callback
Una tcnica programtica, en la cual un proceso comienza otro y entonces contina. El
segundo proceso llama al primero como resultado de la accin, del valor, o del otro acontecimiento. Esta tcnica se utiliza en la mayora de los programas que tengan una interfaz
utilitaria, para permitir la interaccin continua.

Cartridge
Un programa almacenado en Java o en PL/SQL, que agrega la funcionalidad necesaria para
que la base de datos entienda y manipule un nuevo datatype.

CDATA
Vea los datos de carcter.

CGI
Vea Common Gateway Interface

CSS Cascading Style Sheets.


Hojas de conexin en cascada del estilo.

CDATA Datos de carcter


El texto en un documento que no deba ser analizado se pone dentro de una seccin de
CDATA. Esto permite la inclusin de los caracteres, tales como los que tendra de otra
manera funciones especiales, y, <, >, las secciones del etc. CDATA se pueden utilizar en el
contenido de un elemento o en atributos.

Common Gateway Interface (cgi)


Las siglas genricas para la programacin interconectan permitir a los servidores del Web
ejecutar otros programas, y pasar su salida a las pginas, a los grficos, al audio, y al vdeo
del HTML enviado a los browsers.

CLASSPATH
La variable ambiental del sistema operativo que el JVM utiliza para encontrar las clases que
necesita para ejecutar aplicaciones.

/86

glosario general de trminos


Client Server
El trmino describe la arquitectura de la aplicacin donde la aplicacin real funciona en el
cliente, pero los datos de los accesos u otros procesos externos en un servidor a travs de
una red.

Character Large Object (CLOB)


El datatype LOB, cuyo valor se compone de los datos de carcter que corresponden al juego
de caracteres de la base de datos. Un CLOB se puede poner en un ndice y buscar por el
Search Engine del texto.

CLOB
Vea el objeto grande del carcter.

Common Oracle Runtime Environment (CORE)


La biblioteca de las funciones escritas en C, que proporciona a los desarrolladores la capacidad de crear el cdigo que se puede girar fcilmente, virtualmente, cualquier plataforma
y sistema operativo.

Conectividad de la base de datos de Java (JDBC)


El API de programacin, que permite a los usos de Java tener acceso a una base de datos con
el lenguaje del SQL. Los conductores de JDBC se escriben en Java para la independencia
de la plataforma, pero son especficos a cada base de datos.

Database Access Descriptor (DAD)


Un DAD es un sistema nombrado de valores de la configuracin, usados para el acceso de
base de datos. Un DAD especifica la informacin, tal como el nombre o el SQL * nombre
neto del servicio V2, el directorio de ORACLE_HOME e informacin de la configuracin de
la base de datos del NLS, tal como lengua, tipo de la clase, y lenguaje de la fecha.

Datagrama
Un fragmento de texto, que puede estar en el formato XML, que se devuelve al solicitante
en una pgina HTML de una query de SQL, procesada por el XSQL Servlet.

DOCTYPE
El trmino usado como el nombre de la etiqueta que seala el DTD o su referencia dentro
de un documento de XML.

Document Type Definition (DTD)


Un sistema de reglas, que definen la estructura permisible de un documento XML. DTDs
son los archivos de texto que derivan su formato del SGML, y se pueden incluir en un

/87

glosario general de trminos


documento de XML, usando el elemento de DOCTYPE o usando un archivo externo con
una referencia de DOCTYPE.

DCL
Data Control Language

DDL
Data Definition Language

DML
Data Manipulation Language

EDI
Intercambio de los datos electrnicos.

Elemento
La unidad lgica bsica de un documento de XML que puede servir como un envase para
otros elementos como hijos, datos, atributos, y sus valores. Los elementos son identificados
por las etiquetas de comienzo el <name> y el extremo-tags</el name> o en el caso de los
elementos vacos, <name/>.

Extensible Markup Language (XML)


Un estndar abierto para describir datos se convirti por el W3 C, usando un subconjunto
de sintaxis del SGML y dise para la aplicacin del Internet. La versin 1.0 es el estndar
actual, siendo publicado como recomendacin del W3 C en febrero de 1998.

Entorno Runtime de Java (JRE)


La coleccin de clases conformadas que componen la mquina virtual de Java en una plataforma. JREs es sealado por versiones, y Java 2 se utiliza para sealar versiones del 1.2
hacia adelante.

Framework
Entorno de trabajo

Generador de la clase
Una utilidad que acepta un fichero de entrada y crea un sistema de las clases de salida
que tienen funcionalidad correspondiente. En el caso del generador de la clase de XML, el
fichero de entrada es un DTD, y la salida es una serie de clases que se puedan utilizar para
crear los documentos de XML que se conforman con el DTD.

/88

glosario general de trminos


HTML
Vea el lenguaje del margen de beneficio del hypertext.

HTTP
Vea el protocolo del transporte del hypertext.

Hypertext
El mtodo de crear y de publicar los documentos del texto en los cuales los usuarios pueden
navegar entre otros documentos o grficos, seleccionando las palabras o las frases sealadas como hyperlinks.

Hypertext Markup Language (HTML)


El lenguaje de marcas creaba los archivos enviados a los browsers del Web, y esos servicios
como la base del World Wide Web. La versin siguiente del HTML ser llamada xHTML, y
ser un uso de XML.

Hypertext Transport Protocol (HTTP)


El protocolo usado para transportar el HTML archivos a travs de Internet entre los servidores del Web y los browsers.

IDE Integrated Development Environment - Entorno integrado del desarrollo


Un sistema de programas diseado para ayudar en el desarrollo del software, funcionando
con un solo interfaz de desarrollo. JDeveloper es un IDE para el desarrollo de Java, como
incluye a redactor, recopilador, depuracin, inspector del sintaxis, sistema de ayuda, y as
sucesivamente, para permitir el desarrollo del software de Java a travs de un solo interfaz
utilizador.

Instancia
Un trmino usado en lenguajes, basado en objetos como Java y C++ para referir a la creacin de un objeto de una clase especfica.

ISO
International Organization for Standardization

Java Server Page (JSP)


Una extensin de la funcionalidad del servlet, que permite un interfaz programtico simple
para las pginas Web. JSPs son pginas HTML con las etiquetas especiales y el cdigo
encajado de Java, que se ejecuta en el Web o el servidor de la aplicacin, que proporciona
funcionalidad dinmica a las pginas del HTML. JSPs se compila realmente en servlets
cuando, primero, est solicitado y se ejecuta en JVM del servidor.

/89

glosario general de trminos


Java Virtual Machine (JVM)
El intrprete de Java que convierte el bytecode compilado de Java en el lenguaje de mquina
de la plataforma y lo funciona. JVMs puede funcionar en un cliente, en un browser, en una
grada media, en un Web, en un servidor de la aplicacin tal como OAS, o en un servidor de
la base de datos tal como Oracle9iAS.

MR
Modelo Relacional

MT
Main Transaction

Namespace
El trmino para describir un sistema de nombres o de cualidades relacionados del elemento
dentro de un documento de XML. La sintaxis del namespace y su uso es definido por una
recomendacin del W3 C. Por ejemplo, el <xsl:las aplicar-plantillas/> elemento se identifican
como parte del namespace de XSL. Namespaces se declara en el documento de XML o el
DTD antes de que se est utilizando el sintaxis siguiente de la cualidad:- los xmlns:xsl=
http://www.w3.org/TR/WD-xsl .

N-Tier
La designacin para una arquitectura de red de comunicaciones de la mquina, que consiste
en una o ms capas compuestas de clientes y de servidores. Los sistemas tpicamente de
dos niveles se componen de un nivel del cliente y de un nivel del servidor. Un sistema de
la tres capas utiliza dos capas del servidor; normalmente, un servidor de la base de datos y
un Web o un servidor de la aplicacin, junto con una capa del cliente.

OAG
Open Applications Group.

OAS
Oracle Application Server

OASIS
Organization for the Advancement of Structured Information.

Object View
Una presentacin adaptada de los datos contenidos en una o ms tablas del objeto u otras
vistas. La salida de una query se trata como tabla. Las vistas del objeto se pueden utilizar
en la mayora de los lugares en donde se utiliza una tabla.

/90

glosario general de trminos


Object-relacional
El trmino para describir un sistema de la base de datos relacionada que puede tambin
almacenar y manipular tipos de datos higher-order, tales como documentos del texto, audio,
archivos vdeo, y objetos definidos por el usuario.

OE
Oracle Exnchage

Oracle Application Server (OAS)


El servidor de Oracle que integra todos los servicios de la base y las caractersticas que se
requirieron para el edificio, desplegando, y manejando de alto rendimiento, n-grada, usos
orientados a transacciones del Web, dentro de un marco abierto de los estndares.

ORACLE_HOME
La variable ambiental del sistema operativo que identifica la localizacin de la instalacin
de la base de datos del Oracle para uso de las aplicaciones.

PL/SQL
El lenguaje procesal de la base de datos del Oracle, que ampla el SQL para crear los programas que se pueden funcionar dentro de la base de datos.

Sistema del resultado


La salida de una consulta SQL que consiste en unas o ms filas de datos.

SAX Simple API for XML.


Un interfaz estndar de XML, proporcionado por programas de anlisis de XML y usado
por usos acontecimiento-basados.

Schema
La definicin de los tipos de la estructura y de datos dentro de una base de datos. Puede
tambin ser utilizada para referir a un documento de XML, que apoya la recomendacin
del W3 C del esquema de XML.

Servlet
Una aplicacin de Java que funciona en un servidor; normalmente, un Web o un servidor
de la aplicacin, y realiza el proceso en ese servidor. Servlets a Java, equivalente a las
escrituras del cgi.

/91

glosario general de trminos


session
La conexin activa entre dos capas.

SGBD
Sistema de Gestin de Bases de Datos.

SGBDR
Sistema de Gestin de Bases de Datos Relacionales.

Structured Generalized Markup Language (SGML).


Un estndar de ISO para definir el formato de un documento del texto puesto en ejecucin
con margen de beneficio y DTDs.

Structured Query Language (SQL)


El lenguaje de estndar para tener acceso y procesar los datos en una base de datos relacional.

Server-side Include (SSI)


El comando del HTML pone los datos u otro contenido en una pgina Web antes de enviarlo
al browser de peticin.

Secure Sockets Layer (el SSL)


El protocolo primario de la seguridad en el Internet, que utiliza una llave pblica/una forma
dominante privada de cifrado entre los browsers y los servidores.

Tag etiqueta
Una pieza nica de XML que delimita el comienzo o el extremo de un elemento. Las etiquetas comienzan con < y terminan con >. En XML, hay que empezar-etiquetas (<name>),
extremo-etiquetas (</name>), y etiquetas vacas (<name/>).

TCP/IP Transmission Control Protocol/Internet Protocol


El protocolo de la red de comunicaciones que consiste en el TCP que controla las funciones
del transporte, y el IP que proporciona el mecanismo del routing. Es el estndar para las
comunicaciones del Internet.

W3 C
World Wide Web (W3 C).

/92

glosario general de trminos


WAN
Wide Area Network.

Wrapper
El trmino que describe una estructura o un software de datos que se envuelven alrededor
de los otros datos o software, para proporcionar un interfaz genrico del objeto.

Web server
Un proceso del servidor (demonio del HTTP) que funciona en un Web site, que enva pginas
Web en respuesta a peticiones HTTP de los browsers.

/93

Garben Proyectos: C/ General Pardias 112 bis 1 A. Madrid.


Garben Formacin: C/ Claudio Coello 124. Madrid.

You might also like