Manual Plsql

Post on 04-Jul-2015

2.874 views 10 download

Tags:

Transcript of Manual Plsql

09/03/2005

GEDICA TRAINING & CONSULTING C.A.

I�TRODUCCIÓ� A PL/SQL

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 1

TABLA DE CONTENIDO

I�TRODUCCIO� A PL/SQL ...................................................................................................4 OBJETIVOS DEL CURSO: .............................................................................................................................. 4 CONTENIDO PROGRAMÁTICO: .................................................................................................................. 4 ESTRATEGIAS METODOLÓGICAS:............................................................................................................. 5 RECURSOS AUDIOVISUALES Y EVALUACIÓN: ...................................................................................... 5 REQUISITOS DE ADMISIÓN: ........................................................................................................................ 5

Capítulo 1....................................................................................................................................6

I�TRODUCCIO� A PL/SQL ....................................................................................................6

I�TRODUCCIÓ� A PL/SQL............................................................................................................ 7

ESTRUCTURA DE LOS BLOQUES DE PL/SQL.......................................................................... 8

TIPOS DE BLOQUE .......................................................................................................................... 9 Bloques Anónimos........................................................................................................................................... 10 Subprogramas................................................................................................................................................... 10 SINTAXIS DE BLOQUES PL/SQL................................................................................................................ 11

TIPOS DE DATOS E� PL/SQL...................................................................................................... 15

VARIABLES E� PL/SQL................................................................................................................ 16 TIPOS DE VARIABLE EN PL/SQL............................................................................................................... 16

DECLARACIO� DE VARIABLES E� PL/SQL .......................................................................... 20

VARIABLES TIPO ATRIBUTO E� PL/SQL............................................................................... 23 Variables tipo RECORD.................................................................................................................................. 23 Variables tipo TABLE ..................................................................................................................................... 24

ASIG�A�DO VALORES A VARIABLES .................................................................................... 26

BLOQUES I�TER�OS Y ALCA�CE DE VARIABLES ............................................................ 28 Alcance ............................................................................................................................................................ 29

OPERADORES ................................................................................................................................. 29 OPERADORES NUMERICOS ....................................................................................................................... 29 OPERADORES LOGICOS O BOOLEANOS ................................................................................................ 29 PRACTICA 1................................................................................................................................................... 31

Capítulo 2..................................................................................................................................32

FU�CIO�ES E� PL/SQL......................................................................................................32

FU�CIO�ES E� PL/SQL................................................................................................................ 33

I�TERACTUA�DO CO� EL ORACLE SERVER...................................................................... 33 COMPARACION DE INSTRUCCIONES SQL y PL/SQL............................................................................ 34 RECUPERANDO DATOS – La cláusula SELECT ........................................................................................ 34 INSERTANDO DATOS – La cláusula INSERT............................................................................................. 36 ACTUALIZANDO DATOS – La cláusula UPDATE ..................................................................................... 36 BORRANDO DATOS – La cláusula DELETE............................................................................................... 37

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 2

CONTROL DE TRANSACCIONES............................................................................................................... 37 PRACTICA 2................................................................................................................................................... 40

Capítulo 3..................................................................................................................................41

ESTRUCTURAS DE CO�TROL ............................................................................................41

ESTRUCTURAS DE CO�TROL DE PL/SQL.............................................................................. 42 CONDICIONALES ......................................................................................................................................... 42 La sentencia IF ................................................................................................................................................. 43 ITERACIONES ............................................................................................................................................... 45 ETIQUETAS.................................................................................................................................................... 49

CURSORES ....................................................................................................................................... 51 CURSORES en SQL........................................................................................................................................ 51 CURSORES EN PL/SQL ................................................................................................................................ 53 PRACTICA 3................................................................................................................................................... 62

Capítulo 4..................................................................................................................................63

MA�EJO DE ERRORES ........................................................................................................63

MA�EJO DE ERRORES E� PL/SQL........................................................................................... 64 EXCEPCIONES PREDEFINIDAS ................................................................................................................. 64 MANEJANDO EXCEPCIONES..................................................................................................................... 65 EL PRAGMA EXCEPTION_INIT.................................................................................................................. 66 EXCEPCIONES DEFINIDAS POR EL USUARIO ....................................................................................... 67 PRACTICA 4................................................................................................................................................... 70

Capítulo 5..................................................................................................................................71

PROGRAMAS ALMACE�ADOS E� LA BASE DE DATOS...............................................71

I�GE�IERIA DEL LE�GUAJE PL/SQL ..................................................................................... 72 INGENIERIA DE PL/SQL.............................................................................................................................. 72

I�GE�IERIA DE PL/SQL RESIDE�TE E� EL RDBMS .......................................................... 73 DIFERENCIA ENTRE PROCEDIMIENTO Y FUNCION ............................................................................ 74 CARACTERISTICAS DE PROCEDIMIENTOS Y FUNCIONES ................................................................ 74 USOS DE PROCEDIMIENTOS Y FUNCIONES .......................................................................................... 75 CREACION Y COMPILACION DE PROCEDIMIENTOS Y FUNCIONES................................................ 75 Instrucciones Válidas en Procedimientos y Funciones .................................................................................... 77 Instrucciones No Validas en Procedimientos y Funciones............................................................................... 78 EJECUCION DE PROCEDIMIENTOS Y FUNCIONES ALMACENADOS ............................................... 78

COMPILACIO� DE ERRORES E� PL/SQL............................................................................... 80 ERRORES DE PL/SQL ................................................................................................................................... 80 ERRORES DEFINIDOS POR EL USUARIO ................................................................................................ 81 ELIMINACION DE PROCEDIMIENTOS Y FUNCIONES.......................................................................... 82

PAQUETES ....................................................................................................................................... 83 ESTADO PERSISTENTE ............................................................................................................................... 83 ESTRUCTURA DE UN PAQUETE ............................................................................................................... 84 DEPENDENCIAS ENTRE PAQUETES ........................................................................................................ 84 ESPECIFICACIONES PARA LA CREACION DE PAQUETES .................................................................. 85 PRACTICA 5................................................................................................................................................... 88

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 3

Capítulo 6..................................................................................................................................89

TRIGGERS DE BASE DE DATOS.........................................................................................89

TRIGGERS o DISPARADORES DE EVE�TOS.......................................................................... 90 RESTRICCIONES DE LOS TRIGGERS........................................................................................................ 92 DEFINICION Y CREACION DE TRIGGERS............................................................................................... 93 CREACION DE UN TRIGGER DE BASE DE DATOS ................................................................................ 94 SECUENCIA DE EJECUCION DE UN TRIGGER DE BASE DE DATOS ................................................. 94 Predicados Condicionales ................................................................................................................................ 96 ELIMINANDO UN TRIGGER DE BASE DE DATOS ................................................................................. 98 PRACTICA 6................................................................................................................................................... 99

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 4

I�TRODUCCIO� A PL/SQL

En este taller los participantes aprenderán a escribir programas en PL\SQL, a almacenarlos en

la base de datos, y luego accesarlos desde cualquier otra interfaz.

OBJETIVOS DEL CURSO:

• Crear, ejecutar y mantener procedimientos, funciones, paquetes, triggers de la base de

datos y tipos de objetos

• Administrar la construcción de programas PL/SQL

• Describir los ambientes de desarrollo PL/SQL

CO�TE�IDO PROGRAMÁTICO:

• Introducción a PL\SQL

• Estructura de los bloques

• Tipos de Bloques

• Declaración de variables

• Operadores

• Funciones en PL\SQL

• Estructuras de Control

• Cursores

• Manejo de Errores

• Programas almacenados en la B.D.

• Triggers de Base de Datos.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 5

ESTRATEGIAS METODOLÓGICAS:

• Utilización de laminas audiovisuales las cuales serán transmitidas durante el curso.

• Realización de ejercicios prácticos, los cuales son asignados por el instructor.

RECURSOS AUDIOVISUALES Y EVALUACIÓ�:

• diapositivas elaboradas en power point

• Para la evaluación se realizaran distintas practicas dirigidas por el instructor.

REQUISITOS DE ADMISIÓ�:

• Introducción a SQL y SQL Avanzado

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 6

Capítulo 1

I�TRODUCCIO� A PL/SQL

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 7

I�TRODUCCIÓ� A PL/SQL

El SQL es un lenguaje muy poderoso, permite visualizar, modificar, o borrar múltiples

registros con el uso de una simple instrucción. También puede ser usado para crear reportes,

empleando para ello muy poco esfuerzo. Esto nos da la ventaja, de realizar accesos a la base de

datos, sin la necesidad de poseer un software especializado.

Es muy probable que en sus prácticas de SQL, UD. haya sentido la necesidad de usar

condiciones, bucles, o declarar variables, como lo hacía en los lenguajes de tercera generación,

como lo son Pascal, Basic, C, Cobol, etc. Para mayor sorpresa observó que esto no es posible

usando solo SQL. Fue por la razón que se hizo necesaria una herramienta que concediera todas las

ventajas de SQL y a su vez, todas las ventajas de un lenguaje de tercera generación. Es así como

nace PL/SQL.

PL/SQL es clasificado como un lenguaje procedimental, debido al uso de bucles,

condicionales, y declaración de variables; su entrada y salida es a través de parámetros o medios

intermedios.

Los bloques de PL/SQL, se pueden escribir en SQL*Plus, para realizar accesos rápidos a la

base de datos, sin la necesidad de utilizar un software especializado, pero PL/SQL también es

empleado en otras herramientas de ORACLE, (como por ejemplo FORMS, REPORTS, Pro*C,

POWER*OBJECTS, entre otras), para la elaboración de programas de gran envergadura.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 8

ESTRUCTURA DE LOS BLOQUES DE PL/SQL

El lenguaje de programación PL/SQL es un lenguaje estructurado por bloques. En este, los

programas son divididos en bloques lógicos. Cada bloque es independiente y consta de tres

secciones: Sección Declarativa (opcional), Ejecutable (Obligatoria) y de Manejo de Excepciones

(Opcional). Solo las palabras reservadas BEGIN y END son obligatorias y al menos una

instrucción dentro de ellas. La tabla siguiente describe brevemente las tres secciones:

Sección Descripción Inclusión

Declarativa Contiene todas las variables, constantes, cursores y excepciones definidas por el usuario que son referenciadas en la sección Ejecutable y en la misma sección Declarativa

Opcional

Ejecutable Contiene instrucciones SQL para manipular la data en la base de datos e instrucciones PL/SQL que permiten manipular la data en el bloque

Obligatoria

Manejo de Excepciones Indica las acciones a tomar cuando ocurra una condición anormal o algún error durante la ejecución de las instrucciones de la sección Ejecutable

Opcional

La estructura básica de un bloque de PL/SQL es la siguiente:

DECLARE

-- Declaraciones de variables, cursores y excepciones

BEGIN -- Inicio de Bloque

-- Instrucciones SQL;

-- Instrucciones PL/SQL;

EXCEPTION;

-- Instrucciones para el manejo de errores

END; -- Fin de Bloque

/ -- Comando de ejecución del bloque

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 9

Cada instrucción de SQL o cada sentencia de control de PL/SQL debe estar terminada en

punto y coma (;)

Para ejecutar un bloque de PL/SQL se debe utilizar un slash (/). Cuando el bloque se ha

ejecutado exitosamente, debe aparecer el mensaje siguiente:

PL/SQL procedure successfully completed

En PL/SQL un error es llamado una excepción.

Las palabras reservadas DECLARE, BEGIN y EXCEPTION son las únicas que no están

seguidas de punto y coma.

TIPOS DE BLOQUE

Cada unidad de programa de PL/SQL se compone de uno o más bloques, estos bloques

pueden ser independientes o estar inmersos uno dentro de otro. Puede haber cualquier número de

sub-bloques internos o anidados. Se conocen dos tipos de bloque anónimos y subprogramas

(Procedimientos y Funciones). La siguiente figura ilustra la estructura de los tipos de bloques

conocidos:

Anónimo Procedimiento Función

[DECLARE]

BEGIN

--- Instrucciones

[EXCEPTION]

--- Instrucciones

END;

PROCEDURE nombre IS

BEGIN

--- Instrucciones

[EXCEPTION]

--- Instrucciones

END;

FUNCTION nombre IS

RETURN tipo_dato

BEGIN ----

Instrucciones

RETURN valor,

[EXCEPTION] ---

Instrucciones

END;

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 10

Bloques Anónimos

Son bloques sin nombre, se declaran en un punto de la aplicación desde el cual se ejecutan.

Se puede insertar un bloque anónimo dentro de otro programa que posea un precompilador, como

Pro*C o ejecutarse desde SQL*Plus. El cuerpo de instrucciones de los Triggers lo conforman

bloques de este tipo.

Subprogramas

Son bloques de PL/SQL con nombre. Estos pueden tomar parámetros de entrada y devolver

