Sie sind auf Seite 1von 39

01/10/2010

EVALUACIÓN

OBJETIVO:
Otorgar al alumno los conocimientos necesarios para comprender las
funcionalidades y ventajas que ofrece el lenguaje procedural de Oracle
llamado PL/SQL. Bases que permitirán al alumno prepararse para obtener
la certificación Oracle 1z0-147: Oracle 9i. Programación con PL/SQL.
Oracle 9i. Programación
con PL/SQL
1 Tarea ….………............(10 %)
Proyecto ………..……….(55 %)
Octubre de 2010
1 Examen ..….….………...(35 %)

© LANIA
01/10/20
A.C.
2
10
Rébsamen 80 Xalapa, Veracruz 91000, México T. (52) (228) 841.61.01 | LANIA A.C. | Todos los derechos reservados

EVALUACIÓN
PROYECTO:
• Construir una aplicación web para la compra-venta de modelos clásicos
de transporte a escala.

• Se tiene la base de datos, construirla a través de procedimientos •Descripción de un programa


almacenados. en PL/SQL
• Recurrir a todos los elementos vistos en clase: paquetes, procedimientos, • Bloques Introducción a PL/SQL
funciones, vistas, triggers. El sistema al final será expuesto por cada • Sección declarativa
• Sección ejecutable
persona.

© LANIA
01/10/20
A.C.
3
10
Rébsamen 80 Xalapa, Veracruz 91000, México T. (52) (228) 841.61.01 | LANIA A.C. | Todos los derechos reservados

1
01/10/2010

SQL vs PL/SQL PL/SQL


Es un lenguaje procedural que extiende SQL con diversos elementos
ELEMENTOS

• Variables, constantes y tipos


• Estructura de Bloques (modular)
• Estructuras de control de flujo
• Manejo de excepciones.
• Datos estructurados

5 6

PL/SQL: Ventajas Arquitectura Cliente-Servidor en PL/SQL

• Capacidad procedural. Soporta tipo de datos boolean,


secuencias, arreglos y subprogramas.
• Es el lenguaje procedural principal para herramientas del
lado del cliente como Oracle Forms, Oracle Reports.

• Portable. Son independientes del hardware y sistema


operativo. Son altamente portables y trabajan bien en
cualquier plataforma donde Oracle server esté instalado.

• Modularidad. Permite escribir programas como módulos


independientes que pueden ser integrados en diversas
aplicaciones. Tomado de: Oracle PL/SQL by Example

7 8

2
01/10/2010

PL/SQL Delimitadores
El código en PL/SQL puede contener: delimitadores, Tipo de operador Operadores
identificadores, literales, comentarios Operador de asignación := (dos puntos + igual)
Operadores aritméticos + (suma)
Unidades Descripción - (resta)
Delimitador Símbolo simple o compuesto con un fin específico, * (multiplicación)
representado por operadores aritméticos, lógicos o / (división)
relacionales ** (exponente)
Comentario Existen dos tipos, de línea simple y multilínea. Operadores relacionales o de comparación = (igual a)
<> (distinto de)
Identificador Permite nombrar objetos o unidades de programas: < (menor que)
constantes, cursores, variables, subprogramas, > (mayor que)
excepciones, paquetes. PL/SQL no es CASE- >= (mayor o igual a)
SENSITIVE <= (menor o igual a)
Operadores lógicos AND (y lógico)
Literal Valor de tipo número, carácter, cadena o lógico con un NOT (negacion)
valor explícito OR (o lógico)
Operador de concatenación ||
9 10

Comentarios Identificadores
Un identificador consiste de una letra seguida opcionalmente de:
-- Esto es un comentario de una sola línea A..Z, 0..9, _, #, $

Caracteres tales como: &, - , / , espacios y palabras reservadas NO


son permitidos

No debe exceder de 30 caracteres

DECLARE
v_lastname VARCHAR2(30); -- válido
/* v_last_name VARCHAR2(30); -- válido, _ permitido
Esto es un comentario de varias líneas v_last$name VARCHAR2(30); -- válido, $ permitido
*/ v_last#name VARCHAR2(30); -- válido, # permitido
-- v_last-name no válido
-- v_last/name no válido
-- v_last name no válido
-- V_LASTNAME no válido, es igual que v_lastname
-- v_LastName no válido, es igual que v_lastname y V_LASTNAME

11 12

3
01/10/2010

Bloques en PL/SQL Bloques en PL/SQL


Bloque es la unidad de estructura básica en los programas
PL/SQL.

Envía los bloques completos de instrucciones al servidor para ser


procesados en lugar de enviar cada secuencia SQL.
1 Sección [DECLARATIVA]

2 Sección EJECUTABLE

13
B C 3 14
Sección de
Manejo de [EXCEPCIONES]

Bloques en PL/SQL Sección Declarativa


-- Sección declarativa (OPCIONAL)
nombre_variable [CONSTANT] tipo [NOT NULL] [:= valor_inicial];
DECLARE [DEFAULT]
pay_per_day NUMBER(6,2);

-- Sección ejecutable
identif%TYPE
BEGIN
tipo identif%ROWTYPE
pay_per_day := 21/8;
tipo_escalar NUMBER
DBMS_OUTPUT.PUT_LINE('The pay per day is ' || DATE
TO_CHAR(number_of_days_worked)); CHAR TRUE
VARCHAR FALSE
BOOLEAN NULL
-- Sección de manejo de excepciones(OPCIONAL)
EXCEPTION
WHEN ZERO_DIVIDE THEN
pay_per_day := 0; [CONSTANT] indica la definición de una constante cuyo valor es fijo.
[NOT NULL] impide que a una variable se le asigne un valor nulo.
END; [:=valor_inicial] debe ser del mismo tipo del identificador definido.
[DEFAULT] Inicializa el valor de una variable.
15 16

4
01/10/2010

Sección Declarativa Sección Declarativa


Se declaran todos los tipos de datos, cursores, constantes y
variables utilizadas en la sección de ejecución. Las variables
que no son inicializadas toman el valor inicial NULL. SELECT * INTO emp_rec
FROM EMPLOYEES
DECLARE WHERE employee_id = 120;
v_location VARCHAR2(15) := ’Granada’
v_pay_per_day NUMBER(6,2);

c_comm CONSTANT NUMBER(3) := 160; SELECT last_name INTO emp_name


v_avg_days_worked_month NUMBER(2) NOT NULL := 21; FROM EMPLOYEES
WHERE employee_id = 120;
v_date DATE:= ’11-AUG-2008’;
v_time1 TIMESTAMP:= ’11-AUG-2008 11:10:00 PM’
v_days_worked_month NUMBER(2) DEFAULT 20;

v_nombre tabla_empleados.nombre%TYPE;
v_emp_name employees.last_name%TYPE;
17
v_emp_rec employees%ROWTYPE; 18

Sección Declarativa Sección Ejecutable


ESTRUCTURAS DE DATOS ESTRUCTURAS DE CONTROL

Son tipos de datos compuestos.


IF-THEN-ELSE
DECLARE IF-THEN-ELSIF-ELSE
TYPE t_location IS RECORD ( CASE
room_number NUMBER(4),
building VARCHAR2(25) LOOP
);
WHILE-LOOP
TYPE t_person_rec IS RECORD ( FOR - LOOP
employee_id employees.employee_id%TYPE,
first_name employees.first_name%TYPE,
last_name employees.last_name%TYPE,
location location_rec
);
person t_person_rec;
19 20

5
01/10/2010

Estructuras de Control Estructuras de Control


IF- THEN - ELSE CASE

IF condition THEN
CASE selector
statements;
WHEN exp1 THEN result1
[ELSIF condition THEN
WHEN exp2 THEN result2
statements;]

[ELSE
[ELSE result;]
statements;]
END;
END IF;
v_exp_grade:=
CASE v_grade
IF UPPER (v_last_name) = ‘GIETZ’ THEN WHEN ‘A’ THEN ‘Excellent’
v_mgr:=102; WHEN ‘B’ THEN ‘Very Good’
ELSE WHEN ‘C’ THEN ‘Good’
v_mgr:=1; ELSE ‘No such grade’
END IF; END;

21 22

Estructuras de Control Estructuras de Control


LOOP WHILE LOOPS

LOOP WHILE condition LOOP


statement1; statement1;
… …
exit [WHEN condition]; END LOOP;
END LOOP;

WHILE v_counter <= 3 LOOP


INSERT INTO locations(location_id, city, country_id)
LOOP VALUES ((v_location_id + v_counter), v_city, v_country_id);
INSERT INTO locations(location_id, city, country_id) VALUES v_counter:= v_counter + 1;
((v_location_id + v_counter), v_city, v_country_id); END LOOP;
v_counter:= v_counter + 1;
EXIT WHEN v_counter > 3;
END LOOP;