valores a su vez una vez finalizada la ejecución. Se pueden invocar desde diferentes puntos en la

aplicación. Se declaran como Procedimientos y Funciones, en general se elabora un procedimiento

para ejecutar alguna tarea compleja o repetitiva, y una función para calcular algún valor.

Puede almacenar subprogramas en la base de datos o declararlos como parte de una

aplicación, estos subprogramas pueden ser llamados desde cualquier parte, si están en la base de

datos, o desde cualquier parte de la aplicación si solo pertenecen a esta.

La siguiente tabla muestra los diferentes programas que pueden crearse en PL/SQL:

Tipo de Programa Descripción Disponibilidad

Anónimo Bloque sin nombre de PL/SQL

que esta inmerso dentro de una

aplicación o que es interactivo

Todos los entornos de

PL/SQL

Stored Procedure o

Función

Bloque PL/SQL con nombre

almacenado en el Oracle Server, puede

aceptar parámetros y ser llamado varias

veces usando el nombre

Oracle Server

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 11

Procedimiento o

Función de Aplicación

Bloque con nombre de PL/SQL

almacenado en una aplicación Developer

o una librería compartida, puede aceptar

parámetros y ser invocado repetidas

veces usando el nombre

Componentes Oracle

Developer, por ejemplo Forms

Paquete Modulo con nombre de PL/SQL

que agrupa objetos relacionados como

procedimientos, funciones e

identificadores

Componentes Oracle

Server y Oracle Developer, por

ejemplo Forms

Trigger de base de

datos

Bloque de PL/SQL que esta

asociado a una tabla de la base de datos y

se ejecuta automáticamente cuando

ocurre el evento para el que fue definido

Oracle Server

Trigger de

aplicación

Bloque de PL/SQL que esta

asociado con un evento en la aplicación y

se ejecuta automáticamente cuando el

evento ocurre durante la ejecución

Componentes de Oracle

Developer, por ejemplo Forms

SI�TAXIS DE BLOQUES PL/SQL

Debido a que PL/SQL es una extensión de SQL, las reglas de sintaxis en general que aplican

a SQL también aplican al lenguaje PL/SQL:

Los identificadores y literales, así como otras unidades léxicas, pueden estar separadas por

uno o más espacios u otros delimitadores que no puedan ser confundidos como parte de la unidad

léxica. No puede insertar espacios dentro de las unidades léxicas excepto en cadenas de caracteres

literales y comentarios.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 12

Las instrucciones pueden estar en una misma línea, pero las palabras clave deben estar en una

única línea.

DELIMITADORES

Los delimitadores son símbolos simples o compuestos que adquieren un significado especial

al ser interpretados por PL/SQL, la siguiente tabla muestra los símbolos que maneja este lenguaje:

Símbolo Significado Símbolo Significado

+ Operador de adición <> Operador “diferente de”

- Operador de sustracción/negación != Operador “diferente de”

* Operador de multiplicación | | Operador de concatenación

/ Operador de división real -- Comentario de una línea

= Operador “igual a” /* Delimitador “apertura de comentario”

@ Indicador de acceso remoto */ Delimitador “cierre de comentario”

; Terminador de instrucción := Operador de asignación

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 13

IDE�TIFICADORES

Los identificadores son usados para nombrar programas PL/SQL, ítems y unidades, entre las

cuales pueden incluir variables, constantes, excepciones, cursores, variables de cursores,

subprogramas y paquetes. Las reglas para nombrar un identificador en PL/SQL son las mismas que

para nombrar variables.

LITERALES

Un literal es un valor explícito ya sea numérico, string, caracter o booleano. Es un valor no

representado por un identificador.

Los literales incluyen todos los caracteres imprimibles en PL/SQL, estos son letras, números,

espacios y caracteres especiales.

Los literales numéricos se pueden representar por un valor simple entero o punto flotante (por

ejemplo 5 ó -650.76) o en notación científica (por ejemplo 3.45E-5 lo que representa 3.4x10-5)

COME�TARIOS

Los comentarios son utilizados para documentar los programas y facilitar el mantenimiento

de los mismos. En PL/SQL los comentarios deben estar precedidos por dos guiones de separación

(--) sin blanco entre ellos, si el comentario ocupa una línea o encerrado entre los separadores de

inicio y fin /* y */, si el comentario ocupa varias líneas.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 14

El siguiente ejemplo muestra el uso de los comentarios:

v_salario NUMBER(9,2);

BEGIN -- Este es el inicio del bloque

/* En este bloque se calcula el salario anual basado en el salario

mensual el cual es dado por el usuario como dato de entrada */

v_salario := &p_salario_mensual * 12;

END; -- Este es el final de la transacción

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 15

TIPOS DE DATOS E� PL/SQL

La siguiente tabla muestra un resumen de los tipos de datos base de PL/SQL:

Tipo de Dato Descripción

VARCHAR2(long. max) Cadena de caracteres de longitud variable con un máximo de “long.

max” pueden llegar hasta un máximo de 32.767 bytes y no tiene longitud

por defecto

NUMBER[(posic, dec)] Numero de precisión fija o flotante con “posic” posiciones y “dec”

posiciones decimales

DATE Fecha y Hora hasta una precisión de minutos y segundos

CHAR[(long.max)] Caracteres de longitud fija hasta un máximo de 32.767 bytes, por defecto

la longitud es 1

LONG Cadenas de caracteres de hasta 2 Gbytes de longitud. Estos datos no

pueden ser seleccionados y almacenados en una variable PL/SQL

RAW Números enteros hasta 255

LONG RAW Datos en formato binario de hasta 2 Gbytes, generalmente utilizado para

imágenes, este tipo de dato no es interpretado por PL/SQL

BOOLEAN Valores lógicos, pueden almacenar tres posibles valores VERDADERO,

FALSO o NULL

BINARY_INTEGER Valores enteros entre –2.147.483.647 y 2.147.483.647

PLS_INTEGER Valores enteros entre -2.147.483.647 y 2.147.483.647 pero los cuales

requieren menor almacenamiento que los demás tipos numéricos

RECORD Columnas tipo registro

TABLE Arreglo de una dimensión

ROWID Dirección de fila en formato hexadecimal

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 16

VARIABLES E� PL/SQL

Con PL/SQL se pueden declarar variables, estas variables pueden ser utilizadas para recibir

valores resultantes de la ejecución de consultas SQL, o pueden aparecer en cualquier tipo de

expresiones que aparezcan dentro del bloque PL para el cual fueron declaradas. Algunas ventajas

del uso de variables son las siguientes:

• Almacenamiento temporal de datos

• Calculo de valores sin nuevos accesos a la base de datos

• Pueden ser reutilizadas en distintas partes del bloque de instrucciones

• Son fáciles de mantener y actualizar

TIPOS DE VARIABLE E� PL/SQL

En PL/SQL se pueden declarar distintos tipos de variables:

ESCALARES

Son variables que contienen valores simples, almacenan principalmente valores que

corresponden a los mismos tipos básicos de las columnas de una tabla. También pueden almacenar

valores lógicos.

COMPUESTAS

Son variables que contienen varios tipos de datos, como los registros.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 17

REFERE�CIAS

Son variables de tipo puntero referencian posiciones de almacenamiento de otros objetos.

Estas variables no están cubiertas por este curso.

LOB

Variables llamadas localizadores. Indican la localización de objetos complejos cuyo

almacenamiento real esta en archivos fuera de base de datos, como por ejemplo imágenes, texto,

vídeo, etc de hasta 4 GB de longitud.

Los tipos de dato LOB (Objetos Largos) permiten localización eficiente y acceso aleatorio a

los datos, existen los siguientes tipos de datos LOB:

• CLOB : (Character Large Object) se utilizan para almacenar grandes cantidades

de texto en la base de datos.

• BLOB: (Binary Large Object) se utiliza para almacenar en la base de datos

objetos binarios.

• BFILE : (Binary File) se utiliza para almacenar archivos binarios fuera de la base

de datos, en archivos del sistema operativo.

• NCLOB: (National Language Character Large Object) se utiliza para almacenar

grandes bloques de datos en la base de datos con formatos de presentación

multilenguaje.

Además existen variables que no son de PL/SQL:

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 18

� Variables Bind (de enlace), son variables que se declaran en una sesión y sirven

para almacenar cálculos parciales, son las variables utilizadas para el pase de

parámetros al runtime durante la ejecución de uno o más programas PL/SQL. Para

declarar una variable bind durante una sesión de SQL*Plus se utiliza el comando

VARIABLE seguido del nombre de la variable y el tipo, a continuación se muestra un

ejemplo :

VARIABLE valor_de_retorno NUMBER

VARIABLE mensaje_devuelto VARCHAR2(60)

Tanto SQL como SQL*Plus pueden referenciar las variables bind, y SQL*Plus puede

visualizar su valor o utilizarla como cualquier variable durante la ejecución de cualquier bloque.

Para visualizar el contenido de una variable de tipo bind se utiliza el comando PRINT. El siguiente

ejemplo ilustra el uso del comando PRINT:

SQL> VARIABLE tot_sueldo NUMBER

. . .

SQL> PRINT tot_sueldo

� Variables Host: son llamadas también variables de sustitución, se definen

precediendo al identificador por el símbolo ampersand, se referencian dentro de los

bloques de PL/SQL colocando inclusive el símbolo ampersand y su efecto es el de

sustituir completamente la variable por la cadena que recibe como entrada. El siguiente

ejemplo muestra un ejemplo en el cual se hace uso de ambos tipos de variables,

contiene comandos de SQL*Plus y un bloque completo de PL/SQL :

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 19

VARIABLE salario_mensual NUMBER

ACCEPT salario_anual PROMPT ‘Introduzca el Salario Anual : ‘

DECLARE

salario_auxiliar NUMBER(12,2) := &salario_anual;

BEGIN

:salario_mensual := salario_auxiliar / 12;

END;

/

PRINT salario_mensual

También podemos ver el contenido de las variables bind usadas dentro de un bloque

PL/SQL, desde dentro del mismo bloque, haciendo uso del paquete DBMS_OUTPUT.PUT_LINE

que es un paquete proporcionado por ORACLE y PUT_LINE es un procedimiento dentro de ese

paquete. El siguiente ejemplo muestra el uso del paquete DBMS_OUTPUT:

SET SERVER OUTPUT ON

ACCEPT salario_anual PROMPT ‘Introduzca el Salario Anual : ‘

DECLARE

salario_auxiliar NUMBER(12,2) := &salario_anual;

BEGIN

salario_auxiliar := salario_auxiliar / 12;

dbms_output.put_line (‘El salario mensual es ‘

| | TO_CHAR(salario_auxiliar));

END;

/

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 20

Observe que en este ejemplo no se hace uso de ninguna variable host.

DECLARACIO� DE VARIABLES E� PL/SQL

Es necesario declarar todos los identificadores en la sección declarativa antes de referenciar

estos en cualquier bloque PL/SQL, se pueden asignar valores iniciales a las variables durante la

declaración, cada variable debe estar en una línea de declaración separada.

Sintaxis: identificador [CO�STA�T] tipo_dato [�OT �ULL] [:= | DEFAULT expresión];

Donde:

identificador: es el nombre de la variable

CONSTANT: restringe la variable al único valor de inicialización, no puede ser cambiado

tipo_dato: es un tipo de dato valido, escalar, compuesto, referencia o LOB

NOT NULL: indica que la variable no puede contener un valor nulo, las variables que

poseen esta cláusula deben ser inicializadas

expresión: es cualquier expresión PL/SQL valida, puede ser un literal, otra variable o una

expresión que involucra operadores y funciones

En la declaración debe considerar lo siguiente:

� Los nombres de variables deben obedecer las mismas reglas que los objetos SQL

� Es recomendable usar ciertos estándares en los nombres para mayor facilidad de

comprensión y mantenimiento del código, por ejemplo v_nombre indicara el nombre

de una variable y c_nombre indicara el nombre de una constante

� Se puede inicializar la variable usando el operador de asignación, o usando la

palabra reservada DEFAULT, si no hay asignación inicial el valor será NULL hasta

que se realice la primera asignación

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 21

� Dos objetos pueden tener el mismo nombre, si están definidos en bloques distintos,

cuando esto sucede, solo puede usarse en un bloque el objeto que esta definido en él

� No se debe asignar nombres de variables con el mismo nombre de una columna

referenciada en el bloque, cuando esto sucede al referenciar el nombre de la variable, el

manejador asumirá que se está consultando la columna y puede generar errores

� Los identificadores no deben tener más de 30 caracteres. El primer carácter debe ser

una letra, los restantes caracteres pueden ser letras, números o caracteres especiales

A continuación se muestran algunos ejemplos de declaración de variables:

Ejemplos de variable tipo �UMBER:

DECLARE