23 24

6
01/10/2010

Estructuras de Control Cursores en PL/SQL


FOR LOOPS
Los cursores le permiten al programador recuperar los datos de
una tabla y realizar acciones en esos datos una fila a la vez.
Existen dos tipos de cursores.
FOR counter IN [REVERSE]
lower_bound..upper_bound LOOP
statement1;
• Cursores implícitos
statement2;

END LOOP;
• Cursores explícitos

FOR I IN 1..3 LOOP


INSERT INTO locations(location_id, city, country_id) VALUES
((v_location_id + i), v_city, v_country_id);
END LOOP;

25

Cursores en PL/SQL Cursores Implícitos en PL/SQL


Cada vez que ejecutamos una sentencia SQL, esta es asignada a Se utilizan para realizar consultas SELECT que devuelven un único
una localidad de memoria, la cual es llamada área de contexto ó registro.
cursor.
• Deben ser escritos en el bloque BEGIN.

Cuando se declara un cursor, lo que se obtiene es una variable • Con cada cursor implícito debe existir la palabra clave INTO.
puntero, el cual inicialmente no apunta a nada.
• Las variables que reciben los datos devueltos por el cursor tienen
que contener el mismo tipo de dato que las columnas de la tabla.
Cuando el cursor es abierto, la memoria es asignada y la estructura
del cursor es creada. La variable cursor ahora apunta al cursor. • Los cursores implícitos solo pueden devolver una única fila.

Cuando el cursor es cerrado la memoria asignada para el cursor es


liberada.

7
01/10/2010

Cursores Implícitos en PL/SQL Cursores Implícitos en PL/SQL


En caso de que se devuelva más de una fila (o ninguna fila) se
producirá una excepción.
SELECT * INTO emp_rec
FROM EMPLOYEES Las más comunes que se pueden encontrar son NO_DATA_FOUND y
WHERE employee_id = 120; TOO_MANY_ROWS.

La siguiente tabla explica brevemente estas excepciones.


SELECT last_name INTO emp_name
FROM EMPLOYEES Excepción Explicación
WHERE employee_id = 120;
NO_DATA_FOUND Se produce cuando una sentencia SELECT
intenta recuperar datos pero ninguna fila
satisface sus condiciones. Es decir, cuando
"no hay datos"
TOO_MANY_ROWS Detecta la existencia de más de una fila al
realizar una consulta.
29

Cursores Explícitos en PL/SQL Cursores Explícitos en PL/SQL


Se emplean para realizar consultas SELECT que pueden devolver
cero filas, o más de una fila Para abrir el cursor:
OPEN nombre_cursor;
CURSOR nombre_cursor IS instrucción_SELECT
Con parámetros:
Si queremos utilizar parámetros en el cursor: OPEN nombre_cursor(valor1, valor2, ..., valorN);
CURSOR nombre_cursor(param1 tipo1, ..., paramN tipoN) IS Para recuperar los datos en variables PL/SQL.
instrucción_SELECT
FETCH nombre_cursor INTO lista_variables

DECLARE Para cerrar el cursor:


CURSOR emp_cur IS CLOSE nombre_cursor;
SELECT ename FROM EMP;
BEGIN
----
END;
/

8
01/10/2010

Cursores Explícitos en PL/SQL Cursores Explícitos en PL/SQL


Abriendo Cursor Abriendo Cursor
Ejemplo:
Se puede simplificar utilizando el atributo de tipo %ROWTYPE sobre
el cursor, en vez de utilizar variables independientes.
Ejemplo:

DECLARE
CURSOR cpaises (p_continente VARCHAR2)
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES
WHERE CONTINENTE = p_continente;
registro cpaises%ROWTYPE;
BEGIN
OPEN cpaises('EUROPA');
FETCH cpaises INTO registro;
CLOSE cpaises;
END;

Cursores Explícitos en PL/SQL Cursores Explícitos en PL/SQL


Cada cursor definido por el usuario tiene 4 atributos. Estos le Cursores usando ciclos
permiten al usuario acceder a cierta información en tiempo de
Por medio de un ciclo LOOP podemos iterar a través del
ejecución.
cursor. Debe tenerse cuidado de agregar una condición para
salir del bucle:
1. %NOTFOUND: Atributo booleano que es verdadero si la
última búsqueda falla es decir cuando ya no queda ninguna
Bucle LOOP con una sentencia EXIT condicionada:
fila en el cursor.

2. %FOUND: Atributo booleano que es verdadero si la última


búsqueda fue exitosa.

3. %ROWCOUNT: Atributo numérico, el cual regresa el número


de filas almacenadas en el cursor.

4. %ISOPEN: Atributo booleano que es verdadero si el cursor se


encuentra abierto de otra forma devuelve falso.

9
01/10/2010

Cursores Explícitos en PL/SQL Cursores Explícitos en PL/SQL


Cursores usando ciclos Cursores usando ciclos
Bucle WHILE LOOP. La instrucción FECTH aparece dos veces
El cursor FOR LOOP puede ser usado para procesar múltiples
para habilitar el atributo %FOUND.
registros.

1. Implícitamente se declara una variable %ROWTYPE, el cual es usado


como LOOP index.

2. Un cursor For Loop abre asimismo un cursor, lee los registros y


después cierra el cursor automáticamente. De tal manera que ya
no son necesarios las sentencias OPEN, FETCH y CLOSE.

Bloques en PL/SQL Bloques anónimos en PL/SQL


 Anónimos  Subprogramas No tienen nombre

Comienzan con DECLARE o directamente con BEGIN

BEGIN
DBMS_OUTPUT.PUT_LINE (‘Hola’);
END; /

DECLARE fecha date;


BEGIN
select sysdate into fecha
from dual;
dbms_output.put_line (to_char(fecha,
'day", "dd" de "month" de "yyyy", a las
"hh24:mi:ss'));
END;
/
39 40

10
01/10/2010

PRÁCTICA!!
Subtemas
 Subprogramas
 Invocación de
procedimientos/funciones
Definición y creación de
procedimientos almacenados Procedimientos Almacenados

 Parámetros (Stored Procedures)


 Propagación de excepciones
 Borrado de procedimientos

42

41
Rébsamen 80 Xalapa, Veracruz 91000, México T. (52) (228) 841.61.01 | LANIA A.C. | Todos los derechos reservados

Bloques en PL/SQL Subprogramas en PL/SQL

Subprogramas Promueven la reusabilidad y mantenimiento


Se les asigna un nombre significativo
Mejoran el desempeño
Pueden tomar parámetros y ser invocados
Pueden ser compilados y almacenados en la base de datos Mejoran la seguridad e integridad de los datos

Mejoran la claridad del código


<header> Especificación
IS | AS
-- Sección declarativa
BEGIN
-- Sección ejecutable
EXCEPTION
-- Sección de manejo de Cuerpo
excepciones(OPCIONAL)
END;
43 44

11
01/10/2010

Subprogramas en PL/SQL Invocando Funciones y Procedimientos


Tipos

iSQL *Plus EXECUTE log_execution


• Procedimientos en PL/SQL. Ejecuta una acción especifica y Herramientas de
no devuelve ningún valor. Puede recibir parámetros. desarrollo de Oracle tales
log_execution;
como Oracle Forms o
Reports
• Funciones en PL/SQL. Una función es un bloque de código
PL/SQL que devuelve un valor. Puede recibir parámetros. Desde otro procedimiento CREATE OR REPLACE PROCEDURE
leave_emp (id IN
employees.employee_id&TYPE) IS
• Subprogramas en bloques anónimos BEGIN
DELETE FROM employees
WHERE employee_id=id:
log_execution;
END leave_emp;

45 46

Procedimiento almacenado Procedimiento almacenado


Puede ser compilado y almacenado en la base de datos
Ejecuta una acción específica y no regresa valor alguno.
Puede recibir parámetros
Promueven la reusabilidad y mantenimiento
Se debe tener el privilegio CREATE PROCEDURE ó CREATE
ANY PROCEDURE (para crear el procedimiento en otro
esquema).

 Es un subprograma almacenado que desempeña una


acción específica, el cual puede ser llamado usando el
47 nombre que se le haya asignado. 48

12
01/10/2010

Sintaxis de un procedimiento Sintaxis de un procedimiento


[CREATE [OR REPLACE]]
Además de las
1 CREATE PROCEDURE procedure_name[(parameter[, parameter]...)] PROCEDURE procedure_name[(parameter[, parameter]...)]
{ IS | AS} secciones de un [AUTHID {DEFINER | CURRENT_USER}] { IS | AS}
2 [local declarations] bloque, [local declarations]
BEGIN No contiene un BEGIN
3 executable statementscontiene
executable statements
[EXCEPTION] ENCABEZADO
4 exception handlers la cláusula [EXCEPTION]
END [name]; DECLARE exception handlers
-- Sección declarativa (OPCIONAL)
END [name];
1 [DECLARE]
pay_per_day NUMBER(6,2);
parameter _name [IN | OUT [NOCOPY] | IN OUT [NOCOPY]] datatype
-- Sección ejecutable [{:= | DEFAULT} expression]
BEGIN
2 pay_per_day := 21/8;

Al menos DBMS_OUTPUT.PUT_LINE('The pay per day is ' ||


TO_CHAR(number_of_days_worked)); [AUTHID] Determina si un procedimiento es ejecutado con el privilegio del
debe existir propietario o del usuario actual.
una -- Sección de manejo de excepciones(OPCIONAL)
[EXCEPTION]
instrucción 3 WHEN ZERO_DIVIDE THEN
pay_per_day := 0;

49 END;
Bloque anónimo 50

Parámetros de un procedimiento Parámetros de un procedimiento


No se puede restringir el tamaño del tipo de dato de un parámetro. Los procedimientos que no tienen parámetros son escritos sin
paréntesis:
Esto es:
PROCEDURE desplegarMensaje IS …
PROCEDURE desplegar(mensaje CHAR(5)) IS …

Parámetros actuales: Variables o expresiones referenciadas en la


lista de parámetros de la llamada de un subprograma.
calcular_salario (num_emp, s_juan + s_luis)
DECLARE
SUBTYPE st_char5 IS CHAR(5); Parámetros formales: Variables declaradas en la especificación
PROCEDURE desplegar (mensaje st_char5) IS … de un subprograma y referenciadas en el cuerpo del
subprograma.
PROCEDURE calcular_salario (num_emp INTEGER, salario REAL) IS
BEGIN

Parámetros = Argumentos UPDATE emp SET sal= sal+salario WHERE numemp=num_emp;


END calcular_salario;
51 52

13
01/10/2010

Modos de un parámetro Modos de parámetros


Entrada Salida Entrada/Salida
Procedimiento IN OUT IN OUT
Parámetro IN Valor default Tiene que ser especificado Tiene que ser especificado
entorno Pasa valores a un subprograma Pasa un valor inicial a un
de llamada Parámetro OUT Regresa un valor a quien invocó el subprograma y regresa valores
subprograma actualizados a quien invocó el
Parámetro IN OUT subprograma
Parámetros formales actúan como Parámetros formales actúan como Parámetros formales actúan como
una constante una variable una variable inicializada
(DECLARE)
Al parámetro formal NO se le
puede asignar un valor El parámetro formal debe tener El parámetro formal podría tener
BEGIN asignado un valor asignado un valor

El parámetro actual puede ser una


El parámetro actual tiene que ser una El parámetro actual tiene que ser
constante, variable inicializada,
(EXCEPTION) literal o expresión
variable una variable

El parámetro actual es pasado por El parámetro actual es pasado por El parámetro actual es pasado por
END; referencia (un apuntador al valor) valor (una copia del valor es pasado valor (una copia del valor es pasado
fuera) a menos que sea especificado dentro y fuera) a menos que sea
NOCOPY especificado NOCOPY
53 54

Modos de Parámetros Modos de Parámetros


PROCEDURE debit_account (acct_id IN INTEGER, amount IN REAL) IS
minimum_purchase CONSTANT REAL DEFAULT 10.0;
PROCEDURE get_emp_rec (emp_number emp_tab.empno%TYPE, service_charge CONSTANT REAL DEFAULT 0.50;
emp_ret OUT emp_tab%ROWTYPE) BEGIN
IS… IF amount < minimum_purchase THEN
amount := amount + service_charge;
END IF;
...
DECLARE END debit_account;
TYPE staff IS VARRAY(200) OF employee;
PROCEDURE reorganize (my_staff IN OUT NOCOPY staff)
IS ...

55 56
?

14
01/10/2010

Modos de Parámetros Declaración de subprogramas


Es posible declarar subprogramas en algún bloque de PL/SQL,
PROCEDURE calc_bonus (emp_id IN INTEGER, bonus OUT REAL) IS… subprograma o paquete. PERO se deben declarar al final de la
sección declarativa, después de cualquier otro elemento.
calc_bonus(7499, salary + commission);

Se debe declarar un subprograma antes de invocarlo.

PROCEDURE create_dept (
new_dname VARCHAR2 DEFAULT ’TEMP’,
new_loc VARCHAR2 DEFAULT ’TEMP’) IS
BEGIN

?
INSERT INTO dept
VALUES (deptno_seq.NEXTVAL, new_dname, new_loc);
...
END;

57 58

Declaración de subprogramas Manejo de excepciones


Es una condición de advertencia (warning) o error.
PROCEDURE create_dept (
new_dname VARCHAR2 DEFAULT ’TEMP’, Definidas-internamente Definidas-por-el-usuario
new_loc VARCHAR2 DEFAULT ’TEMP’) IS NO es necesario declararlas Deben ser declaradas
v_estado:= 1; Cuando ocurre un error, son lanzadas
Cuando ocurre un error, son lanzadas
PROCEDURE log_exec explicitamente utilizando el enunciado
automáticamente
RAISE
IS
BEGIN A EXCEPTION;
BEGIN
INSERT INTO log_table (user_id, log_date) BEGIN
IF X = 1 THEN
VALUES (USER, SYSDATE); IF X = 1 THEN
Z:= X/Y;
END log_exec; RAISE A;
END IF;
BEGIN END IF;

INSERT INTO dept …
EXCEPTION
VALUES (deptno_seq.NEXTVAL, new_dname, new_loc); EXCEPTION
WHEN ZERO_DIVIDE THEN
... WHEN A THEN

log_exec; …
END;
END;
59 60
END;

15
01/10/2010

Manejo de excepciones Manejo de excepciones


IF … THEN
EXCEPTION Para enviar RAISE out_of_balance;
WHEN … THEN nuevamente una END IF;
Utilizar OTHERS para -- captura el error misma excepción
garantizar que toda EXCEPTION
WHEN … THEN (Reraise), basta con
excepción lanzada en colocar el enunciado WHEN out_of_balance THEN
-- captura el error
la sección de ejecución WHEN OTHERS THEN RAISE; en el manejador RAISE; -- reenvía la excepción
será capturada -- captura todos los demás errores local END;
END;

Utilizar OR para capturar


dos o más excepciones Si la excepción ocurre en la
Si la excepción es
en la misma secuencia sección declarativa o en la
capturada, todas las
de instrucciones sección de excepciones, dicha
instrucciones previas
excepción no podrá ser
EXCEPTION podrán efectuarse a
capturada y se propagará al
WHEN over_limit OR under_limit OR VALUE_ERROR THEN través de un commit
ambiente de llamada.
-- captura el error
61 END; 62

Propagación de excepciones Propagación de excepciones


La excepción C no es
Cuando se lanza una excepción y PL/SQL no encuentra el BEGIN
capturada, al regresar al
ambiente de llamada, todas
manejador de excepciones, dicha excepción se propaga, hasta La excepción
BEGIN las transacciones efectuadas
B se propaga
que un manejador es encontrado o no hay más bloques para al manejador
IF X = 1 THEN hasta entonces harán rollback
buscar. BEGI N apropiado
RAISE A;
ELSIF X = 2 THEN BEGI N
BEGIN RAISE B;
IF X = 1 THEN ELSE BEGIN
RAISE A; RAISE C; IF X = 1 THEN
Una excepción no ELSIF X = 2 THEN END IF; RAISE A;
puede propagarse a RAISE B; … ELSIF X = 2 THEN
EXCEPTION RAISE B;
través de llamadas a ELSE
WHEN A THEN ELSE
RAISE C;
procedimientos END IF; … RAISE C;
remotos (RPC) … END; END IF;
EXCEPTION La excepción B …
EXCEPTION
WHEN A THEN es capturada y EXCEPTION
WHEN A THEN
… NO regresa el WHEN B THEN

END; control al lugar …
END;
END;
donde fue
EXCEPTI ON
La excepción A WHEN B THEN
lanzada EXCEPTI ON
WHEN B THEN
es capturada
localmente END;
END;

63 64

16
01/10/2010

Propagación de excepciones Ejemplo de excepciones


Excepción Número Descripción
ACCESS_INTO_NULL ORA- Intenta asignar valores a los atributos de un objeto sin
DECLARE 06530 inicializarse
--lanza excepción
CASE_NOT_FOUND ORA- Ninguna de las opciones en la cláusula WHERE de un enunciado
credit_limit CONSTANT NUMBER(3):= 5000; 06592 CASE es seleccionada y no hay una cláusula ELSE
BEGIN Las excepciones
… ocurridas en la sección
CURSOR_ALREADY_OPEN ORA- Intenta abrir un cursor ya abierto
declarativa y de 06511
excepciones se DUP_VAL_ON_INDEX ORA- Intenta insertar un valor duplicado
propagan 00001
inmediatamente al INVALID_NUMBER ORA- Conversión de cadena a número ha fallado
bloque adjunto 01722
(enclosing block) NO_DATA_FOUND ORA- La cláusula SELECT de un solo renglón no regresó datos
01403

TOO_MANY_ROWS ORA- La cláusula SELECT de un solo renglón, regresó más de un


EXCEPTION 01422 renglón.
WHEN INVALID_NUMBER THEN
INSERT INTO … --podría lanzar la excepción de valor duplicado VALUE_ERROR ORA- Ocurrió un error aritmético, de conversión, truncado o
WHEN DUP_VAL_ON_INDEX THEN … --no capturaría la excepción 06502 restricciones de tamaño

ZERO_DIVIDE ORA- Intentó dividir entre 0


65 66 01476

Borrado de un procedimiento Parámetros de un procedimiento


Un procedimiento puede ser borrado usando la instrucción SQL: Paso de Parámetros

DROP PROCEDURE nombre_procedimiento;


• Notación Posicional: Especifica los parámetros en el mismo orden
en el cual fueron declarados.

Privilegios
• Notación Nominal: Especifica el nombre de cada parámetro con
Para borrar un procedimiento:
su respectivo valor. Una flecha (=>) indica la asociación. El orden
El usuario debe tener el privilegio DROP ANY PROCEDURE,
de los parámetros no es significativo.
ó
Éste debe estar en el esquema del usuario
• Notación Mixta: Especifica primero los parámetros por notación
posicional y después con notación nominal. (A la inversa no es
Un procedimiento que existe dentro de un paquete NO PUEDE ser posible)
borrado.

67 68

17
01/10/2010

Invocación de Procedimientos Invocación de Procedimientos


Dentro de un bloque de ejecución de otro subprograma o Ejecutar un procedimiento, con variables de salida, desde SQL
paquete. *Plus.
BEGIN
BEGIN
award_bonus(179, 0.05);
award_bonus(bonus_rate=>0.05, emp_id=>123); VARIABLE v_name varchar2(15);
END;
END;
VARIABLE v_salary number;
VARIABLE v_comm number:=50;
En SQL *Plus se utiliza la palabra reservada: EXECUTE EXECUTE consulta_emp (7654,:v_name,:v_salary,:v_comm)
EXECUTE consulta_emp(6565, ‘juan’,5000,12);
PRINT v_name
V_NAME
---------------
MARTIN

69 70

Valores por Default PRÁCTICA!!


Es la forma de pasar diferentes valores a los parámetros actuales
de un subprograma.

PROCEDURE create_dept (
new_dname VARCHAR2 DEFAULT ’TEMP’, Sólo aplica a
new_loc VARCHAR2 DEFAULT ’TEMP’) IS
BEGIN parámetros con
INSERT INTO dept modo IN, no es
VALUES (deptno_seq.NEXTVAL, new_dname, new_loc); válido para
...
END;
OUT, IN OUT.

create_dept;
create_dept(’MARKETING’);
create_dept(’MARKETING’, ’NEW YORK’);

create_dept(, ’NEW YORK’); -- not allowed

create_dept(new_loc => ’NEW YORK’);


71 72

18
01/10/2010

PL/SQL y Web

La combinación de PL/SQL y HTML/XML brindan una


Subtemas

tecnología innovadora, al permitir la construcción de
aplicaciones Web utilizando PL/SQL.
 PL/SQL y el Web
 DAD
 Developer Toolkit
 Ejemplos PL/SQL y el Web
 Para correr PL/SQL en el Web, es necesario utilizar:
 Una base de datos Oracle 9i instalada y configurada.
 Oracle HTTP Server, de Oracle 9i Application Server (Oracle9iAS) instalado
y configurado.

73

74
Rébsamen 80 Xalapa, Veracruz 91000, México T. (52) (228) 841.61.01 | LANIA A.C. | Todos los derechos reservados

Pasos a seguir Pasos a seguir


1. Es necesario crear un Database Access Descriptor
(DAD). En donde se especifica un nombre y la cadena
de conexión hacia la base de datos (usuario,
password, sid).

2. La función del DAD es convertir el URL especificado en


el navegador en una llamada a un procedimiento
almacenado.

3. Una vez creado el DAD, se debe crear un


procedimiento que posea HTML incrustado.

Tomado de: Oracle® Database Application Developer's Guide - Fundamentals


10g Release 2 (10.2)
75 76

19
01/10/2010

Ejemplo Ejemplo
CREATE OR REPLACE PROCEDURE p_displayOrgs IS
BEGIN
CREATE OR REPLACE PROCEDURE html_page IS htp.p('<HTML>');
htp.p('<HEAD>');
BEGIN htp.p('<TITLE>Organization Records</TITLE>');
HTP.HTMLOPEN; -- generates <HTML> htp.p('</HEAD>');
HTP.HEADOPEN; -- generates <HEAD> htp.p('<BODY>');
HTP.TITLE('Title'); -- generates <TITLE>Hello</TITLE> htp.p('<H1>Organization Records</H1>');
HTP.HEADCLOSE; -- generates </HEAD> htp.p('<TABLE BORDER="1 ">');
-- generates <BODY TEXT="#000000" BGCOLOR="#FFFFFF"> htp.p('<TR><TH>Hierarchy</TH><TH>Org Long Name</TH></TR>');
HTP.BODYOPEN( cattributes => 'TEXT="#000000" BGCOLOR="#FFFFFF"'); for idx in (select h.hrc_descr, o.org_long_name from org_tab o,
hrc_tab h where o.hrc_code = h.hrc_code order by
-- generates <H1>Heading in the HTML File</H1> h.hrc_code ) loop htp.p('<TR>');
HTP.HEADER(1, 'Heading in the HTML File'); htp.p('<TD>'||idx.hrc_descr||'</TD>');
HTP.PARA; -- generates <P> htp.p('<TD>'||idx.org_long_name||'</TD>');
HTP.PRINT('Some text in the HTML file.'); htp.p('</TR>');
HTP.BODYCLOSE; -- generates </BODY> end loop;
htp.p('</TABLE>');
HTP.HTMLCLOSE; -- generates </HTML>
htp.p('</BODY>');
END; htp.p('</HTML>');
end; /

77 78

Developer’s Toolkit Pasando parámetros


1. Htp.print o htp.p. Genera una línea en un documento HTML. Ejemplo:  Se puede especificar de dos formas:
htp.p(„<TABLE>‟);
2. Htp.prn. Parecido al anterior, solo que no agrega un salto de línea al  Definiéndolos en el URL
final.  Usando una forma HTML para aceptar entradas de usuarios.
3. Htp.htmlOpen. Imprime el TAG de inicio de un documento HTML.
4. Htp.htmlClose. Imprime el TAG de cierre de un documento HTML.
 Parámetros en el URL
5. Htp.headOpen. Imprime un TAG que indica el inicio del encabezado
HTML.
6. Htp.headClose. Imprime un TAG que indica el fin del encabezado  Cuando el procedimiento es invocado desde el navegador, se
HTML. coloca el nombre del parámetro y su valor: name=value.
7. Htp.bodyOpen. Imprime el TAG que identifica el inicio del cuerpo de
 Si recibe múltiples parámetros, éstos deberán estar separados
un documento HTML, permite especificar una imagen de fondo.
por un “&”.
Ejemplos: htp.bodyOpen(„/img/background.gif‟);
8. Htp.bodyClose. Define el fina del cuerpo de un documento HTML.  Ejemplo:
9. Htp.title. Define el titulo de la página HTML.  http://localhost:80/pls/webdad/p_displayOrgs?ip_code=1
10. Htp.htitle. Imprime los TAGS HTML tanto para el titulo como para el
encabezado.

79 80

20
01/10/2010

Pasando parámetros PRÁCTICA!!


 Utilizando forma HTML:
 Al construir una forma, los elementos de entrada son pasados al
procedimiento como parámetros.

CREATE OR REPLACE PROCEDURE p_displayOrgs_with_param_form IS


BEGIN
htp.p('<HTML>'); htp.p('<HEAD>'); htp.p('<TITLE>Organization
Records</TITLE>');
htp.p('</HEAD>');
htp.p('<BODY>');
htp.p('<H1>Organization Records</H1>');
htp.p('<P>Enter Hrc Code and Press the <b> Run </b> button. </P>');
htp.p('<FORM method="get" action="p_displayOrgs_with_param">');
htp.p('<P>Hrc Code <INPUT type="text" name="ip_code" maxlength="4"
size="4"> </P>');
htp.p('<P> <INPUT type="submit" value="Run"> </P>');
htp.p('</FORM>');
htp.p('</BODY>');
htp.p('</HTML>');
end; /

81 82

Función
Es un subprograma almacenado que calcula un valor y lo
Subtemas devuelve mediante la cláusula RETURN.

 Definición y creación de funciones


definidas por el usuario Utilizada para calcular un valor y regresarlo.
 Ventajas de las funciones definidas por
el usuario
 Borrado de funciones Funciones
 Invocación de funciones
(Functions) Puede recibir parámetros
 Diferencia entre procedimientos y
funciones

Debe tener una cláusula RETURN en la cabecera, y al menos


una sentencia RETURN en la sección ejecutable

Se debe tener el privilegio CREATE PROCEDURE ó CREATE ANY


PROCEDURE (para crear la función en otro esquema).
83

84
Rébsamen 80 Xalapa, Veracruz 91000, México T. (52) (228) 841.61.01 | LANIA A.C. | Todos los derechos reservados

21
01/10/2010

Sintaxis básica de una función Invocación de funciones


Pueden ser invocada como parte de:
una expresión SQL.
CREATE OR REPLACE FUNCTION function_name[(parameter[, parameter]...)]
RETURN datatype SELECT (como una columna más)
{ IS | AS}
WHERE y HAVING (dentro de sus condiciones)
[local declarations] Al menos
BEGIN debe CONNECT BY, START WITH, ORDER BY, GROUP BY
executable statements existir una
RETURN VALUES del comando INSERT
instrucción
[EXCEPTION
SET del comando UPDATE
exception handlers]
Al menos
END [name];
debe existir
una cláusula una expresión PL/SQL. El identificador de función actúa
RETURN como una variable cuyo valor depende de los parámetros
que le han pasado.

85 86

Invocación de funciones Invocación de funciones


Expresión SQL Restricciones en Expresión SQL

Control de “Side Effects” Sólo pueden utilizarse funciones, no procedimientos


La invocación de la función debe utilizar notación
Para ejecutar una sentencia SQL que llame a una función
posicional, no permite la notación nominal
almacenada, Oracle debe saber si la función es “free” o
“side effects”.
Los parámetros deben ser de modo IN, no pueden ser OUT
“Side effects” son cambios efectuados a las tablas de la
o IN OUT.
base de datos los cuales podrían retrasar las ejecuciones
de las consultas o dar resultados diversos dependiendo Los tipos de datos deben ser CHAR, NUMBER o DATE, no
del orden. permite tipos de datos de PL/SQL: TABLE, REGISTER,
BOOLEAN.

87 88

22
01/10/2010

Invocación de funciones Invocación de funciones


Restricciones en Expresión SQL Ventajas de utilizar Expresiones SQL

Debe ser una función almacenada, no una función definida Incrementa la productividad. Al permitir la realización de tareas
en un bloque o subprograma. no disponibles en SQL.

Una función llamada de un query o DML no puede modificar Incrementa la eficiencia de las consultas.
tablas de la base de datos, ni ejecutar los comandos INSERT,
UPDATE o DELETE.
Manipula cadenas para representar tipos de datos especiales
(por ejemplo, latitud, longitud o temperatura).
Una función llamada de un DML no puede leer o modificar la
tabla a actualizar.
Provee la ejecución de consultas en forma paralela.

89 90

Invocación de Funciones Invocación de Funciones


SELECT <nombre_función> FROM dual;
En SQL *Plus se utiliza la palabra reservada: EXECUTE
SELECT ocupa_clase(„Informática‟, 3)
FROM dual;
VARIABLE ex_ocupacion VARCHAR2(15);
EXECUTE :ex_ocupacion := ocupa_clase(„Informática‟, 3);
Desde el bloque de ejecución de otro subprograma o paquete. PRINT ex_ocupacion;

declare
v_ocupa VARCHAR2(15);
begin
v_ocupa := ocupa_clase(„Informática‟, 3);
dbms_output.put_line(v_ocupa);
end;

91 92

23
01/10/2010

Borrado de una función Procedimientos vs Funciones


Una función puede ser borrada usando la instrucción SQL: Procedimiento
Argumento IN
Entorno
DROP FUNCTION nombre_función; de llamada Argumento OUT
Argumento IN
OUT
(DECLARE)
Privilegios
BEGIN

Para borrar una función: Función


EXCEPTION
Entorno IN argumento
Ésta debe estar en el esquema del usuario, o de llamada
END;
El usuario debe tener el privilegio DROP ANY
FUNCTION
(DECLARE)

Una función que existe dentro de un paquete no puede ser BEGIN


borrada con esta instrucción.
EXCEPTION

END;

93 94

PRÁCTICA!!

Subtemas
 Descripción y creación de un paquete
 Invocación de constructores dentro de
paquetes
Creación de
Borrado de paquetes
paquetes

 Beneficios
 Sobrecarga de constructores
 Variables, inicialización, estados de
persistencias
 Restricciones de los paquetes
 Invocar funciones de paquetes en SQL
 Uso de tablas y registros en paquetes
 Paquetes de Oracle 96

95
Rébsamen 80 Xalapa, Veracruz 91000, México T. (52) (228) 841.61.01 | LANIA A.C. | Todos los derechos reservados

24
01/10/2010

Paquetes Paquetes
Agrupación lógica de elementos de PL/SQL tales como: tipos,
El cuerpo y especificación de un paquete están almacenados
elementos y subprogramas
por separado en la base de datos.
1. Especificación del Paquete 1
Es la interfaz de la aplicación. Declaración del
Si el cuerpo del paquete cambia, pero la especificación no,
Declara tipos, variables, constantes, Procedimiento A 2 las llamadas a los constructores del paquete son válidas.
excepciones, cursores y
subprogramas Si la especificación del paquete cambia, las llamadas a los
4
constructores del paquete son invalidadas, así como el cuerpo
2. Cuerpo del Paquete Definición del
3 del paquete.
Procedimiento B
Define cursores, subprogramas
implementando así la
especificación Definición del
Procedimiento A 2
1 Variable pública 2 Procedimiento público
5
4 Variable privada 3 Procedimiento privado
97
5 Variable local

98

Sintaxis de un Paquete Ejemplo Especificación de un Paquete


Especificación del paquete

Una especificación CREATE OR REPLACE PACKAGE comm_package IS


CREATE [OR REPLACE] PACKAGE package_name
del paquete gcomm NUMBER := 0.5
IS | AS
puede existir sin un PROCEDURE reset_comm (pcomm IN NUMBER);
public type and item declarations
cuerpo de END comm_package;
subprogram specifications paquete; /
END package_name;
• gcomm es una variable global o pública

• reset_comm es un procedimiento público que será


Cuerpo del paquete implementado en el cuerpo del paquete
pero un cuerpo
CREATE [OR REPLACE] PACKAGE BODY package_name de paquete no
IS | AS puede existir sin • Ambos son conocidos como constructores públicos
private type and item declarations una
especificación
subprogram bodies
de paquete.
END package_name;

99 100

25
01/10/2010

Ejemplo Cuerpo de un Paquete Invocación de un constructor


CREATE OR REPLACE PACKAGE BODY comm_package IS
FUNCTION validate_comm (pcomm IN NUMBER) Invocar un procedimiento desde iSQL *Plus
RETURN BOOLEAN IS EXECUTE comm_package.reset_comm(0.15)
v_max_comm NUMBER;
BEGIN No es
SELECT MAX(comission_pct) INTO v_max_comm necesario
FROM employees; Invocar un procedimiento desde un esquema diferente
IF pcomm>v_max_comm THEN cualificar el EXECUTE scott.comm_package.reset_comm(0.15)
RETURN (FALSE); nombre
ELSE
RETURN (TRUE);
END IF;
END validate_comm;
PROCEDURE reset_comm(pcomm IN NUMBER)IS
BEGIN
Cuando se invoca un
IF validate_com(pcomm) THEN
gcomm:=pcomm; subprograma o variable,
ELSE cursor, constante, excepción
RAISE_APPLICATION_ERROR (-20210. ‘ Invalid comission’); fuera del paquete, se le
END IF;
END reset_comm; debe anteponer el nombre
END comm_package; del paquete
/
101 102

Utilizando referencias adelantadas Creación de un paquete sin cuerpo


CREATE OR REPLACE PACKAGE BODY comm_package IS
FUNCTION validate_comm (pcomm IN NUMBER) RETURN BOOLEAN; CREATE OR REPLACE PACKAGE global_const IS
PROCEDURE reset_comm(pcomm IN NUMBER)IS
BEGIN millas_a_kilometros CONSTANT NUMBER:= 1.6093;
IF validate_com(pcomm) THEN
gcomm:=pcomm;
kilometros_a_millas CONSTANT NUMBER:= 0.6214;
ELSE yardas_a_metros CONSTANT NUMBER:= 0.9144;
RAISE_APPLICATION_ERROR (-20210. ‘ Invalid comission’);
END IF;
metros_a_yardas CONSTANT NUMBER:= 1.0936;
END reset_comm; END global_const;
FUNCTION validate_comm (pcomm IN NUMBER)
/
RETURN BOOLEAN IS
v_max_comm NUMBER;
BEGIN EXECUTE DBMS_OUTPUT.PUT_LINE(’20 millas =‘ || 20 *
SELECT MAX(comission_pct) INTO v_max_comm
FROM employees; global_const.millas_a_kilometros || ‘km’)
IF pcomm>v_max_comm THEN
RETURN (FALSE);
ELSE
RETURN (TRUE);
END IF;
END validate_comm;

END comm_package;
/
103 104

26
01/10/2010

Paquetes Sobrecarga de constructores


Un paquete NO puede ser invocado o estar anidado. CREATE OR REPLACE PACKAGE over_pack
IS
Un paquete NO puede recibir parámetros, sólo los procedimientos PROCEDURE add_dept (p_deptno IN NUMBER,
y funciones contenidos en el paquete. p_name IN VARCHAR2,
p_loc IN NUMBER);
El contenido de los paquetes puede ser compartido por muchas PROCEDURE add_dept (p_name IN VARCHAR2,
aplicaciones. p_loc IN NUMBER);
END over_pack;
“Side effects” cambios a las tablas de la base de datos o a las
variables públicas de la especificación del paquete.
EXECUTE over_pack.add_dept (980,’Education’,2500);
El valor de una variable o del cursor de un paquete persiste en las EXECUTE over_pack.add_dept (‘Training’,2400);
transacciones de una sesión.
Sólo los subprogramas locales o en paquetes pueden
El valor no persiste de sesión a sesión para el mismo usuario. El valor sobrecargarse
no persiste de usuario a usuario.

105 106

Restricciones de sobrecarga Persistencia de variables / cursores


No se puede crear una sobrecarga cuando: CREATE OR REPLACE PACKAGE pack_cur IS
CURSOR c1 IS SELECT empno FROM emp 1 Declarar el cursor en la
ORDER BY empno desc; especificación del
 Dos subprogramas difieren sólo en el tipo de dato de los PROCEDURE proc1_3rows; paquete.
parámetros, pero éstos son de la misma familia (NUMBER a PROCEDURE proc4_6rows;
DECIMAL, VARCHAR a STRING). END pack_cur;
/
SET SERVEROUTPUT ON
CREATE OR REPLACE PACKAGE BODY pack_cur IS
EXECUTE pack1.proc1_3rows;
 Dos funciones que difieren sólo en el tipo de dato del RETURN, v_empno NUMBER;
PROCEDURE proc1_3rows IS Id : 7934
aunque los tipos sean de diferente familia. BEGIN Id : 7902
OPEN c1; Id : 7900
LOOP FETCH c1 INTO v_empno; EXECUTE pack1.proc4_6rows;
DBMS_OUTPUT.PUT_LINE('Id :' ||(v_empno)); Id : 7876
EXIT WHEN c1%ROWCOUNT >= 3;
Id : 7844
END LOOP;
END proc1_3rows; Id : 7839
PROCEDURE proc4_6rows IS
BEGIN
LOOP FETCH c1 INTO v_empno;
DBMS_OUTPUT.PUT_LINE('Id :' ||(v_empno)); 2 Abrir el cursor y buscar
EXIT WHEN c1%ROWCOUNT >= 6; registros sucesivos desde el
END LOOP; 3 Cerrar el cursor cursor utilizando los
CLOSE c1; en otro procedimientos del paquete.
107 108
END proc4_6rows; procedimiento.
END pack_cur;

27
01/10/2010

110

Borrado de Paquetes DBMS_OUTPUT


Habilita la escritura de mensajes desde bloques PL/SQL. Incluye los
Borrado del paquete (especificación y cuerpo):
siguientes procedimientos:
DROP PACKAGE package_name;

Procedimiento Descripción
Borrado del cuerpo del paquete : PUT Agrega texto del procedimiento a la línea actual de
DROP PACKAGE BODY package_name; la salida del buffer
NEW_LINE Coloca una marca de fin de línea en la salida del
buffer
PUT_LINE Combina la acción PUT y NEW_LINE
GET_LINE Regresa la línea actual de la salida del buffer en el
procedimiento.
GET_LINES Regresa un arreglo de líneas de la salida del
buffer al procedimiento
ENABLE/DISABLE Habilita de deshabilita las llamadas a
109 DBMS_OUTPUT

UTL_FILE PRÁCTICA!!
Procedimiento Descripción

FOPEN Abre un archivo para lectura y escritura y regresa un


apuntador al archivo.
IS_OPEN Regresa un valor Boolean si el manejador de un archivo hace
referencia a un archivo abierto
PUT, PUT_LINE Escribe una cadena de texto almacenada en el parámetro del
buffer
GET_LINE Lee una línea de texto del archivo abierto y coloca el texto en
el parámetro de salida del buffer
PUTF Da formato a través de %s y \n
NEW_LINE Termina una línea
FFLUSH Escribe todos los datos almacenados en memoria al archivo
FCLOSE Cierra un archivo abierto
FCLOSE_ALL Cierra todos los archivos abiertos para la sesión

112

111

28
01/10/2010

Trigger
Es un bloque o procedimiento PL/SQL asociado a una Tabla, Vista,

Subtemas
Esquema o Base de datos que se ejecuta implícitamente si ocurre
un evento
 Descripción y tipos de Triggers
 Creación de un Trigger DML
 Creación de un Trigger a nivel renglón
 Creación de un Trigger a nivel
instrucción Triggers
 OLD y NEW
 Store Procedure vs Triggers
 Borrado de Triggers
 Trigger de base de datos
 Creación de un Trigger DDL
 Privilegios y vistas asociadas a Triggers

113

114
Rébsamen 80 Xalapa, Veracruz 91000, México T. (52) (228) 841.61.01 | LANIA A.C. | Todos los derechos reservados

Tipos de Trigger Estructura de un trigger


1. Timing (Momento)
de aplicación: Se dispara si ocurre un evento dentro Para una tabla: BEFORE, AFTER
de una aplicación (Developer 2000/ Forms, Developer Para una vista: INSTEAD OF
2000/ Reports)

4. Body:
Declare 2. Event: INSERT,
TRIGGER
Begin UPDATE o DELETE
TRIGGER
de base de datos: Se dispara si ocurre un evento: End Tabla: On table, view

de datos (DML, DDL)


sistema (logon o shutdown)
3.Type : (Cuantas veces se
ejecutará) Row o Statement
Cláusula WHEN: condiciones de restricción

115 116

29
01/10/2010

Trigger Type Trigger Event – Trigger Body


Define el EVENTO que activará al trigger

Afecta a las columnas deseadas: Trigger Event


UPDATE OF columns ON table_name

¿Cuántas veces se ejecutará el Afecta a todas el renglón:


trigger cuando ocurre el DELETE ON table_name
evento? INSERT ON table_name
Define la ACCIÓN que debe realizar el
trigger
Statement: El cuerpo del trigger se ejecuta sólo una vez para el evento.
(Default) Bloque anónimo:
Trigger Body [DECLARE]
Row: El cuerpo del trigger se ejecuta una vez para cada registro afectado BEGIN
por el evento. [EXCEPTION]
END

117 118

Sintáxis de Trigger Tipo: STATEMENT Ejemplo:


CREATE OR REPLACE TRIGGER check_salary_count
CREATE [OR REPLACE] TRIGGER trigger_name
AFTER UPDATE OF sal ON emp
timing event1 [OR event2 OR event3] DECLARE
Verifica que el
ON table_name v_salary_changes NUMBER; cambio de salario
PL/SQL block; v_max_changes NUMBER; no rebase el
BEGIN máximo
SELECT upd, max_upd establecido
CREATE OR REPLACE TRIGGER secure_emp
INTO v_salary_changes, v_max_changes
BEFORE INSERT ON emp FROM audit_table
BEGIN WHERE user_name = user
IF (TO_CHAR (sysdate,'DY') IN ('SAT','SUN')) THEN AND table_name = 'EMP'
RAISE_APPLICATION_ERROR (-20500, AND column_name = 'SAL';
'You must insert into EMP of Monday to Friday.'); IF v_salary_changes > v_max_changes THEN
RAISE_APPLICATION_ERROR (-20501,'You may only make a maximum
END IF;
of '||
END; Verifica que el
registro sea TO_CHAR (v_max_changes) || ' changes to the SAL column');
insertado sólo de END IF;
lunes a viernes
Cuando falla un trigger de la base de datos, END;
Oracle Server hace rollback sobre las sentencias del trigger
119 120

30
01/10/2010

Ejemplo: Sintáxis de Trigger Tipo: ROW


CREATE OR REPLACE TRIGGER secure_emp
BEFORE INSERT OR UPDATE OR DELETE ON emp
BEGIN
CREATE [OR REPLACE] TRIGGER trigger_name
IF (TO_CHAR(SYSDATE,’DY’) IN (‘SAT’,’SUN’)) THEN
IF DELETING THEN
timing event1 [OR event2 OR event3]
RAISE_APPLICATION_ERROR (-20502,'You must delete from Monday to ON table_name
Friday); [REFERENCING OLD AS old | NEW AS new]
ELSIF INSERTING THEN FOR EACH ROW
RAISE_APPLICATION_ERROR (-20500, You must insert from Monday to
Friday); [WHEN condition]
ELSIF UPDATING (‘SALARY’) THEN PL/SQL block;
RAISE_APPLICATION_ERROR (-20503, You must update salary from
Monday to Friday);
ELSE
RAISE_APPLICATION_ERROR (-20504, You must modify Employees only
OLD y NEW sólo están disponibles en “ROW triggers”.
from Monday to Friday);
END IF;
END IF; Verifica que los cambios
END; sean realizados sólo de
lunes a viernes
121 122

Tablas Mutantes Utilizando OLD y NEW


Son aquellas tablas que se encuentran en un proceso de cambio
(INSERT, UPDATE, DELETE) Con un Trigger ROW, es posible hacer referencia a los valores de una
columna antes y después del cambio de los datos.
Dado que los datos en las tablas tiene cambios pendientes, el Trigger
de tipo ROW que es disparado por dichos cambios, NO PUEDE realizar
una consulta a la misma tabla.
Operación Valor Anterior Valor Nuevo
INSERT NULL Valor agregado
NO es posible realizar consultas (SELECT) a
la misma tabla que será actualizada. (Sólo UPDATE Valor antes de actualizar Valor después de
aplica para los triggers tipo: statement) actualizar
DELETE Valor antes de borrar NULL

Se debe prefijar OLD y NEW con dos puntos en cada sentencia


PL/SQL y SQL (excepto cuando son referenciados en la condición
de restricción WHEN).

123 124

31
01/10/2010

Ejemplo Ejemplo CALL


CREATE OR REPLACE TRIGGER restrict_salary
BEFORE INSERT OR UPDATE OF salary ON employees
FOR EACH ROW Permite llamar un procedimiento en lugar de escribir un bloque de código
Verifica que el
BEGIN cambio al salario en
IF NOT (:NEW.job_id IN („AD_PRES‟,‟AD_VP‟)) ciertas áreas no sea
AND :NEW.salary > 15000 mayor a 15000
THEN
CREATE [OR REPLACE] TRIGGER trigger_name
RAISE_APPLICATION_ERROR (-20202, timing event1 [OR event2 OR event3]
‟Employee cannot earn this amount‟);
END IF;
ON table_name
END; [REFERENCING OLD AS old | NEW AS new]
CREATE OR REPLACE TRIGGER derive_commission
BEFORE INSERT OR UPDATE OF salary ON employees
FOR EACH ROW
FOR EACH ROW [WHEN condition]
WHEN (NEW.job_id = 'SALESMAN') CALL procedure_name;
BEGIN
IF INSERTING THEN
:NEW.comm := 0;
Si se agrega un registro para
el área „SALESMAN‟ la
ELSIF :OLD.comm IS NULL THEN CREATE OR REPLACE TRIGGER
comisión=0, si se actualiza, :NEW.comm :=0; log_employee No lleva „;‟ al
será igual a la anterior ELSE final de la
comisión más 5% BEFORE INSERT ON employees
:NEW.comm := :OLD.comm + OLD.comm*0.05; llamada del
END IF; CALL log_execution procedimiento
END;

125 126

INSTEAD OF Sintáxis de Trigger Timming: INSTEAD OF

INSERT INTO my_view


CREATE [OR REPLACE] TRIGGER trigger_name
INSTEAD OF event1 [OR event2 OR event3]

X En lugar de…
INSERT
ON view_name
[REFERENCING OLD AS old | NEW AS new]
FOR EACH ROW
Trigger_body;

my_view

UPDATE

127 128

32
01/10/2010

Ejemplo: Administrando Triggers


CREATE OR REPLACE TRIGGER new_emp_dept Deshabilitar o Habilitar un Trigger:
INSTEAD OF INSERT OR UPDATE ON emp_view Actualiza las tablas
asociadas a una ALTER TRIGGER trigger_name DISABLE | ENABLE
FOR EACH ROW vista
BEGIN
IF INSERTING THEN
INSERT INTO new_emps Deshabilitar o Habilitar todos los Triggers de una tabla:
VALUES (:NEW.employee_id, :NEW.last_name, :NEW.salary); ALTER TABLE table_name DISABLE | ENABLE ALL TRIGGERS
UPDATE new_depts SET
total= total+:NEW.salary
WHERE dept_id= :NEW.dept_id; Recompilar un Trigger para una tabla:
ELSIF UPDATING(‘salary’) THEN
ALTER TRIGGER trigger_name COMPILE
UPDATE new_emps SET
salary=:NEW.salary
WHERE employee_id= :OLD.employee_id;
UPDATE new_depts SET
Borrar un Trigger:
total=total+(:NEW.salary - :OLD.salary) DROP TRIGGER trigger_name;
WHERE dept_id= :OLD.dept_id;
END IF; Todos los Trigger de una tabla son eliminados cuando la tabla es borrada
END;
129 130

Database Trigger Sintáxis de Trigger en DDL


CREATE [OR REPLACE] TRIGGER trigger_name
timing [ddl_event1 [OR ddl_event2 OR …]
TRIGGER
ON {DATABASE | SCHEMA }
Eventos de Sistema
trigger_body;

• Base de Datos CREATE


• Esquema
TRIGGER ALTER DROP
DDL
CLUSTERS, FUNCTIONS, INDEXES, PACKAGES, PROCEDURES, ROLES, SEQUENCES,
SYNONYMS, TABLES, TABLESPACE, TRIGGERS, TYPES, VIEWS, USERS

TRIGGER • Tabla o vista


DML específica Cuando falla un trigger de la base de datos,
Oracle Server hace rollback sobre las sentencias del trigger

131 132

33
01/10/2010

Ejemplo Inserta un registro Sintáxis de Trigger en Sistema de Eventos


cuando un usuario crea
un objeto
CREATE OR REPLACE TRIGGER trial CREATE [OR REPLACE] TRIGGER trigger_name
AFTER CREATE ON SCHEMA timing [database_event1 [OR database_event2 OR …]
BEGIN ON {DATABASE | SCHEMA }
INSERT INTO trigger_body;
log_table(user_id,date,action)
VALUES (USER,SYSDATE,‟NEW OBJECT‟);
END; AFTER LOGON BEFORE SHUTDOWN*
CREATE OR REPLACE TRIGGER trial2
AFTER CREATE ON SCHEMA BEFORE LOGOFF AFTER STARTUP*
BEGIN
INSERT INTO AFTER SERVERERROR
log_table(user_id,date,action)
VALUES (USER,SYSDATE,‟NEW OBJECT‟ ||
ORA_DICT_OBJ_TYPE || ‘ CALLED ’||
ORA_DICT_OBJ_NAME ); * Shutdown y Startup aplican solamente para base de datos
END;
133 134

Ejemplo PRÁCTICA!!
CREATE OR REPLACE TRIGGER logon_trig
AFTER LOGON ON SCHEMA
BEGIN
Inserta un registro
INSERT INTO después de que un
log_table(user_id,date,loggin)
usuario se conecta a su
VALUES (USER,SYSDATE,‟ON‟); cuenta
END;

CREATE OR REPLACE TRIGGER


logoff_trig
BEFORE LOGOFF ON SCHEMA
Inserta un registro BEGIN
cuando un usuario se
INSERT INTO
desconecta de su log_table(user_id,date,loggin)
cuenta
VALUES (USER,SYSDATE,‟OFF‟);
END;

135 136

34
01/10/2010

Privilegios de Sistema vs Privilegios de Objeto

Subtemas Privilegios de Sistema. Son los privilegios que usan la palabra


CREATE o ANY y son asignados por el usuario SYSTEM o SYS.
 Privilegios de Sistema vs Privilegios de
Objetos GRANT ALTER ANY TABLE TO green;
 Otorgamiento de privilegios
 Derechos de los Invocadores vs
Derechos de Propietarios Administración de
 Identificación de vistas en el diccionario
de datos subprogramas
Dependencias procedurales Privilegios de Objeto. Son derechos asignados a un objeto
 Objetos dependientes y objetos
referenciados específico dentro de un esquema y siempre incluye el nombre del
 Dependencia remota objeto.
 Cómo minimizar fallas de dependencias
GRANT ALTER ON employees TO green;

137

138
Rébsamen 80 Xalapa, Veracruz 91000, México T. (52) (228) 841.61.01 | LANIA A.C. | Todos los derechos reservados

Privilegios de Sistema vs Privilegios de Objeto Derechos de Invocadores vs Derechos de Propietarios

Por default un subprograma es ejecutado con los privilegios de su


Para crear un subprograma propietario (definers), no del usuario actual (invokers)
PL/SQL se debe tener el
privilegio de sistema CREATE Privilegios de Sistema
PROCEDURE
CREATE PROCEDURE crear_depto (
CREATE (ANY) PROCEDURE CREATE PROCEDURE crear_depto (
my_deptono NUMBER,
ALTER ANY PROCEDURE my_deptono NUMBER,
my_dname VARCHAR2,
DROP ANY PROCEDURE my_dname VARCHAR2,
Otorga DBA my_loc VARCHAR2)
my_loc VARCHAR2) AS
EXECUTE ANY PROCEDURE AUTHID CURRENT_USER AS
BEGIN
BEGIN
INSERT INTO dept
VALUES(my_deptono, my_dname, INSERT INTO dept
Para invocar un subprogama my_loc); VALUES(my_deptono, my_dname,
PL/SQL se debe tener el my_loc);
END;
END;
privilegio de objeto EXECUTE
dept dept
Privilegios de Objeto Invocador
Propietario
Otorga el propietario
EXECUTE 140
EXECUTE
139 SCOTT TOM

35
01/10/2010

Ventajas de otorgar derechos de invocadores Dependencias entre objetos


Depende de la existencia de
Es referenciado por otro
otro(s) objeto(s)
objeto
Permiten reutilizar código y
centralizar la lógica de la
aplicación Dependencia directa Dependencia directa

Dependencia indirecta
Objeto Objeto
Referenciado Dependiente

Oracle Server automáticamente registra dependencias entre objetos

141 142

Dependencias Dependencia entre Objetos


Objetos Dependientes Objetos Referenciados Cuando un objeto es modificado, los objetos dependientes son
inválidos.
Tabla Tabla
Vista Vista Oracle server implícitamente recompila algún objeto inválido
cuando el objeto es llamado.
Triggers de BD Procedimiento
Procedimiento Función Para administrar dependencias, todos los objetos del esquema
tienen un estado (válido o inválido) que es almacenado en el
Función Especificación del Paquete
diccionario de datos
Cuerpo del paquete Secuencia
Oracle server no administra dependencias entre objetos de
Especificación del paquete Sinónimo
esquemas remotos, por lo tanto no recompilará implícitamente
Objetos definidos por el usuario Objetos definidos por el algún objeto inválido.
y tipos de colecciones usuario y tipos de colecciones

143 144

36
01/10/2010

USER_OBJECTS Dependencias Remotas


En la vista del diccionario de datos: USER_OBJECTS se puede
Un procedimiento que hace referencia a un procedimiento
consultar el estado de dependencia de objetos
remoto es INVÁLIDO si el procedimiento remoto es
recompilado después de que el procedimiento local es
compilado. Para cambiar su estado a VALIDO es necesario
Estado Significado
invocarlo por segunda vez.
VALID El objeto del esquema ha sido compilado y

  
puede ser usado inmediatamente cuando es
referenciado
INVALID El objeto del esquema debe ser compilado
antes que pueda ser usado
Objeto
Referenciado  
145
Objeto
Dependiente
146
 

Dependencias Remotas USER_DEPENDENCIES


Despliega las dependencias directas
SIGNATURE

Columna Descripción
TIMESTAMP NAME Nombre del objeto dependiente
TYPE El tipo del objeto dependiente
(PROCEDURE, FUNCTION, PACKAGE,
Revisar Horario. Cada objeto de Revisar Firma. Cada objeto de PACKAGE BODY, TRIGGER, VIEW)
PL/SQL guarda un horario de PL/SQL guarda una firma que REFERENCED_OWNER Esquema del objeto referenciado
cuando es creado o contiene la siguiente
recompilado. La comparación información: nombre del REFERENCED_NAME Nombre del objeto referenciado
de horario se realiza cuando es constructor, tipos, cantidad y REFERENCED_TYPE Tipo del objeto referenciado
llamado un procedimiento modos de parámetros
remoto. REFERENCED_LINK_NA Vínculo a la base de datos usado para
ME acceder al objeto referenciado

147 148

37
01/10/2010

Minimizar fallas en dependencias

Declarando registros usando el atributo %ROWTYPE

Declarando variables con el atributo %TYPE

Consultar con la notación SELECT *


VISTAS
Incluyendo una lista de columnas con los enunciados
INSERT

150

149
Rébsamen 80 Xalapa, Veracruz 91000, México T. (52) (228) 841.61.01 | LANIA A.C. | Todos los derechos reservados

Administrando Objetos Almacenados USER_OBJECTS


Utilizado para obtener los nombres de todos los objetos
Información Descripción Método de Acceso almacenados dentro del esquema.
Almacenada
General Información del objeto La vista USER_OBJECTS del Columna Descripción
diccionario de datos
OBJECT_NAME Nombre del objeto
Código fuente Texto del procedimiento La vista USER_SOURCE del
diccionario de datos OBJECT_ID Identificador interno del objeto

Parámetros Modo: IN/OUT/IN OUT, iSQL *Plus: comando DESCRIBE OBJECT_TYPE Tipo de objeto: TABLE, PROCEDURE, FUNCTION, PACKAGE,
tipo de dato TRIGGER
CREATED Fecha cuando el objeto fue creado
P-código Código de objetos No es accesible
compilados LAST_DDL_TIME Fecha cuando el objeto fue modificado
Errores de Sintaxis de errores La vista USER_ERRORS del
TIMESTAMP Fecha y hora cuando el objeto fue compliado
compilación PL/SQL diccionario de datos o en iSQL
*Plus: comando SHOW ERRORS
STATUS VALID o INVALID
Información de Variables y mensajes El paquete otorgado por Oracle
debug en tiempo de de debug especificados DBMS_OUTPUT
ejecución por el usuario
151 152

38
01/10/2010

USER_SOURCE USER_ERRORS
Utilizado para obtener el texto de un procedimiento o función Utilizado para obtener el texto de los errores de compilación
almacenada
Columna Descripción
Columna Descripción NAME Nombre del objeto
NAME Nombre del objeto TYPE Tipo de objeto: PROCEDURE, FUNCTION, PACKAGE,
TRIGGER
TYPE Tipo de objeto: PROCEDURE, FUNCTION, PACKAGE
LINE Número de línea del código fuente donde ocurrió el error
LINE Número de línea del código fuente
TEXT Texto del mensaje de error
TEXT Texto de la línea de código fuente
SEQUENCE Número de secuencia, para el ordenamiento

POSITION Posición en la línea en la cual ocurre el error

153 154

USER_TRIGGERS Ejemplo
select trigger_name, trigger_type,
Columna Descripción triggering_event,table_name, referencing_names,
TRIGGER_NAME Nombre del trigger when_clause, status, trigger_body
from USER_TRIGGERS
TRIGGER_TYPE BEFORE, AFTER, INSTEAD OF

TRIGGERING_EVENT La operación DML que disparará al trigger


TABLE_NAME Nombre de la tabla de la base de datos
REFERENCING_NAMES Nombre usado para :OLD y :NEW

WHEN_CLAUSE Contenido de la cláusula WHEN

STATUS Estado del trigger

TRIGGER_BODY Acción a tomar


155 156

39

Das könnte Ihnen auch gefallen