EDAD NUMBER(2);

SUELDO NUMBER(8,2);

SUELDO NUMBER(8,2) := 0;

PI CONSTANT NUMBER(5,4) := 3.141592;

Ejemplos de variable tipo CHAR:

DECLARE

NOMBRE CHAR(20);

DEPARTAMENTO CHAR(14) NOT NULL := 'ADMINISTRACIÓN';

LETRAINICIAL CHAR;

Ejemplos de variable tipo DATE:

DECLARE

NACIMIENTO DATE;

FUNDACION DATE :='17-JAN-94';

NACIMIENTO DATE NOT NULL;

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 22

Ejemplos de variable tipo BOOLEA�:

DECLARE

DISPONIBLE BOOLEAN;

DISPONIBLE BOOLEAN := NULL;

DISPONIBLE BOOLEAN NOT NULL := TRUE;

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 23

VARIABLES TIPO ATRIBUTO E� PL/SQL

Los objetos de PL/SQL (variables y constantes) y las operaciones efectuadas sobre los

objetos de la base de datos (tablas, vistas y columnas), pueden ser asociados con los siguientes

atributos:

%ROWTYPE : Este atributo es utilizado para declarar una variable con la estructura

idéntica a la de una fila en una tabla o vista. A continuación se muestra un ejemplo:

FILA_EMP EMPLEADO%ROWTYPE;

En la declaración anterior, la estructura del identificador FILA_EMP será idéntica a la de la

fila en la tabla EMPLEADO.

%TYPE: Este atributo es utilizado para declarar una variable del mismo tipo como:

- Una columna de una tabla o vista

- Una variable previamente declarada

A continuación se muestra un ejemplo de este tipo de declaración:

TRABAJADOR EMPLEADO.NOMBRE%TYPE;

En este ejemplo, el identificador TRABAJADOR será del mismo tipo que la columna

NOMBRE de la tabla EMPLEADO.

Variables tipo RECORD

Se utilizan para declarar registros con campos especificados por el usuario.

Sintaxis : TYPE nombre_tipo IS RECORD nombre_campo tipo_campo [�OT �ULL]

:= expresión _pl/sql

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 24

A continuación se muestra un ejemplo de una declaración de variable de tipo RECORD:

DECLARE

TYPE emprectyp IS RECORD

(empno NUMBER(4) NOT NULL,

ename VARCHAR2(10),

job VARCHAR2(14),

......

deptno NUMBER (4));

La siguiente declaración, define la variable reg_emp como de tipo registro con la estructura

definida en la declaración anterior.

emp_rec emprectyp;

Los campos de un registro, pueden ser inicializados en la declaración

DECLARE

TYPE timetyp IS RECORD

(second NUMBER(2) :=0,

minute NUMBER(2) := 0,

hour NUMBER(2) := 0);

Variables tipo TABLE

Se tiene un nuevo tipo de dato el cual permite ser usado como un arreglo, es el tipo TABLE.

A continuación se muestra la sintaxis para declarar variables de tipo table.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 25

TYPE nombre_tipo IS TABLE OF columna_tipo/nombre_tabla.nombre_columna%TYPE

[�OT �ULL] I�DEX BY BINARY_INTEGER

A continuación se muestra un ejemplo de una declaración de variable tipo TABLE:

DECLARE

TYPE enametabtyp IS TABLE OF CHAR(10)

INDEX BY BINARY_INTEGER;

DECLARE

TYPE enametabty IS TABLE OF emp.ename%TYPE

INDEX BY BINARY_INTEGER;

Al declarar una variable de PL/SQL como de tipo TABLE se deben tener en cuenta las

siguientes consideraciones:

� No puede ser inicializada en la declaración

� Puede ser pasada como parámetro de procedimientos

� No pueden ser utilizadas en una cláusula INTO.

� Para referenciar sus valores, se debe utilizar la posición del elemento que se

desea manipular o consultar. De la misma manera que cuando se referencian

posiciones de un arreglo o vector.

En el siguiente ejemplo, se muestra la forma de insertar en la tabla EMPLEADO los valores

del vector filas pasado como parámetro al procedimiento insertar_datos_emp

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 26

PROCEDURE insertar_datos_emp

(filas BINARY_INTEGER, empno_tab empnotabtyp, ename_tab enametabtyp) IS

BEGIN

FOR i IN 1 .. filas LOOP

INSERT INTO EMPLEADO (EMPNO, NOMBRE, ...)

VALUES (empno_tab(i), ename_tab(i), ...);

END LOOP;

END;

ASIG�A�DO VALORES A VARIABLES

Para asignar un valor a una variable, deberá escribir una sentencia PL/SQL. En el lado

izquierdo estará el nombre de la variable ya declarada, a continuación el operador de asignación

(:=) y seguidamente el valor o la expresión cuyo resultado se almacenara en la variable, terminando

con punto y coma (;).

Sintaxis: identificador := expresión;

Donde:

identificador: es el nombre de la variable

expresión: puede ser una variable, un literal o una llamada a función, pero no una columna de

base de datos

Ejemplo 1: Asignar a la variable PROMEDIO, el promedio de 5, 10 y 30

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 27

Ejemplo 2: Almacenar en la variable SALARIOMENSUAL el salario del empleado

PABLO

SELECT SALARIO I�TO SALARIOMENSUAL

FROM EMPLEADO

WHERE NOMBRE = 'PABLO';

Evaluando Condiciones con el Valor �ULL

� Se puede determinar una condición de NULL con el operador IS NULL

� Cualquier expresión aritmética que contenga un valor NULL el resultado será NULL

� El valor NULL en las operaciones de concatenación se tratara como un string vacío

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 28

BLOQUES I�TER�OS Y ALCA�CE DE VARIABLES

En los bloques PL/SQL una variable declarada en la sección de declaraciones, solo es visible

dentro de ese bloque. Un bloque que sea declarado a su vez dentro de otro (bloque interno) puede

acceder a las variables que fueron declaradas en el bloque principal que lo contiene y manipular el

contenido de estas variables, además de las variables que sean declaradas en su propia sección de

declaración. Sin embargo, las variables declaradas en el bloque interno no pueden visualizarse en el

bloque externo.

El siguiente cuadro muestra un ejemplo del ámbito de visualización de las variables en un

bloque interno:

… DECLARE X

BINARY_INTEGER; BEGIN

-- Instrucciones X := X + 1;

DECLARE Y NUMBER; BEGIN

Alcance

de X

… Y := Y + X; …

Alcance

de Y

END; …

END;

En el ejemplo anterior observe que en bloque interno tanto la variable X, que fue declarada

en el bloque externo, como la variable Y propia del bloque, son visibles en tanto que en el bloque

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 29

externo solo es visible la variable X. Esto se debe a que una variable declarada en un bloque, tiene

vida solo mientras el bloque se ejecuta, y desaparece al terminar la ejecución de ese bloque.

Alcance

El alcance de un identificador es la zona de una unidad de programa, sea esta un bloque,

subprograma o paquete desde donde puede ser referenciado ese identificador.

OPERADORES

Los operadores son símbolos reservados de PL/SQL que permiten la comparación de dos o

más expresiones para permitir la obtención de un resultado BOOLEANO. Se conocen varios tipos

de operadores, a continuación se muestran los operadores que maneja PL/SQL:

OPERADORES �UMERICOS

Operador Significado

< menor que

> mayor que

= igual a

!= ó <> diferente de

<= menor o igual a

>= mayor o igual a

OPERADORES LOGICOS O BOOLEA�OS

Operador Significado

AND Y

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 30

OR O

NOT Negación

Los operadores lógicos poseen un valor de verdad que puede ser TRUE o FALSE, o en su

defecto puede ser NULL o vacío. Dependiendo de los valores de las dos expresiones que en un

momento dado se estén comparando, los valores posibles de la comparación para cada tipo de

operador se muestran a continuación:

Para el operador A�D

TRUE FALSE NULL

TRUE TRUE FALSE NULL

FALSE FALSE FALSE FALSE

NULL NULL FALSE NULL

Para el operador OR

TRUE FALSE NULL

TRUE TRUE TRUE TRUE

FALSE TRUE FALSE FALSE

NULL TRUE NULL NULL

Para el operador �OT

TRUE FALSE NULL

FALSE TRUE NULL

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 31

PRACTICA 1 1. Desarrollar un bloque de programa simple, que muestre el costo final de un producto, al

aplicar el Iva de 15% al precio solicitado como entrada.

2. Declarar una tabla PL/SQL denominada estudiante con los campos nombre, edad y sexo. El

programa deberá mostrar un mensaje indicando que la misma esta vacío, utilice los

métodos vistos.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 32

Capítulo 2

FU�CIO�ES E� PL/SQL

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 33

FU�CIO�ES E� PL/SQL

El lenguaje de programación PL/SQL soporta todas las funciones provistas por SQL. Todas

las funciones, excepto las de agrupamiento, pueden ser utilizadas como parte de una instrucción

PL/SQL que no involucra cláusulas de SQL. La tabla siguiente muestra algunas de las funciones

que pueden utilizarse clasificadas por tipo:

Tipo de función Funciones pertenecientes al tipo

Numéricas SQRT, ROUND, POWER, TRUNC, TO_NUMBER

Carácter LENGTH, UPPER, LOWER, INITCAP, LPAD, RPAD, LTRIM,

TO_CHAR, SUBSTR

Fecha y Hora ADD_MONTHS, MONTHS_BETWEEN, LAST_DAY, TO_DATE

De Grupo AVG, MAX, MIN, COUNT, SUM

I�TERACTUA�DO CO� EL ORACLE SERVER

El lenguaje de programación PL/SQL soporta totalmente las sentencias del lenguaje de

manipulación de datos de SQL. Esto significa que puede soportar las instrucciones: SELECT de

recuperación de datos, UPDATE de actualización de datos, INSERT de inserción de datos y

DELETE de eliminación de datos. También soporta las instrucciones que permiten el control de

transacciones y el resguardo de la integridad en la base de datos, como son COMMIT, para guardar

de forma permanente los datos en la base de datos, ROLLBACK para anular una transacción que

no haya sido guardada previamente con una instrucción commit, SAVEPOINT para fijar un punto

de control que sirve para devolver parcialmente una transacción, desde el lugar en que se encuentra

hasta el punto donde se definió el savepoint, y LOCK TABLE para el bloqueo de tablas durante las

modificaciones críticas de datos.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 34

Los identificadores de cada sentencia son primero verificados para comprobar si son

columnas de una tabla de la base de datos, en caso de no serlo, el manejador asumirá que es un

identificador de PL/SQL.

COMPARACIO� DE I�STRUCCIO�ES SQL y PL/SQL

� Un bloque PL/SQL no es una unidad de transacción. Las sentencias COMMIT,

ROLLBACK y SAVEPOINT son independientes de los bloques, sin embargo pueden

usarse dentro de cualquier bloque

� PL/SQL no soporta instrucciones de definición de datos, tales como CREATE, DROP o

ALTER

� PL/SQL no soporta instrucciones de control de lenguaje, tales como GRANT y REVOKE

RECUPERA�DO DATOS – La cláusula SELECT

Al igual que en SQL, para recuperar datos de la base de datos se hace uso de la cláusula

SELECT, con la única variante de que para poder manipular el resultado mediante instrucciones

PL/SQL se necesitan variables de almacenamiento propias de PL/SQL, puesto que las columnas no

se pueden manipular directamente.

Sintaxis: SELECT lista_de_columnas

I�TO {lista_de_variables | nombre_registro}

FROM tabla

WHERE condición;

Donde:

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 35

lista_de_columnas: es la lista de una o más columnas que se recuperan en la consulta, puede

contener expresiones SQL, funciones de fila o funciones de grupo

lista_de_variables: es una lista de variables escalares, deben coincidir tanto en posición como en

tipo de dato y número, con las columnas que se recuperan en la consulta

nombre_registro: es el bloque PL/SQL que recibirá los valores

Tabla : indica la o las tablas desde las cuales se hace la consulta

condición: es la condición de búsqueda, puede contener nombres de columnas, expresiones,

constantes y operadores de comparación, incluyendo variables PL/SQL

La cláusula INTO es obligatoria, debe aparecer entre las opciones SELECT y FROM. Se

utiliza para especificar las variables que almacenaran los valores de las columnas que retornara la

consulta. La consulta debe retorna una y solo una fila, si retorna mas de una generara un error, igual

sucede cuando la consulta no retorna ninguna fila. En PL/SQL los errores pueden capturarse y

tratarse de manera diferente para que el programa no se detenga de manera abrupta, a este proceso

se le llama manejo de excepciones y será explicado en capítulos posteriores.

En el siguiente ejemplo se muestra un ejemplo del uso de la cláusula INTO:

DECLARE

v_deptno NUMBER(2);

v_loc VARCHAR2(15);

BEGIN

SELECT deptno, loc

INTO v_deptno, v_loc

FROM dept

WHERE dname = ‘VENTAS’;

END;

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 36

I�SERTA�DO DATOS – La cláusula I�SERT

La inserción de datos desde PL/SQL cumple las mismas especificaciones de la inserción

hecha desde SQL. A continuación se muestra un ejemplo de la inserción de datos desde un bloque

PL/SQL:

DECLARE

SUELDO NUMBER(6,2) := 5000.50;

EMPLEADO CHAR(25) := 'MONICA';

BEGIN

INSERT INTO EMPLEADO (NOMBRE, CARGO,

SALARIO)

VALUES (EMPLEADO, 'SECRETARIA', SUELDO);

END;

ACTUALIZA�DO DATOS – La cláusula UPDATE

En el siguiente ejemplo se muestra un caso de una posible inserción desde un bloque

PL/SQL:

DECLARE

SUELDO NUMBER(6,2) := 5000.50;

EMPLEADO CHAR(25) := 'MONICA';

BEGIN

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 37

UPDATE EMPLEADO

SET SALARIO = SALARIO * 1.5

WHERE EMPNO = 500;

END;

BORRA�DO DATOS – La cláusula DELETE

Igual que en las operaciones anteriores, la eliminación de datos desde un bloque PL/SQL es

idéntica a la eliminación de datos hecha desde SQL. A continuación se muestra un ejemplo:

DECLARE

EMPLEADO EMPLEADO.NOMBRE%TYPE := 'MONICA';

BEGIN

DELETE FROM EMPLEADO

WHERE NOMBRE = EMPLEADO

AND CODIGO = 1050;

COMMIT;

END;

CO�TROL DE TRA�SACCIO�ES

El lenguaje PL/SQL permite un control total de la lógica de las transacciones, tomando como

transacción el mismo criterio que en SQL. Esto permite que el usuario pueda controlar totalmente

los cambios que se efectúan en la base de datos, guardando algunos grupos de datos y descartando

otros si la situación así lo requiere. Una transacción comienza con la primera instrucción SQL que

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 38

se ejecuta y finaliza con el próximo COMMIT o ROLLBACK exitoso, el final de una transacción

puede ocurrir de manera explícita, por una instrucción dentro de un bloque PL/SQL o de manera

implícita, por algún evento en el entorno de SQL donde se está ejecutando el bloque de

instrucciones, por ejemplo la culminación de una sesión SQL*Plus termina automáticamente la

transacción pendiente. Para marcar un punto intermedio en el procesamiento de la transacción se

utiliza el comando SAVEPOINT.

Sintaxis : SAVEPOINT punto_intermedio;

Donde:

punto_intermedio: es el nombre de punto de control hasta donde se reversará la transacción

en caso de usar una sentencia ROLLBACK.

Los comandos de control de transacciones son completamente soportados por PL/SQL, sin

embargo algunas instalaciones pueden imponer algunas restricciones al uso de estos.

A continuación se muestra un ejemplo de la aplicación de las cláusulas de control de

transacciones:

DECLARE

SUELDO NUMBER(6,2) := 5000.50;

EMPLEADO CHAR(25) := 'MONICA';

BEGIN

INSERT INTO EMPLEADO (NOMBRE, CARGO,

SALARIO)

VALUES (EMPLEADO, 'SECRETARIA',

SUELDO);

SAVEPOINT A;

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 39

DELETE FROM EMPLEADO

WHERE NOMBRE = 'LUIS'

AND CODIGO = 2350;

SAVEPOINT B;

UPDATE EMPLEADO

SET SALARIO = SUELDO

WHERE NOMBRE = EMPLEADO

OR NUMDEPT = 01;

ROLLBACK TO SAVEPOINT B;

COMMIT;

END;

/

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 40

PRACTICA 2 1. Crear un bloque PL/SQL que muestre por pantalla cuantos registros tiene la tabla

Empleados.

2. Crear un bloque PL/SQL que inserte una fila a la tabla empleados. Todos los datos debe ser

solicitados por pantalla.

3. Crear un bloque PL/SQL que actualice el nombre del registro insertado en el ejercicio

anterior.

4. Crear un bloque PL/SQL que elimine el registro insertado en el ejercicio anterior

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 41

Capítulo 3

ESTRUCTURAS DE CO�TROL

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 42

ESTRUCTURAS DE CO�TROL DE PL/SQL

En PL/SQL se puede controlar el flujo de control de las operaciones mediante el uso de dos

tipos de estructuras de control básicas: CONDICIONALES con la sentencia IF e ITERACIONES

con la sentencia LOOP.

CO�DICIO�ALES

El condicional es una sentencia que controla la ejecución de sus bloques de instrucciones

dependiendo del valor de verdad que retorna una o más comparaciones que gobiernan a la

instrucción. En PL/SQL el resultado de una comparación puede arrojar como resultado: TRUE,

FALSE o NULL.

Cuando es posible la aparición de un valor NULL, se debe tomar en cuenta lo siguiente:

• Cuando se realiza una comparación entre un valor NO NULO y un valor NULO, el

resultado siempre será NULO.

• Cuando se realiza un cálculo (suma, resta, etc.) de un valor NO NULO y un valor

NULO el resultado siempre será NULO, exceptuando la concatenación.

A continuación se muestran algunos ejemplos:

10 + NULL --------------------> el resultado será NULO.

'ANA' || NULL || 'LISIS' ------> el resultado será ANALISIS.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 43

La sentencia IF

Permite la ejecución de una o varias sentencias dependiendo de que el valor de verdad que

retorna una condición resulte verdadero. En la instrucción condicional puede haber una o más

condiciones en la misma instrucción, en este caso cada una gobernará la ejecución de un grupo de

instrucciones y todas las condiciones deben ser excluyentes entre sí.

Sintaxis: IF condición THE� sentencia o grupo de sentencias [ELSIF condición THE� sentencia o grupo de sentencias] . . . . . . . . . . . . . . . . (grupo de ELSIF) . . . . . . . . [ELSE sentencia o grupo de sentencias por defecto] END IF;

Donde:

condición: es como su nombre lo indica, el parámetro que permitirá la ejecución o no de las

instrucciones que están dentro del IF. Si la condición es verdadera las sentencias asociadas al IF se

ejecutan, en el caso contrario (FALSE o NULL), no se ejecutan.

sentencias o grupo de sentencias: son el conjunto de instrucciones que formarán el

algoritmo que se ejecutará cuando la condición se cumpla.

Ejemplo de IF: Construya un programa que permita obtener como parámetro de entrada

desde teclado un código de empleado, buscará el salario del mismo y aumentar el sueldo según la

tabla siguiente:

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 44

Rango de sueldos Monto de

aumento

De 10.000 a 20.000 5.000

> 20.000 y <=

30.000

4.000

DECLARE

SUELDO NUMBER;

BEGIN

SELECT SALARIO INTO SUELDO

FROM EMPLEADO

WHERE CODIGO = &IDENTIFICA;

IF (SUELDO => 10000) AND (SUELDO <= 20000) THEN

UPDATE EMPLEADO

SET SALARIO = SUELDO + 5000;

WHERE CODIGO = &IDENTIFICA;

ELSIF (SUELDO > 20000) AND (SUELDO < 30000)

THEN

UPDATE EMPLEADO

SET SALARIO = SUELDO + 4000;

WHERE CODIGO = &IDENTIFICA;

END IF;

COMMIT;

END;

/

�OTA: El ampersand (&) es usado en los bloques de PL/SQL, (cuando se trabaja con SQL*PLUS), para

facilitar el ingreso de parámetros. Los parámetros serán recibidos e interpretados al momento de la ejecución del bloque.

Como se puede observar en el ejemplo anterior, código es igual a &IDENTIFICA, donde &IDENTIFICA va a ser

sustituido por el valor introducido por el usuario al momento de ejecutar el bloque de PL/SQL.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 45

ITERACIO�ES

Una iteración es la ejecución repetida de un conjunto de instrucciones, múltiples veces hasta

que se cumpla una condición, que permite la finalización del ciclo. Existen dos formas de realizar

una iteración:

� Por medio de bucles

� Por medio de la sentencia GOTO

Existen cuatro tipos de bucles:

� Bucle simple

� Bucle numérico (FOR)

� Bucle condicional (WHILE)

BUCLE SIMPLE

Repite una o más sentencias múltiples veces.

Sintaxis: LOOP

sentencia o grupo de sentencias

condición de salida del bucle

E�D LOOP;

Donde:

LOOP: indica el inicio del bucle

sentencia o grupo de sentencias: conjunto de instrucciones a ejecutar

condición: requisito de salida del bucle. Si a un bucle no se le coloca una condición de salida,

este permanecerá ejecutándose indefinidamente.

La condición de salida posee la siguiente estructura:

EXIT [nombre_de_etiqueta] [WHE� condición];

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 46

El "nombre_de_etiqueta" se utiliza cuando se desea salir, no solamente del bucle en curso,

sino también de uno más externo a este.

A continuación se muestra un ejemplo de bucle simple:

Ejemplo 2: Construya un programa que permita insertar en una tabla temporal diez veces la

cadena de caracteres “HOLA”:

DECLARE

CONTADOR NUMBER(3) := 0;

BEGIN

LOOP

INSERT INTO TEMPORAL (NUMERO1, TEXTO)

VALUES (CONTADOR, 'HOLA');

CONTADOR := CONTADOR + 1;

EXIT WHEN CONTADOR = 10;

END LOOP;

END;

/

BUCLE �UMÉRICO (FOR)

Repite una o más sentencias un número fijo de veces.

Sintaxis: FOR índice I� [ REVERSE ] entero_1 . . entero_2 LOOP

sentencia o grupo de sentencias

E�D LOOP;

Donde:

índice: es la variable de conteo y control del bucle. Esta variable es implícitamente de tipo

numérico, el cual podrá ser referenciado dentro del bucle, pero no podrá asignársele valor

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 47

REVERSE: realiza el conteo de mayor a menor, (si no se coloca este parámetro el conteo se

realizará de menor a mayor).

entero_1 y entero_2: rango en el que se va a realizar el conteo.

Ejemplo 3: Elabore el mismo programa del ejemplo2, usando un bucle numérico:

BEGIN

FOR I IN 1..10 LOOP

INSERT INTO TEMPORAL (NUMERO1, TEXTO)

VALUES (I, 'HOLA');

END LOOP;

END;

/

BUCLE CO�DICIO�AL (WHILE)

Repite una o más sentencias mientras la condición de control de la iteración sea verdadera

Sintaxis: WHILE condición LOOP

sentencia o grupo de sentencias

E�D LOOP;

Donde:

condición: es la condición que gobierna la ejecución

Ejemplo 3: Elabore el mismo programa del ejemplo2, usando el bucle while:

DECLARE

CONTADOR NUMBER(3) := 0;

BEGIN

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 48

WHILE CONTADOR < 10 LOOP

INSERT INTO TEMPORAL (NUMERO2, TEXTO)

VALUES (CONTADOR, ‘HOLA’);

CONTADOR := CONTADOR + 1;

END LOOP;

END;

/

SE�TE�CIA GOTO

La sentencia GOTO, como en otros lenguajes de programación, permite saltar

incondicionalmente hacia una línea específica de un bloque PL/SQL identificada mediante una

etiqueta, pudiendo así alterar la secuencia normal de la ejecución del programa. La etiqueta debe ir

encerrada entre dobles símbolos de “menor que” y “mayor que”

Sintaxis: . . . . . . . . . . . . . . . . GOTO ETIQUETA sentencia o grupo de sentencias <<ETIQUETA>> sentencia o grupo de sentencias . . . . . . . . . . . . . . . . Está permitido el uso de la sentencia GOTO cuando:

- Se ejecute dentro de una misma secuencia de instrucciones

- Se cierra una secuencia de sentencias

No está permitido utilizar la sentencia GOTO:

- Para ir a una etiqueta que se encuentre dentro de un bucle o estructura condicional.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 49

ETIQUETAS

Las etiquetas se pueden usar para referenciar valores en bloques y bucles, que de otra manera

no podrían ser visibles a causa de las reglas de alcance. Las etiquetas tienen que ser especificadas

previa a sentencias ejecutables.

Sintaxis : <<Nombre_etiqueta>> DECLARE declaraciones BEGIN sentencias a ejecutar [EXCEPTION excepciones manejadas en el bloque] E�D Nombre_etiqueta;

En el siguiente ejemplo se muestra el uso de las etiquetas para referenciar bloques:

BEGIN

<<BLOQUEEXTERNO>>

DECLARE

N NUMBER;

BEGIN

N := 5;

<<BLOQUEINTERNO>>

DECLARE

X NUMBER := 10;

N CHAR(10) := 'DOS';

BEGIN

INSERT INTO TEMPORAL

VALUES (BLOQUEEXTERNO.N, X, N);

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 50

COMMIT;

END BLOQUEINTERNO;

END BLOQUEEXTERNO;

END;

/

En el ejemplo anterior, se está utilizando el nombre del bloque para decirle a PL/SQL, que el

valor "N" que deberá ser procesado, es el que se declaró en el bloque externo y no el que se declaró

en el bloque interno.

En el siguiente ejemplo se muestra el uso de las etiquetas para referenciar bucles:

BEGIN

<<ETIQUETA>>

FOR I IN 1..10 LOOP

-- sentencias a ejecutar

DECLARE

I NUMBER := 10;

BEGIN

INSERT INTO TEMPORAL

VALUES (I, ETIQUETA.I, 'COMPLETO');

END;

END LOOP ETIQUETA;

END;

/

En el ejemplo anterior, se toma el valor "I" del bloque interno y el valor "I" del bucle FOR,

referenciado por la etiqueta, al momento de realizar la inserción.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 51

CURSORES

CURSORES en SQL

Cuando se manda a ejecutar una instrucción SQL, el manejador Oracle Server abre un área

en memoria en la cual el comando es interpretado y, en caso de ser correcto, el comando es

ejecutado. A esta área de memoria se le llama CURSOR.

Cuando comienza la ejecución de la instrucción, PL/SQL crea un cursor implícito que posee

el identificador de SQL. PL/SQL maneja este cursor automáticamente, sin embargo el programador

puede declarar explícitamente cursores para el tratamiento secuencial de filas de datos, la forma de

hacer esto se explicará en secciones subsiguientes. Hay cuatro atributos asociados a los cursores

que nos permiten controlar y verificar el resultado de su ejecución, estos atributos son:

SQL%ROWCOUNT Retorna el número de filas que fueron afectadas por la mas reciente

instrucción de SQL, es un valor entero

SQL%FOUND Valor lógico BOOLEANO que retorna VERDADERO si la más reciente

instrucción SQL afectó una o más filas de datos

SQL%NOTFOUND Valor BOOLEANO que retorna FALSO si la mas reciente instrucción SQL

no afectó ninguna fila de datos

SQL%HISOPEEN Siempre evalúa en FALSO debido a que PL/SQL cierra implícitamente los

cursores inmediatamente después que son ejecutados

Los atributos de cursores permiten evaluar que pasó en el último cursor implícito utilizado,

estos atributos pueden utilizarse en instrucciones PL/SQL pero no pueden ser utilizados en

instrucciones SQL. Se puede utilizar estos atributos en la sección de excepciones de un bloque para

conocer el resultado de la ejecución de una instrucción de manipulación de datos y tomar las

acciones necesarias como emitir mensajes de número de registros afectados.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 52

El siguiente ejemplo muestra un uso posible de los atributos de cursores:

VARIABLE filas_borradas VARCHAR2(20)

DECLARE

v_orden NUMBER := 605;

BEGIN

DELETE FROM item

WHERE num_orden = v_orden;

:filas_borradas := ‘ Se eliminaron : ‘||

to_char(SQL%ROWCOUNT)|| ‘ filas’;

END;

/

PRINT filas_borradas

Los cursores como se indicó anteriormente son áreas de memoria que contienen filas de datos

de una sentencia SQL durante la ejecución, existen dos tipos de cursores:

CURSORES IMPLÍCITOS

Creados y controlados totalmente por el manejador. Se crean cursores implícitos al ejecutar

cualquier sentencia de manipulación de datos, estas son SELECT, INSERT, UPDATE y DELETE

Cursores explícitos

Creados y manejados totalmente por el programador. Los cursores creados explícitamente, se

crean utilizando la sentencia SELECT para leer múltiples registros y dejarlos en un área de

memoria identificada con el nombre del cursor. Usando el identificador del cursor los registros

pueden ser recuperados y procesados secuencialmente.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 53

DIFERE�CIAS E�TRE CURSORES EXPLÍCITOS E IMPLÍCITOS

Cursor explícito Cursor implícito

Requieren ser declarados No requieren ser declarados

Requieren ser abiertos y cerrados El cursor se abre y se cierra automáticamente

CURSORES E� PL/SQL

Los cursores en PL/SQL son cursores explícitos, para crear y manipular este tipo de cursores

se deben tener en cuenta varios aspectos, tomando en cuenta que el control de estos es

responsabilidad del programador:

Sintaxis: DECLARE

CURSOR nombre_del_cursor IS sentencia select;

Para poder utilizar correctamente un cursor explícito, debe seguir los siguientes pasos:

Paso 1: Declarar el cursor

Paso 2: Abrir el cursor, para ello se utiliza la instrucción OPEN seguida del nombre del

cursor

OPEN nombre_del_cursor

Paso 3: Recuperar los datos en secuencia, para esto se utiliza la cláusula FETCH. Esta

cláusula permite la recuperación de los registros uno a uno en secuencia

FETCH nombre_del_cursor I�TO variable1, variable2... ;

En este caso la cláusula INTO funciona igual que cuando se utiliza para recuperar datos en

cualquier instrucción de SQL. La primera columna obtenida será asignada a la variable1, la segunda

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 54

a la variable2, y así sucesivamente. El orden de estas columnas está fijado por la sentencia

SELECT, al momento de la creación del cursor.

Paso 4: Cerrar el cursor, para ello se utiliza la cláusula CLOSE seguida del nombre del

cursor

CLOSE nombre_de_cursor;

El siguiente ejemplo muestra la declaración y utilización de un cursor explícito llamado

MICURSOR.

Ejemplo 3: Elabore un programa que permita obtener el nombre y el salario de todos

aquellos empleados que ganan mas de $12.000, e insertar estos en otra tabla llamada

TABLANUEVA

DECLARE SALARIOLIMITE NUMBER(4) := 12000; MINOMBRE EMPLEADO.NOMBRE%TYPE; MISALARIO EMPLEADO.SALARIO%TYPE; CURSOR MICURSOR IS -- Declaración del cursor Paso 1 SELECT NOMBRE, SALARIO FROM EMPLEADO WHERE SALARIO > SALARIOLIMITE; BEGIN OPEN MICURSOR; -- Apertura del cursor Paso 2 LOOP -- Recuperación de los datos Paso 3 FETCH MICURSOR INTO MINOMBRE, MISALARIO; EXIT WHEN MICURSOR%NOTFOUND; INSERT INTO TABLANUEVA VALUES (MINOMBRE, MISALARIO); END LOOP; CLOSE MICURSOR; -- Cierre del cursor COMMIT; END; /

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 55

ATRIBUTOS DE CURSORES EXPLICITOS

Atributo Tipo Descripción

%ISOPEN Booleano Evalúa TRUE si el cursor está abierto

%NOTFOUND Booleano Evalúa TRUE si el FETCH mas reciente no retornó ninguna fila

%FOUND Booleano Evalúa TRUE si el FETCH mas reciente retornó una fila

%ROWCOUNT Numérico Contiene el total de filas recuperadas por el cursor

CURSORES Y REGISTROS

Es posible manejar la recuperación de las filas de datos de un cursor usando un registro

PL/SQL como variable de salida. Ejemplo:

DECLARE

CURSOR empleados IS

SELECT empno, nombre

FROM empleado;

reg_empleado empleados%ROWTYPE;

...

FETCH empleados I�TO reg_empleado;

BUCLES FOR DE TIPO CURSOR

También se puede utilizar la instrucción FOR para declarar y utilizar un cursor sin que se

tenga que utilizar explícitamente las instrucciones de APERTURA, RECUPERACION DE

DATOS ni CIERRE del cursor, sino que la misma estructura se encarga de estas operaciones al

momento de su ejecución.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 56

Sintaxis : FOR nombre_del_registro I� nombre_del_cursor LOOP

sentencias que serán ejecutadas para cada fila retornada

END LOOP;

Donde:

Nombre del registro: contendrá cada fila de datos que sea recuperada, las columnas de datos

en el registro se pueden referenciar utilizando el nombre del registro seguido del nombre o alias de

la columna separados por un punto.

�ombre_del_registro.�ombre_de_la_columna

El funcionamiento de un bucle FOR de tipo cursor es el siguiente:

� Cuando el cursor de bucle es ejecutado, implícitamente se abre el cursor (OPE�).

� Cuando una fila satisface la consulta o query asociado al cursor, implícitamente se

ejecuta una búsqueda (FETCH).

� Cuando no hay más filas que satisfagan la búsqueda, implícitamente el cursor es

cerrado (CLOSE).

A continuación se muestra el mismo ejemplo XX para ilustrar el manejo de un cursor

utilizando el bucle FOR, en este ejemplo FILACURSOR es el registro de datos del cursor

MICURSOR

DECLARE SALARIOLIMITE NUMBER(5) := 12.000; TOTALSALARIO NUMBER(9,2) := 0; CURSOR MICURSOR IS SELECT NOMBRE, SALARIO FROM EMPLEADO WHERE SALARIO > SALARIOLIMITE; BEGIN FOR FILACURSOR IN MICURSOR LOOP

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 57

INSERT INTO TABLANUEVA VALUES (FILACURSOR.NOMBRE, FILACURSOR.SALARIO); TOTALSALARIO := TOTALSALARIO +

FILACURSOR.SALARIO; END LOOP; COMMIT; END; /

REAPERTURA DE U� CURSOR

Esta técnica se utiliza para reabrir un cursor con otros valores de inicialización.

El siguiente ejemplo muestra la reapertura de un cursor con un nuevo valor de la variable

SALARIOMIN

DECLARE BONOTOTAL NUMBER(8,2) := 0; SALARIOMIN EMPLEADO.SALARIO%TYPE :=

1000; BONOAUMENTO EMPLEADO.SALARIO%TYPE; CURSOR BONO IS SELECT SALARIO * .10 FROM EMPLEADO WHERE SALARIO > SALARIOMIN; BEGIN OPEN BONO; LOOP FETCH BONO INTO BONOAUMENTO; EXIT WHEN BONO%NOTFOUND; BONOTOTAL := BONOTOTAL + BONOAUMENTO; IF BONOTOTAL > 2000 THEN CLOSE BONO; SALARIOMIN := SALARIOMIN + 500; BONOTOTAL := 0; -- Reapertura del cursor, pero con un nuevo -- valor de SALARIOMIN OPEN BONO;

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 58

END IF; . . . . . . . . . . . . . . . . END LOOP; END; /

CURSOR FOR USADO COMO SUB-QUERIES

En este caso no es necesario declarar el cursor. Ejemplo:

BEGI�

FOR reg_empleado I� (SELECT empno, nombre

FROM empleado) LOOP

instrucciones;

E�D LOOP;

E�D;

DECLARACIÓ� DE U� CURSOR CO� PARÁMETROS

Los cursores pueden parametrizarse de manera que puedan ser abiertos y cerrados en

diferentes instantes de tiempo, con distintos valores que permiten variar la condición de

recuperación de los datos.

Sintaxis: DECLARE

CURSOR nombre_del_cursor [(nombre_del_parámetro tipo_del_parámetro)]

IS sentencia_select_realizando_la_consulta;

El siguiente ejemplo muestra la utilización de un cursor parametrizado, el cursor

MICURSOR es abierto 2 veces, la primera con sueldo 2000 y la segunda con sueldo 3000

DECLARE CURSOR MICURSOR (SUELDO NUMBER) IS SELECT NOMBRE FROM EMPLEADO

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 59

WHERE SALARIO > SUELDO; BEGIN OPEN MICURSOR (2000); . . . . . . . . . . . . . . . . (otras sentencias) . . . . . . . . OPEN MICURSOR (3000); END; /

En el siguiente ejemplo, se muestra la utilización del atributo de cursor SQL%NOTFOUND.

Se intenta modificar un registro en la tabla EMPLEADO y al no encontrarlo se inserta la

información en la tabla.

. . . . . . . . UPDATE EMPLEADO SET SALARIO = SALARIO*10.0 WHERE NOMBRE = 'JOSE'; IF SQL%NOTFOUND THEN --Si no existe el empleado se inserta. INSERT INTO EMPLEADO(CODIGO, NOMBRE,

SALARIO) VALUES (4332, 'JOSÉ', 10000); END IF; . . . . . . . .

CURSORES SELECT FOR UPDATE

A menudo, el procesamiento que se lleva a cabo en un bucle de extracción modifica las filas

extraídas por el cursor. PL/SQL proporciona una sintaxis conveniente para estas situaciones. El

método consta de dos partes: la cláusula FOR UPDATE en la declaración del cursos, y la cláusula

WHERE CURRENT OF en una orden UPDATE o DELETE.

FOR UPDATE

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 60

La cláusula FOR UPDATE es parte de una orden SELECT. Es la última cláusula de la orden,

después de la cláusula ORDER BY (si existe). La sintaxis es:

SELECT … FROM … FOR UPDATE [OF referencia_columna ] [NOWAIT]

Donde referencia_columna es una columna, o lista de columnas, de la tabla sobre la que se realiza

la consulta. Por ejemplo,

Al estar presente la cláusula FOR UPDATE en la sentencia SELECT , se ejecutan bloqueos

exclusivos sobre las filas del conjunto activo antes de que termine la ejecución de la orden OPEN

del cursor. Estos bloqueos evitan que otras sesiones cambien las filas del conjunto activo antes de

que la transacción se confirme. La orden NOWAIT hace que, si las filas están bloqueadas, con

anterioridad, por otra sesión, la orden OPEN termina inmediatamente devolviendo el error:

ORA-54: resource busy and acquire with NOWAIT specified.

WHERE CURRE�T OF

Si se declare el cursor con la cláusula FOR UPDATE, puede emplearse la cláusula WHERE

CURRENT OF en una orden UPDATE o DELETE. La sintaxis de esta cláusula es la siguiente:

WHERE CURRENT OF cursor

DECLARE CURSOR empleados IS SELECT empno, nombre, salario FROM empleado WHERE numdept = 01 FOR UPDATE NOWAIT;

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 61

Donde cursor es el nombre de un cursor declarado con una cláusula FOR UPDATE. La

cláusula WHERE CURRENT OF hace referencia a la fila recién extraída por el cursor.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 62

PRACTICA 3 1. Elaborar un programa que consulte todos los registros de la tabla VENDEDOR y calcule

las comisiones en base al 8% de las ventas, actualice las comisiones para todos los

vendedores

2. Elabore un programa que llene la tabla GRUPO_NUMERO con diez grupos de números

del 1 al 10, el resultado del programa debe ser como sigue:

GRUPO NUMERO

1 1

1 2

1 3

…. ….

1 10

2 1

2 2

… …

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 63

Capítulo 4

MA�EJO DE ERRORES

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 64

MA�EJO DE ERRORES E� PL/SQL

Los errores en PL/SQL son llamados excepciones. Cuando ocurre un error, el procesamiento

salta a la sección de EXCEPCIONES donde deben estar las instrucciones a ejecutarse en caso de

detectarse el error, si no existe el manejo de la excepción el manejador suspenderá la ejecución y

arrojará un mensaje indicando cual fue la condición que no fue tratada apropiadamente. Cuando el

manejo de la excepción es completado, el procesamiento del bloque termina.

Existen dos tipos de excepciones:

� Excepciones predefinidas

� Excepciones definidas por el usuario

EXCEPCIO�ES PREDEFI�IDAS

Las excepciones predefinidas son un grupo de errores posibles totalmente reconocidos por el

manejador. La tabla siguiente muestra algunas de las excepciones predefinidas más comunes:

Nombre de excepción Causa del error

TOO_MANY_ROWS La cláusula SELECT... INTO recuperó más de una fila

NO_DATA_FOUND La cláusula SELECT ... INTO no recupero ninguna fila

VALUE_ERROR Error en la conversión de un valor, u ocurrió un error de restricción

DUP_VAL_ON_INDEX Existe un valor duplicado en la columna de indexación

INVALID_CURSOR Especificación de cursor invalida

ZERO_DIVIDE Ocurrió una división por cero

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 65

MA�EJA�DO EXCEPCIO�ES

Como se indicó anteriormente, cuando ocurre una excepción el control de la ejecución salta

hasta la sección de excepciones, donde estarán las instrucciones de manejo de la condición de error

apropiadas.

Sintaxis: . . . . . . . . . .

EXCEPTIO�

WHE� nombre_de_la_excepción [OR nombre_de_la_excepción ... ] THE�

instrucciones_de_manejo_de_excepcion;

WHE� OTHERS THE�

secuencia_de_sentencias;

Donde:

EXCEPTION: indica el comienzo de la sección de manejo de excepciones.

WHEN: indica que a continuación se indicará el nombre de la excepción, además se

especificarán las acciones a tomar cuando ocurra esta condición.

WHEN OTHERS: es el conjunto de acciones que se ejecutaran en caso de ocurrir alguna

excepción no considerada en las declaraciones que la preceden

El siguiente ejemplo ilustra el manejo de la excepción predefinida TOO_MA�Y_ROWS y

�O_DATA_FOU�D

DECLARE SUELDO NUMBER; BEGIN SELECT SALARIO INTO SUELDO FROM EMPLEADO WHERE CODIGO = 2000; EXCEPTION WHEN TOO_MANY_ROWS OR NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20100,'No retorna filas o demasiadas filas

retornadas'); END; /

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 66

EL PRAGMA EXCEPTIO�_I�IT

Este pragma permite asociar una excepción nominada con un error ORACLE determinado,

lo que permite interceptar de forma específica dicho error, en lugar de a través de un gestor

OTHERS. El pragma EXCEPTION_INIT se emplea de la forma siguiente:

PRAGMA EXCEPTION_INIT (nombre_excepción, número_error_Oracle);

Donde nombre_excepción es el nombre de una excepción declarada con anterioridad al

pragma, y número_error_Oracle es el código de error que se desea asociar con esta excepción

nominada. Este pragma debe incluirse en la sección declarativa.

DECLARE E_EMPLEADOS EXCEPTION; PRAGMA EXCEPTION_INIT(E_EMPLEADOS,-2292); V_NUMDEP DEPARTAMENTO.NUMDEPT%TYPE = 1; BEGIN DELETE FROM DEPARTAMENTO WHERE NUMDEPT = V_NUMDEPT; COMMIT; EXCEPTION WHEN E_EMPLEADOS THEN DBMS_OUTPUT.PUT_LINE(‘NO SE PUEDE ‘||

‘BORRAR DEPARTAMENTO|| TO_CHAR(V_NUMDEP)); END;

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 67

EXCEPCIO�ES DEFI�IDAS POR EL USUARIO

Además de las excepciones predefinidas el usuario puede definir sus propias excepciones, y

obligar la ocurrencia de esa excepción, o de una predeterminada. Para definir una excepción propia

se debe declarar previamente la excepción de la siguiente manera:

Sintaxis: DECLARE

nombre_excepcion_propia EXCEPTIO�;

Una vez definida la excepción puede activarse, esto es hacer que el control salte hasta la

sección de excepciones en el punto donde la excepción aparece, utilizando la cláusula RAISE.

Sintaxis: RAISE nombre_excepcion;

La cláusula RAISE se puede utilizar para activar (levantar) una excepción tanto de usuario

como predefinida, sencillamente colocando el nombre de la excepción que se desea activar a

continuación de la cláusula RAISE.

El siguiente ejemplo ilustra la forma de declarar y activar una excepción de usuario, en este

se define la excepción AUMENTO y se activa la misma en caso de que el sueldo sea menor a 3000.

Al activarse la excepción el control va al manejo de la excepción y actualiza la tabla EMPLEADO

colocando el salario en 5000.

DECLARE SUELDO NUMBER; AUMENTO EXCEPTION; BEGIN SELECT SALARIO INTO SUELDO FROM EMPLEADO WHERE CODIGO = 2000; IF SUELDO < 3000 THEN RAISE AUMENTO;

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 68

EXCEPTION WHEN AUMENTO THEN UPDATE EMPLEADO SET SALARIO = 5000 WHERE CODIGO = 2000; COMMIT; END; /

La cláusula RAISE también puede usarse sin el nombre de la excepción, con la condición

que se utilice dentro del manejador de excepciones. La finalidad de realizar esto, es para reactivar la

excepción en curso.

Cuando una excepción ocurre, esta inmediatamente es buscada en el manejador de

excepciones del bloque en curso, en caso de no encontrarse, se busca en el manejador de

excepciones del próximo bloque, y así sucesivamente hasta encontrarse. Si no es encontrado un

manejador para la excepción ocurrida, esta, es pasada al ambiente que invoco a PL/SQL.

En algunos casos se hace necesario tener el control sobre excepciones, que no han sido

predefinidas por ORACLE.

Sintaxis para definir excepciones

PRAGMA EXCEPTION_INIT(definición_del_usuario, código_de_la_excepción);

DECLARE CODIGOERROR NUMBER; MENSAJEERROR CHAR(70); FORMATOFECHA EXCEPTION; PRAGMA EXCEPTION_INIT(FORMATOFECHA, -1858); BEGIN UPDATE EMPLEADO SET FECHACONTRATO = 'JAN-10-93' -- error en el formato de fecha

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 69

WHERE NUMEMP = 6659; EXCEPTION WHEN FORMATOFECHA THEN ROLLBACK; UPDATE EMP SET FECHACONTRATO = '10-JAN-93' WHERE NUMEMP = 6659; COMMIT; WHEN OTHERS THEN CODIGOERROR := SQLCODE; MENSAJEERROR := SQLERRM; INSERT INTO TABLAERRORES VALUES(CODIGOERROR, MENSAJEERROR);

RAISE_APPLICATION_ERROR(CODIGOERROR,MENSAJEERROR); END; /

La sentencia SQLCODE retorna el código de la excepción ocurrida y la sentencia

SQLERRM retorna el mensaje asociado a la excepción en curso. La instrucción

RAISE_APPLICATIO�_ERROR permite enviar códigos y mensajes de error.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 70

PRACTICA 4 1. Elaborar un programa que consulte los datos de un empleado, si el empleado no existe,

mostrar un mensaje que indique “El código de empleado X no Existe. Ingrese un código

valido”.

2. Elaborar un programa que ingrese un nuevo empleado, antes de insertar el registro debe

validad que el código de empleado no existe, si existe mostrar un error que indique, “El

código X ya esta asignado. Por favor utilice un nuevo código”.

3. Elaborar un programa para actualizar el salario de un empleado que el usuario introduzca,

antes de actualizar valide que el salario nuevo sea mayor al salario actual, de lo contrario

arroje un error que indica que no puede disminuir el salario del empleado.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 71

Capítulo 5

PROGRAMAS ALMACE�ADOS E� LA BASE DE DATOS

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 72

I�GE�IERIA DEL LE�GUAJE PL/SQL

I�GE�IERIA DE PL/SQL

Bloque de PL/SQL

DECLARE

Procedimiento

BEGIN

Procedimiento

Procedimiento

Procedimiento

SQL

SQL

END;

Ingeniería de PL/SQL

Procedimental

sentencias

Ejecutor

Ejecutor de sentencias SQL en el RDBMS de ORACLE

de

Bloque de PL/SQL

DECLARE

Procedimiento

BEGIN

Procedimiento

Procedimiento

Procedimiento

SQL

SQL

END;

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 73

I�GE�IERIA DE PL/SQL RESIDE�TE E� EL RDBMS

Bloque de PL/SQL

DECLARE

Procedimiento

BEGIN

Procedimiento

Procedimiento

Procedimiento

SQL

SQL

END;

Ingeniería de PL/SQL

Procedimental

sentencias

Ejecutor

Ejecutor de sentencias SQL

de

Bloque de PL/SQL

DECLARE

Procedimiento

BEGIN

Procedimiento

Procedimiento

Procedimiento

SQL

SQL

END;

ORACLE RDBMS

Programa anfitrión

Lenguaje anfitrión

Lenguaje anfitrión

Lenguaje anfitrión

Lenguaje anfitrión

Lenguaje anfitrión

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 74

PROCEDIMIE�TOS Y FU�CIO�ES ALMACE�ADAS

Un procedimiento almacenado o una función almacenada es un conjunto de instrucciones

de SQL y PL/SQL que se crean con la finalidad de realizar una tarea específica. Se almacenan en la

base de datos como un objeto y pueden ser invocados desde allí por cualquier programa que tenga

permisología de acceso sobre estos.

DIFERE�CIA E�TRE PROCEDIMIE�TO Y FU�CIO�

Procedimiento Función

Solo puede retornar valores mediante el uso

de parámetros

Retorna siempre un valor en el nombre de la

función

Se invocan solo con el nombre y operan

como si el código estuviera en el lugar donde se

llaman

Deben aparecer en algún lugar donde se

pueda almacenar el valor que retorna

CARACTERISTICAS DE PROCEDIMIE�TOS Y FU�CIO�ES

� Almacenamiento en forma compilada en la Base de Datos

� Pueden llamar a otros procedimientos/funciones o a sí mismo

� Pueden ser llamados desde todos los clientes del ambiente

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 75

USOS DE PROCEDIMIE�TOS Y FU�CIO�ES

• Permiten definir las reglas o funciones del negocio, por ejemplo, Crear una orden,

Eliminar un cliente.

• Encapsula una transacción, por ejemplo, recolecta y procesa información desde

nodos remotos

• Permiten crear programas con código genérico (compartido o común), por ejemplo,

Calculo del impuesto sobre la renta

• Los procedimientos y funciones son compilados en la Base de Datos al momento de

su creación. La forma y el texto compilado de un procedimiento o función son

almacenados en el diccionario de datos.

CREACIO� Y COMPILACIO� DE PROCEDIMIE�TOS Y FU�CIO�ES

Para crear un procedimiento o función almacenado, se utiliza la instrucción CREATE

PROCEDURE para que el nuevo código sea almacenarlo en la base de datos. Debido a que los

procedimientos y funciones son tratados como objetos de la base de datos, se puede utilizar la

cláusula REPLACE PROCEDURE para cambiar un procedimiento o función ya existente.

Sintaxis: CREATE OR REPLACE PROCEDURE esquema.�ombre_Procedimiento [( Argumento [IN] [OUT] [IN OUT] Tipo Dato )] IS Cuerpo de Programa PL/SQL AS /

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 76

Los argumentos pueden operar en tres modos, dependiendo del modo, el argumento se tratará

como un parámetro por valor o por referencia. La siguiente tabla muestra el tipo de argumento

posible para los parámetros en PL/SQL:

Modo Descripción

IN Parámetro por valor, no modifica los valores que recibe como parámetro. Es el modo

por defecto

OUT Parámetro de solo salida, no puede contener un valor de entrada al momento de llamar

al procedimiento o función

IN OUT Parámetro por referencia, puede contener valores de entrada al procedimiento y

cualquier modificación del parámetro dentro del procedimiento o función se reflejara en

el correspondiente parámetro externo

El siguiente ejemplo ilustra la forma de crear un procedimiento. Crear un procedimiento que

acepte un código de empleado como entrada y elimine el empleado de la tabla EMPLEADO.

CREATE PROCEDURE borra_empleado (

empid NUMBER) IS

BEGIN

DELETE

FROM empleado

WHERE empno = empid;

END;

/

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 77

El siguiente ejemplo ilustra la forma de crear una función. Crear una función que acepte

como entrada un número de cuenta contable y retorne el saldo del balance de la cuenta

CREATE FUNCTION obtener_saldo_bal (

cuenta NUMBER)

RETURN NUMBER

IS

saldo_cuenta NUMBER := 0;

BEGIN

SELECT balance

INTO saldo_cuenta

FROM cuentas

WHERE ncuenta = cuenta;

RETURN (saldo_cuenta);

END;

/

Nótese que en el ejemplo anterior existe la cláusula RETURN, que no aparece en el

procedimiento anterior, esta cláusula es la que permite retornar el valor de la función.

Instrucciones Válidas en Procedimientos y Funciones

� Instrucciones SQL, DML o PL/SQL

� Llamadas a procedimientos y funciones almacenadas en la Base de Datos

(incluyendo posibles llamadas recursivas)

� Llamadas a otros procedimientos y funciones en una Base de Datos remota.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 78

Instrucciones �o Validas en Procedimientos y Funciones

� Instrucciones DDL

� Instrucciones dinámicas de SQL

� Las instrucciones COMMIT, ROLLBACK y SAVEPOINT en procedimientos

llamados remotamente

EJECUCIO� DE PROCEDIMIE�TOS Y FU�CIO�ES ALMACE�ADOS

Dependiendo del lugar desde el cual se realiza la llamada al procedimiento, existen diferentes

formas de ejecutar un procedimiento almacenado. A continuación se listan las formas de invocar un

procedimiento almacenado:

� Desde un bloque PL/SQL sin el esquema de usuario propietario

� nombre_procedimiento(parámetros);

� Desde otro esquema de usuario: usuario.nombre_procedimiento(parámetros);

� Procedimiento almacenado en una base de datos remota:

usuario.nombre_procedimiento@enlace_remoto(parámetros);

� Desde alguna herramienta Oracle: EXECUTE nombre_procedimiento(parámetros);

� En bloques anónimos de PL/SQL, cuando el EXECUTE no esta disponible

BEGIN

nombre_procedimiento(parámetros);

END;

� Desde una aplicación precompilada:

EXEC SQL nombre_procedimiento(parámetros);

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 79

� Desde OCI

CALL OSQL3 (cursor, /*interpretador*/

"BEGIN

nombre_procedimiento(parámetros);

END;"

CALL OBNDRV (..);

CALL OEXEC (..);

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 80

COMPILACIO� DE ERRORES E� PL/SQL

ERRORES DE PL/SQL

La compilación de PL/SQL es ejecutada por la ingeniería de PL/SQL en ORACLE. Los

errores de sintaxis en la compilación se almacenan en el diccionario de datos, esto se debe a que

ORACLE puede recompilar un procedimiento automáticamente, y en consecuencia debe tener

algún lugar para colocar los posibles errores.

Para visualizar los errores generados por la compilación de un procedimiento o función

almacenada, se hace uso del comando SHOW ERRORS o bien se pueden consultar las vistas

USER_ERRORS, ALL_ERRORS o DBA_ERRORS

Para ilustrar el manejo de errores en PL/SQL trate de crear un procedimiento llamado TEST1

usando el código siguiente:

SQL> CREATE PROCEDURE test1 IS BEGIN test2; END;

A continuación muestre los errores de compilación, para ello use la instrucción SHOW

ERRORS

SQL> SHOW ERRORS

El resultado debe ser similar al siguiente:

LINE/COL ERROR

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

1/17 PLS-00103: Encountered the symbol "BEGIN" when expecting one of

the following:

( ; is with as compress compiled wrapped

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 81

The symbol "is" was substituted for "BEGIN" to continue.

Para recompilar un procedimiento o función, se debe borrar el objeto y luego recrearlo,

usando las sentencias DROP y CREATE, o simplemente reemplazar el código existente mediante

el uso de la cláusula CREATE OR REPLACE. También puede recompilarse un procedimiento

mediante la instrucción ALTER PROCEDURE, suponiendo, claro está, que el procedimiento

existe.

ERRORES DEFI�IDOS POR EL USUARIO

El usuario puede definir errores y puede hacer que al activarse el error se retorne el número y

el mensaje del error, los cuales previamente deben haber sido definidos por el usuario, para esto:

• Se debe definir el grupo de errores de aplicación

• Se sugiere estandarizar los números y mensajes de error a través de la creación de una tabla

en la Base de Datos, para mantener los errores y mensajes, y ejecutar un SELECT … INTO antes

de llamar al procedimiento

Sintaxis: RAISE_APPLICATIO�_ERROR (error_number, 'Texto del mensaje')

• El rango numérico entre -20000 a -20999, esta reservado en ORACLE para los errores

definidos por el usuario

• ORACLE no verifica que los errores definidos por el usuario sean únicos

Para ilustrar lo dicho anteriormente, consideremos el siguiente ejemplo.

Crear un procedimiento que active un mensaje de error definido por el usuario si la condición

que se indica no es encontrada.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 82

CREATE PROCEDURE analiza_num_emp (empid NUMBER)

AS

BEGIN

IF empid <= 0 THEN

raise_application_error(-20100, 'Numero de empleado debe ser > 0');

ELSE

DELETE

FROM empleado

WHERE empno = empid;

END IF;

END;

/

ELIMI�ACIO� DE PROCEDIMIE�TOS Y FU�CIO�ES

Al igual que las tablas, los procedimientos y funciones también pueden ser eliminados. La

sintaxis para eliminar un procedimiento es:

La sintaxis para eliminar una función es:

DROP PROCEDURE nombre_procedimiento;

DROP FUNCTION nombre_funcion;

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 83

PAQUETES

Un paquete es un objeto de la base de datos que agrupa construcciones de programas

relacionados en una sola unidad lógica. Un paquete contiene uno o más objetos almacenados en la

base de datos, los cuales están disponibles para el usuario en cualquier instante. El cuerpo del

paquete puede ser reemplazado sin afectar las especificaciones. Los paquetes pueden contener

objetos, tales como:

• Procedimientos

• Funciones

• Definiciones de Cursores

• Definiciones de Variables y Constantes

• Definiciones de Excepciones

ESTADO PERSISTE�TE

Los paquetes retienen el último estado válido de los objetos que contienen, mientras esté

activa la sesión del usuario que invoca al paquete o un objeto contenido en él, esto significa que:

� Las variables retienen los valores asignados y los cursores retienen las áreas de

contexto y posicionamiento de datos

� El estado persistirá a través de las llamadas que realice el usuario dentro de una

sesión

� Cada sesión tiene su propio control de versiones del estado del paquete

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 84

ESTRUCTURA DE U� PAQUETE

• Especificaciones del Paquete : Es el área declarativa de la construcción del paquete, en la

cual se indican los nombres y parámetros de los procedimientos y funciones públicas

disponibles, así como los nombres de las variables y cursores públicos

• Cuerpo del Paquete : Es el área de texto donde se coloca el código de los procedimientos y

funciones que el paquete contiene

Dentro del Cuerpo de un paquete se pueden especificar otros procedimientos y funciones

privadas, solo disponibles para las construcciones que están dentro del mismo paquete

• Definición del Código de todas las construcciones que integran el paquete

DEPE�DE�CIAS E�TRE PAQUETES

variable D

procedure A

procedure B

variable C

Procedure A

i := D;

j := C;

Package PK

PK.A;

x := PK.C;

Especificaciones

Cuerpo

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 85

• Si un procedimiento A llama a otro procedimiento B, y ninguno de los dos pertenece a un

paquete, entonces cualquier cambio que afecte al código del procedimiento B provocará que el

procedimiento A se marque automáticamente para ser recompilado

• Si un procedimiento individual A, llama a un procedimiento B que se encuentra dentro de

un paquete, entonces ningún cambio en el código del procedimiento B afectara al procedimiento A

• Si un procedimiento A de un paquete, llama a un Procedimiento B de otro paquete, ningún

cambio que tenga lugar en el código de cualquiera de los procedimientos generará dependencia de

recompilación en el otro

ESPECIFICACIO�ES PARA LA CREACIO� DE PAQUETES

Se deben especificar por separado, tanto la cabecera como el cuerpo del paquete. Para la

definición de la cabecera la sintaxis es la siguiente:

Sintaxis: CREATE OR REPLACE PACKAGE esquema.Nombre_del_Paquete [IS] [AS]

Especificaciones del Paquete;

/

Para la definición del cuerpo del paquete, la sintaxis es la siguiente:

CREATE OR REPLACE PACKAGE BODY esquema.Nombre_del_Paquete [IS] [AS]

Cuerpo de las Construcciones del Paquete;

Variables y Constantes;

/

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 86

A continuación se muestra un ejemplo que ilustra la forma de crear la cabecera de un

paquete.

CREATE PACKAGE paq_empleado AS /* declaraciones publicas */ PROCEDURE insertar_empleado( Empno NUMBER, Ename VARCHAR2, mgr NUMBER, sal NUMBER, comm NUMBER, deptno NUMBER); PROCEDURE borrar_empleado ( empid NUMBER ); /* variables globales */ valid VARCHAR2(1); END paq_empleado; /

El siguiente ejemplo ilustra la forma de crear el cuerpo del paquete definido anteriormente:

CREATE PACKAGE BODY paq_empleado AS /* Procedimiento de registro de empleados */ PROCEDURE insertar_empleado ( empno NUMBER, ename VARCHAR2, mgr NUMBER, sal NUMBER, comm NUMBER, deptno NUMBER) IS BEGIN Valid := chequea_num (empno); /* si el empleado no existe se podrá incluir */ IF valid = 'T' THEN INSERT INTO empleado (empno, ename, mgr, sal, comm, deptno) VALUES (empno, ename, mgr, sal, comm, deptno); END IF; END; /* Procedimiento de despido de empleado */ PROCEDURE borrar_empleado (empid NUMBER) IS BEGIN DELETE FROM empleado WHERE empno = empid; END; /* Función para chequear que el número de empleado es válido */

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 87

FUNCTION chequea_num (empno NUMBER) RETURN VARCHAR2 IS answer VARCHAR2; BEGIN answer := 'T'; IF empno < 0 THEN answer := 'F'; END IF; RETURN (answer); END; END paq_empleado; /* fin del cuerpo del paquete */ /

Como se dijo anteriormente, la compilación de un paquete se realiza al momento de crearlo,

sin embargo se puede realizar, también de manera manual haciendo uso de la cláusula ALTER:

Sintaxis: ALTER PACKAGE [esquema.]Nombre_del_Paquete COMPILE [BODY]

[PACKAGE]

Para eliminar un paquete, se utiliza la cláusula DROP, recuerde que un paquete es también

un objeto de la base de datos:

Sintaxis: DROP PACKAGE [esquema.]Nombre_del_Paquete;

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 88

PRACTICA 5 1. Crear un procedimiento con el nombre valida_no_existe_cliente, donde el empleado debe

recibir el código del cliente y consultar si existe, de ser así, retornar un error con el mensaje

“El código del cliente ya existe”

2. Crear una función llamada busca_direccion_cliente, que reciba el código del cliente y

retorne la dirección del mismo.

3. Crear una función llamada busca_descripcion_producto que reciba el código del producto y

retorne el nombre del mismo.

4. Crear un procedimiento para insertar un nuevo cliente, debe recibir los valores a insertar, y

antes de ejecutar el insert debe validar que el cliente no exista, para esto utilice el

procedimiento creado en el ejercicio 1.

5. Crear un procedimiento llamado maneja_error que le permita controlar los errores que

ocurren en el sistema, el procedimiento debe recibir el código del error, el mensaje y el

nombre del programa que lo origina, debe insertar estos valores en la tabla errores_sistema

junto con la fecha y hora en la que ocurrió el error, luego propagar el error.

6. Modifique los programas de los ejercicios 1 y 4 para que cuando ocurre un error cualquiera

que este sea, ejecuten el procedimiento 5.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 89

Capítulo 6

TRIGGERS DE BASE DE DATOS

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 90

TRIGGERS o DISPARADORES DE EVE�TOS

Los triggers son eventos que se activan automáticamente cuando en la base de datos ocurre el

evento al cual están asociados. Un trigger se asocia a un objeto que contiene datos modificables en

la base de datos, esto es una tabla o una vista, y se dispara cuando ocurre un cambio en el contenido

de ese objeto.

El uso de triggers confiere amplios beneficios al programador, pues le permiten realizar

múltiples labores de verificación de integridad, auditoria o manejo de posibles errores durante la

manipulación de datos almacenados en la base de datos.

Los triggers ayudan a lograr la integridad en aquellas bases de datos que requieren tablas

desnormalizadas, es decir copias de tablas grandes a tablas más pequeñas, técnica que se utiliza con

la finalidad de aumentar la velocidad de ejecución.

Los triggers permiten la creación de tablas de auditoria, con el fin de saber que registro,

usuario, columna, fecha, hora y datos fueron modificados durante una transacción. De esta manera

se podrá preservar tanto el dato antiguo como el dato nuevo en aquellos valores que son críticos.

Los triggers también son utilizados ampliamente en bases de datos distribuidas, para llevar

controles sobre la data, así como también llevar un control de las reglas del negocio.

Según el tipo de operación, asociados internamente a la base de datos existen tres tipos de

triggers:

� Triggers tipo Insert, los cuales se disparan al insertar filas

� Triggers tipo Update, los cuales se disparan al actualizar filas

� Triggers tipo Delete, los cuales se disparan al borrar filas

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 91

De acuerdo al momento en que se disparan en relación con el evento al cual están asociados,

los triggers pueden ser:

� Before, se disparan antes de que la acción se ejecute

� After, se disparan después que la acción se ha ejecutado

La siguiente tabla muestra las posibles combinaciones de activación de los triggers según el

tipo de trigger de que se trate y al instante de activación:

Instante de activación

Acción Before After

Insert Before Insert After Insert

Update Before Update After Update

Delete Before Delete After Delete

De acuerdo a la acción que genera su activación, los triggers pueden ser:

� Por transacción, se disparan cuando la transacción se ha completado

� Por fila, se disparan inmediatamente después de procesar una fila de datos

Un evento en la base de datos dispara uno o varios de los triggers definidos en la tabla

anterior, y cada una de estas combinaciones puede estar asociada a una transacción o a una fila, de

manera excluyente. Esto significa que existen un total de doce triggers asociados a las tablas o

vistas de la base de datos.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 92

RESTRICCIO�ES DE LOS TRIGGERS

Debido a que los triggers de base de datos pueden ser manejados por el usuario, pero el

control de las operaciones internas y de la modificación de los datos es responsabilidad única del

manejador, los triggers tienen ciertas restricciones, a continuación se listan algunas:

• No se pueden usar cláusulas de control de operación. Esto significa que desde un trigger

de base de datos no se puede realizar COMMIT, ni ROLLBACK ni tampoco SAVEPOINT.

Por lo tanto las transacciones deben ser terminadas por quien disparó un trigger y no por el

trigger en sí

• Los triggers de base de datos no pueden crearse sobre una instrucción SELECT, ni pueden

asociarse a instrucciones DDL, tales como son CREATE, ALTER o DROP

• Los triggers de base de datos no pueden asociarse a las tablas del Diccionario de Datos

• Los triggers de base de datos solo se activan cuando ocurre el evento al cual están

asociados, esto quiere decir que su activación no puede ser forzada por el usuario

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 93

DEFI�ICIO� Y CREACIO� DE TRIGGERS

Un trigger de Base de Datos definido por el usuario está formado por un bloque de PL/SQL

asociado a una tabla específica. Se dispara de manera implícita cuando se ejecuta la instrucción

asociada a la tabla.

Applicación Base de Datos

tabla T

UPDATE t

SET...;

INSERT

INTO t....;

DELETEFROM t...;

UPDATEtriger

DELETE

triger

triger

INSERT

A continuación se muestra un ejemplo de la secuencia de ejecución de un trigger de base de

datos

EMPLEADO DEPARTAMENTO

10

50

10

40

20

30

10

Antes del comando trigger

Antes del trigger de fila

Despues del trigger de fila

Antes del trigger de fila

Despues del trigger de fila

Antes del trigger de fila

Despues del trigger de fila

Despues del comando trigger

100

120

240

260

280

300

301

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 94

CREACIO� DE U� TRIGGER DE BASE DE DATOS

Un trigger de base de datos puede ser creado de manera similar a la creación de cualquier

otro objeto de la base de datos, para ello se hace uso de la cláusula CREATE TRIGGER.

Sintaxis: CREATE TRIGGER [esquema.]nombre_de _trigger [BEFORE | AFTER]

[DELETE | INSERT | UPDATE] [OR ] [OF] (columnas) ON [esquema.]tabla

REFERENCING [OLD | NEW] AS viejo | nuevo [FOR EACH ROW WHEN condición

bloque_pl/sql ];

/

Donde:

esquema: indica el entorno de usuario

nombre_de_trigger: indica el nombre con el cual se va a crear el trigger

columnas: indica las columnas de la tabla a las cuales va a estar asociado el trigger

tabla: indica el nombre de la tabla a la cual va a estar asociado el trigger

condición: restringe la activación del trigger a las filas que cumplen esta condición

bloque_pl/sql: contiene el bloque de instrucciones que conforman el cuerpo del

trigger

Los triggers de Base de Datos son almacenados separados de otros objetos, de manera que

un trigger de Base de Datos y una tabla pueden tener el mismo nombre, sin embargo es

recomendable la utilización de nombres únicos.

SECUE�CIA DE EJECUCIO� DE U� TRIGGER DE BASE DE DATOS

1. La instrucción INSERT, UPDATE o DELETE pasa al manejador ORACLE

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 95

2. El manejador chequea y ejecuta el trigger de comando BEFORE

3. Por cada fila afectada por el comando SQL :

4. Se ejecuta el trigger de fila BEFORE

5. Se modifica la fila y se chequean las restricciones de integridad

6. Se ejecuta el trigger de fila AFTER

7. Se complementa la validación de las restricciones de integridad chequeando las

posibles violaciones

8. Se ejecuta el trigger de comando AFTER

9. El control regresa a la aplicación. Si un trigger de comando de Base de Datos falla,

los cambios hechos por el trigger de comando se reversan.

Se pueden tener procedimientos almacenados referenciados en el texto del trigger, siempre y

cuando estos no hagan COMMIT ni violen las restricciones expresas para los triggers.

Para referenciar los valores nuevos o viejos de una columna en expresiones de trigger de fila

se utilizan los prefijos:

:OLD contiene el valor de la columna antes de efectuar el cambio

:NEW contiene el valor que afectará a la columna después de efectuar el cambio

Ejemplo

IF :NEW.salario < :OLD.salario ......

La expresión :NEW.salario contiene el nuevo valor de la columna salario antes de efectuarse

el cambio y la expresión :OLD.salario contiene el valor antiguo de la columna salario.

Al tratar de referenciar los valores :NEW y :OLD se deben tener en cuenta las siguientes

consideraciones:

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 96

• Los valores NEW y OLD están disponibles únicamente en los triggers de fila

• Los valores NEW y OLD están disponibles en el UPDATE

• El valor OLD en un INSERT es nulo

• El trigger de fila BEFORE puede asignar valores a :NEW si no es asignado el valor por la

cláusula UPDATE SET o lista INSERT VALUES

• Se puede usar la cláusula REFERENCING para remplazar :NEW y :OLD con otros

nombres relacionados

• Los dos puntos no son necesarios al referenciar en la cláusula WHEN

Si el trigger de Base de Datos se puede disparar sobre más de un tipo de operaciones DML,

se puede usar el predicado condicional para determinar la operación del DML que ocasiona el

disparo del trigger de Base de Datos.

Predicados Condicionales

• IF INSERT ...

• IF UPDATING ....

• IF DELETING .....

Se puede tener el mismo trigger en la Base de Datos para un DELETE, INSERT y UPDATE,

y usar el predicado condicional para determinar qué ocasionó que se disparase el trigger de Base de

Datos. Esto resulta más fácil que mantener tres triggers por separados. Esto siempre y cuando los

procedimientos no contengan cláusulas de control de operaciones, tales como COMMIT.

El siguiente ejemplo muestra la forma de crear un trigger, haciendo uso de los valores NEW,

OLD y de los predicados condicionales.

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 97

CREATE TRIGGER salario_total

AFTER DELETE OR INSERT OR UPDATE OF departamento, salario

ON empleado

FOR EACH ROW

BEGIN

/* se asume departamento,salario como no nulos */

IF DELETING OR

(UPDATING AND

:OLD.departamento <> :NEW.departamento) THEN

UPDATE departamento_renta /* separa las tablas que referencian a

departamento */

SET total_salario =total_salario - :OLD.salario

WHERE departamento = :OLD.departamento;

END IF;

IF INSERTING OR

UPDATING AND

(:OLD.departamento = :NEW.departamento) AND

(:OLD.salario <> :NEW.salario) THEN

UPDATE departamento_compras

SET total_salario = total_salario + (:NEW.salario -

:OLD.salario)

WHERE departamento = :OLD.departamento;

END IF;

END;

/

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 98

En el caso anterior la opción AFTER DELETE OR INSERT OR UPDATE, indica que el

trigger se disparará después de culminar la acción de inserción o actualización. La opción FOR

EACH ROW indica que el trigger se activará una vez por cada fila de datos que sea procesada.

Antes de la ejecución de cualquier instrucción de actualización sobre la columna SALARIOS

de la tabla NOMINA o la inserción de un nuevo registro, provocará que el trigger definido

anteriormente se active, ejecutando las instrucciones del bloque PL/SQL que conforman el cuerpo

del trigger.

ELIMI�A�DO U� TRIGGER DE BASE DE DATOS

Debido a que un trigger es también un objeto de Base de Datos, para borrar un trigger se

utiliza la cláusula DROP.

Sintaxis: DROP TRIGGER esquema.nombre_trigger;

La siguiente instrucción permite la eliminación del trigger creado anteriormente:

DROP TRIGGER tr_upd_salario;

Para la creación y manipulación de triggers se deben tener en cuenta las siguientes

consideraciones:

Los triggers de Base de Datos no pueden ser alterados, para modificar un trigger

este debe ser eliminado y recreado

La eliminación de un trigger no afecta los privilegios de seguridad existente

asociados a una tabla

Si una tabla es eliminada, los triggers definidos sobre ella también serán eliminados

G E D I C A T R A I N I N G & C O N S U L T I N G C . A .

Lenguaje Procedimental PL/SQL/ 99

PRACTICA 6 1. Elabore un trigger sobre la tabla empleado, para controlar que cuando se ejecute una

actualización de los salarios, el salario nuevo sea siempre mayor al salario actual, pero no

debe ser mayor a 1.000.000 de lo contrario arroja mensajes de error por cada caso. Y

controlar estos a través del procedimiento mensaje_error.

2. Elabore un trigger sobre la tabla empleado para controlar que cuando si inserte un nuevo

empleado, el nombre se inserte en mayúscula, y si la fecha de ingreso no es colocada

entonces se asigne la fecha actual. Adicionalmente si el nuevo empleado pertenece al

departamento de investigación u operaciones insertar los registros en las tablas

emp_investigacion y emp_operaciones.

3. Elabore un trigger sobre la tabla empleado que le permita guardar en la tabla

control_registros si ocurre un evento de actualización o eliminación. En dicha tabla debe

guardarse la fecha en que ocurrió el evento, el usuario que lo ejecuto, y si se trata de una

actualización el valor viejo del campo modificado y el valor nuevo, además del campo

clave del registro que se actualizo, es decir, el código del empleado, si lo que ocurre es una

eliminación guardar el campo clave del registro eliminado.