Sei sulla pagina 1di 99

OL-ORACLE02T

PL/ SQL

Mdulo 2

PL-SQL

MASTER ORACLE ONLINE OL02T

OL-ORACLE02T

PL/ SQL

Mdulo 2

Dirigido a:
Desarrolladores de aplicaciones. Analistas/Programadores. Administradores de Base de Datos. Tcnicos de Sistemas

Duracin:
Dos semanas de autoestudio

Propsito:
Introducir al alumno en el conocimiento del lenguaje de programacin PL/ SQL como lenguaje del motor de base de datos Oracle. Conocer las estructuras y sentencias de control bsicas y su uso en bases de datos. Aprender el uso y ventajas de los elementos de programacin almacenados en la base datos: procedimientos, funciones, paquetes y triggers

MASTER ORACLE ONLINE OL02T

OL-ORACLE02T Contenido

PL/ SQL

Mdulo 2

PL/SQL ........................................................................................................................................... 4 Caractersticas ............................................................................................................................... 5 Ventajas......................................................................................................................................... 6 Elementos del lenguaje.................................................................................................................. 7 Bloques PL / SQL ............................................................................................................................ 8 Tipos de Bloques............................................................................................................................ 9 Variables...................................................................................................................................... 10 Tipos de Datos Escalares .............................................................................................................. 11 Declaracin de Variables.............................................................................................................. 11 El Atributo %TYPE ........................................................................................................................ 12 El atributo %ROWTYPE................................................................................................................. 12 Variables Boolean ........................................................................................................................ 13 Mostrar mensajes: DBMS_OUTPUT.PUT_LINE.............................................................................. 14 Entorno de trabajo, el primer programa....................................................................................... 15 Lectura de variables por teclado, las variables & .......................................................................... 18 Funciones SQL.............................................................................................................................. 22 Utilizables en sentencias procedurales:........................................................................................ 22 No utilizables en sentencias procedurales:................................................................................... 22 Operadores.................................................................................................................................. 25 SELECT ......................................................................................................................................... 26 Manipulacin de Datos ................................................................................................................ 27 La sentencia MERGE ......................................................................... Error! Marcador no definido. Estructuras de Control ................................................................................................................. 28 Flujo de control............................................................................................................................ 28 Sentencia if: ................................................................................................................................. 28 Sentencia CASE ............................................................................................................................ 30 Control Iterativo: Sentencias LOOP .............................................................................................. 32 Tipos de Datos Compuestos ......................................................................................................... 36 Cursores ...................................................................................................................................... 43

MASTER ORACLE ONLINE OL02T

OL-ORACLE02T

PL/ SQL

Mdulo 2

PL/SQL
Es la respuesta de Oracle a las limitaciones de SQL. Es un lenguaje de programacin estructurado que combina sentencias SQL con bucles, sentencias de control,... Es especfico de Oracle, por lo que su uso no es vlido en otras bases de datos. PL/SQL es un sofisticado lenguaje de programacin que se utiliza para acceder a bases de datos Oracle desde distintos entornos. PL/SQL est integrado con el servidor de base de datos, de modo que el cdigo PL/SQL puede ser procesado de forma rpida y eficiente. PL/SQL combina la potencia y flexibilidad de un lenguaje SQL con las estructuras procedimentales de un 3GL.

MASTER ORACLE ONLINE OL02T

OL-ORACLE02T

PL/ SQL

Mdulo 2

Caractersticas
Juega un papel central tanto en las herramientas de Oracle (Developer, Forms, ...) como en el propio servidor (a travs de funciones, triggers, ... almacenados en el propio servidor). El motor PL/SQL presente tanto en las herramientas como en el servidor, filtra las sentencias SQL incluidas en los programas y las enva a la Base de Datos, procesando el resto de las sentencias procedurales en el propio motor con datos que son internos a la aplicacin, lo que reduce las consultas a la base de datos. PL/SQL ampla la funcionalidad de SQL aadiendo estructuras de las que pueden encontrarse en otros lenguajes procedimentales, como: Variables y tipos (tanto predefinidos como definidos por el usuario). Estructuras de control, como bucles y rdenes IF-THEN-ELSE. Procedimientos y funciones. Tipos de objetos y mtodos (en PL/SQL versin 8 o superior).

Las construcciones procedimentales estn perfectamente integradas con Oracle SQL, lo que da como resultado un lenguaje potente y estructurado.

MASTER ORACLE ONLINE OL02T

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ventajas
La modularizacin que caracteriza a los programas escritos en PL/SQL permite: Agrupar sentencias relacionadas lgicamente, en bloques. Anidar subbloques en bloques mayores para desarrollar aplicaciones complejas. Guardar los programas en libreras reutilizables. PL/SQL permite controlar los errores. Almacenamiento de unidades de programacin (procedimientos, funciones, paquetes, triggers) Los procedimientos, funciones y paquetes almacenados pueden ser invocados desde herramientas (Forms, Developer) o desde la propia consola.

PL/SQL integra tanto las estructuras procedimentales necesarias como el acceso a bases de datos. El resultado es un lenguaje robusto y potente, bien adaptado al diseo de aplicaciones complejas. Su capacidad de reutilizacin, de poderse almacenar en paquetes y su control de las excepciones. Su conocimiento permite el acceso a las distintas herramientas de Oracle que lo utilizan.

MASTER ORACLE ONLINE OL02T

OL-ORACLE02T

PL/ SQL

Mdulo 2

Elementos del lenguaje


Se pueden clasificar en: Identificadores Literales Comentarios Identificadores Pueden contener hasta 30 caracteres. Deben empezar con un carcter alfabtico. Pueden contener caracteres alfanumricos, $, _ y signos numricos. No pueden contener guiones, / , y espacios. No debera usarse el mismo nombre que tenga la columna de una tabla. No debera usar palabras reservadas.

Literales y comentarios Los literales de caracteres y fechas deben ir entre comillas simples. Los nmeros pueden ser valores simples o cientficos. Un slash (/) ejecuta la sentencia contenida en un Script o en el entorno SQL . -- Marca comentarios de una lnea. / * Delimita comentarios de ms de una lnea */

MASTER ORACLE ONLINE OL02T

OL-ORACLE02T

PL/ SQL

Mdulo 2

Bloques PL / SQL
Los programas en PL/SQL pueden ser tambin llamados bloques PL/SQL. Pueden tener un nombre esto es, ser un procedimiento, una funcin, un paquete o un trigger o ser un bloque PL annimo. La estructura de un programa sea del tipo que sea es la siguiente: DECLARE declaraciones (variables, cursores, excepciones definidas por el usuario) BEGIN sentencias del programa (PL / SQL y SQL) EXCEPTION Procedimientos a seguir en caso de excepciones END ;

Ejemplo de bloque PL annimo:

DECLARE mi_variable NUMBER (5); BEGIN SELECT salario INTO mi_variable FROM empleados WHERE numero_empleado = 1234; EXCEPTION WHEN nombre_excepcin THEN ... END;

MASTER ORACLE ONLINE OL02T

OL-ORACLE02T

PL/ SQL

Mdulo 2

Tipos de Bloques
Annimos Subprogramas: Procedimientos, Funciones Annimos [DECLARE] BEGIN --sentencias [EXCEPTION] END ; Subprogramas Procedimientos PROCEDURE nombre IS BEGIN --sentencias [EXCEPTION] END ; Funciones FUNCTION nombre RETURN tipo IS BEGIN --sentencias [EXCEPTION] END ;

MASTER ORACLE ONLINE OL02T

OL-ORACLE02T

PL/ SQL

Mdulo 2

Variables
Las variables pueden utilizarse para el almacenamiento temporal de datos, trabajar con valores almacenados, ser usadas repetidamente, etc... Se declaran e inicializan en la seccin de declaraciones. Se les asignan nuevos valores en la seccin de ejecucin. Se les pueden pasar valores a travs de parmetros. Se inicializan a nulo. Tipos de Variables Variables PL / SQL: Escalares slo pueden recoger un valor. Compuestas recogen fila o filas. Referencias punteros que apuntan a objetos de otros programas. LOB (large objects) contienen localizadores que indican la localizacin de objetos de gran tamao (por ejemplo imgenes).

MASTER ORACLE ONLINE OL02T

10

OL-ORACLE02T

PL/ SQL

Mdulo 2

Tipos de Datos Escalares


CHAR [(longitud mxima)] VARCHAR2 (longitud mxima) NUMBER [(precisin, escala)] BINARY_INTEGER PLS_INTEGER BOOLEAN DATE

Declaracin de Variables
Dos variables pueden tener el mismo nombre si pertenecen a dos bloques distintos. El identificador debera ser distinto a los nombres de las columnas de la tabla usada en el bloque. Ejemplos: v_job VARCHAR2 (9); cuenta BINARY_INTEGER NOT NULL : = 0; fecha_fut DATE : = SYSDATE + 7; factor CONSTANT NUMBER (3,2) : = 8.25 ;

MASTER ORACLE ONLINE OL02T

11

OL-ORACLE02T

PL/ SQL

Mdulo 2

El Atributo %TYPE
Define el tipo de la variable en funcin del de una columna de una tabla, o del de una variable previamente declarada.

Ejemplos: var_nombre var_primer_apelllido var_segundo_apellido emp.ename%TYPE; VARCHAR2(50); var_primer_apellido%TYPE ;

El atributo %ROWTYPE
Lo utilizaremos normalmente con cursores (se ven ms adelante), en el ejemplo definimos una variable que es del mismo tipo que lo que haya en la tabla DEPT. Se utiliza para copiar la estructura de campos y de tipos de datos de una variable que es una tabla a otra. VARIABLE_TABLE DEPT%ROWTYPE;

MASTER ORACLE ONLINE OL02T

12

OL-ORACLE02T

PL/ SQL

Mdulo 2

Variables Boolean
nicamente se les pueden asignar los valores TRUE, FALSE y NULL. Para realizar comprobaciones entre variables de este tipo se utilizan los operadores AND, OR y NOT. Se pueden utilizar expresiones aritmticas, caracteres o fechas para conseguir un valor boolean. EJEMPLO: DECLARE ENCONTRADO BOOLEAN :=FALSE; BEGIN IF A=.. THEN ENCONTRADO := TRUE.

MASTER ORACLE ONLINE OL02T

13

OL-ORACLE02T

PL/ SQL

Mdulo 2

Mostrar mensajes: DBMS_OUTPUT.PUT_LINE


Es una manera de mostrar los datos de un bloque PL/SQL, enseando una cadena de caracteres predeterminada. Es un paquete de Base de Datos. Puesto que slo es capaz de mostrar un dato, cuando se quiere mostrar ms de uno ser necesario el uso del operador de concatenacin. Ejemplo DECLARE v_sal NUMBER(9,2) : = 60000 ; BEGIN v_sal : = v_sal/12; DBMS_OUTPUT.PUT_LINE(El salario es :||v_sal); END;

NOTA: Las sentencias pueden continuar a lo largo de varias lneas.

MASTER ORACLE ONLINE OL02T

14

OL-ORACLE02T

PL/ SQL

Mdulo 2

Entorno de trabajo, el primer programa


Inicialmente el entorno de trabajo ser SQL*PLUS aunque existen otros entornos (SQL Developer etc) con los que tambin es posible trabajar. NOTA IMPORTANTE: Las pantallas que se muestran aqu son de Oracle 10g. En Oracle 11g es igual pero a travs de la pantalla que se abre a travs de lnea de comando (ya vista en Sql).

Una vez dentro del sql*plus lanzar el comando: SET SERVEROUTPUT ON. Este comando pertenece al entorno sql*plus no es una sentencia PL/SQL por lo tanto deber ir fuera de los programas. Sirve para habilitar la salida de mensajes por pantalla y deber ponerse en cada nueva conexin.

MASTER ORACLE ONLINE OL02T

15

OL-ORACLE02T

PL/ SQL

Mdulo 2

1) Escribiremos el programa con el editor del sistema, en este caso el notepad.

MASTER ORACLE ONLINE OL02T

16

OL-ORACLE02T

PL/ SQL

Mdulo 2

2) Y ahora lo ejecutaremos. Esto puede hacerse de dos maneras: a. copiar y pegar directamente en sql*plus

b. Ejecutando el fichero con: @c:\hola_mundo.sql (suponermos que est guardado con extensin sql en el directorio c:)

MASTER ORACLE ONLINE OL02T

17

OL-ORACLE02T

PL/ SQL

Mdulo 2

Lectura de variables por teclado, las variables &


El carcter & es un carcter especial en Oracle. Provoca que el programa pare y pida un valor cada vez que encuentra una variable precedida de este smbolo.

El uso que veremos es sencillo. Si la variable es carcter ir entrecomillada, si es numrica no.

Podemos decir que ni la entrada de datos (con &), ni la salida de mensajes con DBMS_OUTPUT son muy sofisticados en este lenguaje. Es necesario tener en cuenta que se trata de un lenguaje enfocado al tratamiento masivo de la informacin.

MASTER ORACLE ONLINE OL02T

18

OL-ORACLE02T

PL/ SQL

Mdulo 2

Segundo programa con lectura de variables.

El programa es el siguiente:

BEGIN -- ESTE ES EL SEGUNDO PROGRAMA -- NO TIENE PARTE DECLARATIVA -- NI DE EXCEPCIONES -- ES PARA DEMOSTRAR COMO SE LEEN VARIABLES -- NOMBRE SE CONSIDERA DE TIPO CARCTER Y AOS -- NUMRICA

DBMS_OUTPUT.PUT_LINE('BUENOS DIAS ' || '&NOMBRE' || ' TIENES ' || &AOS || ' AOS '); END; /

MASTER ORACLE ONLINE OL02T

19

OL-ORACLE02T

PL/ SQL

Mdulo 2

La salida queda como sigue:

MASTER ORACLE ONLINE OL02T

20

OL-ORACLE02T

PL/ SQL

Mdulo 2

Quiz un poco liosa no?. Vamos a eliminar los mensajes de antiguo nuevo. Para ello lanzaremos el comando: SET VERIFY OFF. La salida queda de la siguiente manera:

As queda algo ms clara.

MASTER ORACLE ONLINE OL02T

21

OL-ORACLE02T

PL/ SQL

Mdulo 2

Funciones SQL Utilizables en sentencias procedurales:


Numricas a nivel de una fila De carcter a nivel de una fila De conversin de tipos De fecha De intervalos de tiempo

Igual que en SQL

No utilizables en sentencias procedurales:


DECODE Funciones de Grupo (vlidas en sentencias SQL)

Ejemplo de funciones SQL Concatenando datos en una cadena con espacios en blanco: v_nombre_completo := v_nombre|| || v_primer_apellido || || v_segundo_apellido; Utilizando la conversin a minsculas: v_nombre := LOWER(v_nombre);

MASTER ORACLE ONLINE OL02T

22

OL-ORACLE02T

PL/ SQL

Mdulo 2

Funciones de conversin Las funciones tiene el mismo funcionamiento que en SQL , as: DECLARE v_date DATE := TO_DATE(12,ENE,99,DD,MON,YY); BEGIN... La sentencia : V_date:= Enero 20, 1999 Sera errnea

MASTER ORACLE ONLINE OL02T

23

OL-ORACLE02T

PL/ SQL

Mdulo 2

Bloques Anidados Los bloques se pueden anidar en cualquier sitio que se permitan sentencias ejecutables, convirtindose el bloque en una sentencia. Caractersticas

Una seccin EXCEPTION puede contener bloques anidados, es decir, ser compartida por todos los bloques anidados. El mbito de un identificador es la zona en la que se puede referenciar ese identificador. Un identificador es visible para el bloque que ha sido declarado y para sus bloques anidados.

mbitos .... X NUMBER; BEGIN .... DECLARE aunque puede hacerse no es una buena prctica. y NUMBER(7); mbito de x BEGIN y:=x; mbito de y END; .... END;

MASTER ORACLE ONLINE OL02T

24

OL-ORACLE02T

PL/ SQL

Mdulo 2

Operadores
Operador de Asignacin Operador de Concatenacin Operadores Aritmticos := || +,-,*,/,**(potencia), resto de la divisin entre A y B mod(A,B) Operadores de Relacin =,>,<,>=,<=, IN (contenido), NOT IN, BETWEEN, NOT BETWEEN, LIKE, NOT LIKE, IS NULL, IS NOT NULL Operadores Lgicos AND, NOT ,OR

Parntesis para controlar el orden de las operaciones

MASTER ORACLE ONLINE OL02T

25

OL-ORACLE02T

PL/ SQL

Mdulo 2

Interaccin con el servidor Oracle Sentencias SQL La extraccin de datos de la base de datos se realiza a travs del uso de sentencias SELECT. El cambio de datos en las filas de las tablas se realiza a travs de comandos DML. El control de transacciones se lleva a cabo con los comandos COMMIT, ROLLBACK o SAVEPOINT. Formato general: SELECT expresion INTO {var1[,var2] | registro } FROM nombre_tabla [WHERE condicin];

SELECT
La clasula INTO es imprescindible, es necesario guardar el valor ledo en una variable. Todas las instrucciones SELECT tienen que llevar un INTO a excepcin de los cursores. Las bsquedas deben devolver slo una fila. Cuando devuelven ms es necesario usar otra estructura de datos. DECLARE suma NUMBER(10,2); departamento VARCHAR2(3) : =20; BEGIN SELECT SUM(sal) INTO suma FROM emp WHERE deptno = departamento; DBMS_OUTPUT.PUT_LINE(El total es || suma); END; /

MASTER ORACLE ONLINE OL02T

26

OL-ORACLE02T

PL/ SQL

Mdulo 2

Manipulacin de Datos
Se realiza con los comando INSERT, UPDATE y DELETE de SQL, pudiendo combinarlo con el uso de variables, etc.. DECLARE incremento emp.sal%TYPE : = 50; BEGIN UPDATE emp SET sal = sal + incremento WHERE deptno = 20; END; /

MASTER ORACLE ONLINE OL02T

27

OL-ORACLE02T

PL/ SQL

Mdulo 2

Estructuras de Control Flujo de control.

Sentencia IF:
La ejecucin lgica de un programa se puede cambiar con el uso del condicional IF. IF THEN END IF IF THEN ELSE END IF IF THEN ELSIF END IF

Se utilizan para la toma de decisiones.

MASTER ORACLE ONLINE OL02T

28

OL-ORACLE02T

PL/ SQL

Mdulo 2

La estructura bsica es la siguiente

IF SIMPLE IF CONDIDION THEN SENTENCIA/S; END IF;

IF DOBLE IF CONDIDION THEN SENTENCIA/S; ELSE SENTENCIA/S; END IF;

IF MULTIPLE IF CONDIDION THEN SENTENCIA/S; ELSIF CONDICION1 THEN SENTENCIA/S; ELSIF CONDICION2 THEN SENTENCIA2/S; ELSE SENTENCIA/S; END IF;

MASTER ORACLE ONLINE OL02T

29

OL-ORACLE02T

PL/ SQL

Mdulo 2

Sentencia de seleccin mltiple: CASE


Aparece en Oracle 9i, es equivalente al if mltiple. Es una sentencia de seleccin mltiple que selecciona un valor entre varios y lo devuelve. CASE v_nota WHEN 9 THEN V_calificacion : = Sobresaliente WHEN 7 THEN V_calificacion : = Notable WHEN 5 THEN V_calificacion : = Aprobado ELSE V_calificacion : = Suspenso END CASE; ......

MASTER ORACLE ONLINE OL02T

30

OL-ORACLE02T

PL/ SQL

Mdulo 2

Manejando Valores Nulos Al trabajar con valores nulos, se pueden evitar algunos errores si se tiene en cuenta: Las comparaciones simples que incluyen nulls, siempre devuelven null. Aplicar el operador lgico NOT a un campo null devuelve null. En una sentencia de control condicional, si la condicin devuelve null , las secuencia asociada de sentencias, no se ejecuta.

MASTER ORACLE ONLINE OL02T

31

OL-ORACLE02T

PL/ SQL

Mdulo 2

Control Iterativo: BUCLES (LOOP)


Repiten una sentencia o secuencia de sentencias varias veces. Hay tres tipos de bucles:

Loop Bsico es conveniente cuando las sentencias se deban ejecutar al menos una vez. Loop FOR se usa cuando se conoce el nmero de iteraciones.

Loop WHILE cuando se quiera comprobar la condicin al comienzo de cada iteracin.

MASTER ORACLE ONLINE OL02T

32

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejemplo para mostrar por pantalla los 50 primeros nmeros. Se realiza con los tres tipos de bubles.

Bucle Bsico DECLARE -- SACAR POR PANTALLA LOS 50 PRIMEROS NUMEROS -- CON LOOP CONTADOR NUMBER(2):= 1; BEGIN LOOP DBMS_OUTPUT.PUT_LINE(CONTADOR); EXIT WHEN CONTADOR = 50; CONTADOR := CONTADOR +1; END LOOP; END; /

MASTER ORACLE ONLINE OL02T

33

OL-ORACLE02T

PL/ SQL

Mdulo 2

Bucle WHILE

DECLARE V_CONT BEGIN V_CONT :=0; WHILE V_CONT<50 LOOP DBMS_OUTPUT.PUT_LINE(V_CONT); V_CONT:=V_CONT + 1; END LOOP; END; / NUMBER;

MASTER ORACLE ONLINE OL02T

34

OL-ORACLE02T

PL/ SQL

Mdulo 2

Bucle FOR DECLARE -- SACAR POR PANTALLA LOS 50 PRIMEROS NUMEROS -- CON FOR BEGIN FOR I IN 1..50 LOOP DBMS_OUTPUT.PUT_LINE(I); END LOOP; END; / DECLARE -- SACAR POR PANTALLA LOS NUMEROS DEL 50 AL 1 -- CON FOR BEGIN FOR I IN REVERSE 1..50 LOOP DBMS_OUTPUT.PUT_LINE(I); END LOOP; END; /

MASTER ORACLE ONLINE OL02T

35

OL-ORACLE02T

PL/ SQL

Mdulo 2

Tipos de Datos Compuestos


Los tipos de datos escalares o simples pueden agruparse formando un nuevo tipo de dato llamado estructurado o compuesto, que ser un nuevo tipo de dato definido por el programador. Hay dos tipos: PL / SQL RECORDS (registros). PL / SQL Collections : INDEX BY Table (Tablas). Tablas Anidadas. VARRAY

Aqu se tratan las primeras.

MASTER ORACLE ONLINE OL02T

36

OL-ORACLE02T

PL/ SQL

Mdulo 2

Registros
Son estructuras de datos que agrupan informacin de una tabla o de otro registro y que se tratan como una unidad lgica. Son convenientes para recoger datos de una fila para su procesamiento. Ejemplo: .... TYPE datos_personales IS RECORD ( nombre VARCHAR2(10), apellido VARCHAR2(10), edad NUMBER (3) ); Registro1 datos_personales; .... declaracin de tipo de dato

declaracin de variable del tipo anterior

MASTER ORACLE ONLINE OL02T

37

OL-ORACLE02T

PL/ SQL

Mdulo 2

Tablas
Son matrices dinmicas, compuestas por un ndice y una columna de tipo escalar o registro. Sintaxis: DECLARE TYPE nombre_tabla IS TABLE OF (tipo_columna | variable%TYPE | | tabla.%ROWTYPE INDEX BY BINARY_INTEGER; identificador nombre_tabla; .... Ejemplo de declaracin: DECLARE T_MESES IS TABLE OF NUMBER(5) INDEX BY BINARY_INTEGER; GANACIAS T_MESES;

tabla.columna%TYPE) [NOT NULL]

MASTER ORACLE ONLINE OL02T

38

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejemplo de programa completo:

DECLARE -- PROGRAMA DE EJEMPLO DE UTILIZACIN DE TABLAS TYPE TABLA IS TABLE OF NUMBER(5) INDEX BY BINARY_INTEGER; -- DECLARAMOS DOS VARIABLES DEL TIPO TABLA NUMEROS_1 TABLA; NUMEROS_2 TABLA; -- DECLARAMOS EL NDICE XBINARY_INTEGER; VALOR NUMBER(5):=0; BEGIN -- ASIGNAR VALORES DIRECTAMENTE NUMEROS_1(1) :=100; NUMEROS_1(2) :=200; NUMEROS_1(3) :=300; -- ASIGNAR VALORES CON UN BUCLE FOR X IN 1..3 LOOP VALOR:=VALOR+100; NUMEROS_2(X) :=VALOR; END LOOP;

MASTER ORACLE ONLINE OL02T

39

OL-ORACLE02T

PL/ SQL

Mdulo 2

-- MOSTRAMOS LOS VALORES INTRODUCIDOS EN LAS DOS TABLAS FOR X IN 1..3 LOOP DBMS_OUTPUT.PUT_LINE('TABLA 1 ELEMENTO ' || X || ' = ' || NUMEROS_1(X)); DBMS_OUTPUT.PUT_LINE('TABLA 2 ELEMENTO ' || X || ' = ' || NUMEROS_2(X)); END LOOP; -- OPERAMOS CON LOS ELEMENTOS DE LA TABLA NUMEROS_1(1) :=VALOR*NUMEROS_2(3); -- MOSTRAMOS EL RESULTADO DBMS_OUTPUT.PUT_LINE('TABLA 1 ELEMENTO 1 ' || NUMEROS_1(1)); END;

MASTER ORACLE ONLINE OL02T

40

OL-ORACLE02T

PL/ SQL

Mdulo 2

Atributos de las Tablas Una tabla est compuesta por una serie de elementos y se puede recorrer con un ndice que no tiene por qu ser consecutivo. Es por ello que para poder recorrerla se necesitan una serie de atributos, para acceder a ellos: Nombre_tabla.atributo_al_que_acceder COUNT indica el nmero de elementos que una tabla contiene. Tabla1.count; DELETE Tabla1.delete elimina todos los elementos. Tabla1.delete(4) elimina un elemento determinado. Tabla1.delete(4,7) elimina un rango de elementos.. EXISTS devuelve true si un elemento de la tabla existe. Tabla1.exists(7); FIRST LAST NEXT PRIOR devuelve el ndice del primer elemento de la tabla devuelve el ndice del ltimo elemento de la tabla devuelve el ndice del elemento inmediatamente posterior al de ndice i devuelve el ndice del elemento inmediatamente anterior al de ndice i

MASTER ORACLE ONLINE OL02T

41

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejemplo de Tablas de registros SET SERVEROUTPUT ON DECLARE TYPE emp_table_type is table of employees%ROWTYPE INDEX BY BINARY_INTEGER; my_emp_table emp_table_type; v_count NUMBER(3) := 104; BEGIN FOR i IN 100 .. v_count LOOP SELECT INTO my_emp_table(i) FROM employees WHERE employee_id = i; -- ASUME QUE EXISTEN LOS EMPLEADOS CON NMEROS DEL 100 AL 104 -- SI NO ES AS, LA SELECT FALLARA END LOOP; FOR i IN my_emp_table.FIRST .. my_emp_table.LAST LOOP DBMS_OUTPUT.PUT_LINE(my_emp_table(i).last_name); END LOOP; END;

MASTER ORACLE ONLINE OL02T

42

OL-ORACLE02T

PL/ SQL

Mdulo 2

Cursores
Cuando se ejecuta una sentencia SQL el servidor abre un rea de memoria en la que el comando se lleva a cabo, esa rea es el cursor. Hay dos tipos de cursor:

Implcitos (abiertos por PL/SQL). Explcitos (declarados por el programador).

MASTER ORACLE ONLINE OL02T

43

OL-ORACLE02T

PL/ SQL

Mdulo 2

Cursores implcitos
Para manejar un cursor tenemos unos atributos: SQL%FOUND, Devuelve verdadero si el cursor tiene alguna fila, falso en caso contrario. SQL%NOTFOUND Verdadero si el cursor no ha devuelto ninguna fila. SQL%ROWCOUNT, nmero de filas al que afecta la operacin.

LA SENTENCIA SELECT..INTO NUNCA VA A SALIR POR SQL%NOTFOUND

Si una sentencia SELECT no encuentra filas genera una excepcin, que es un tipo de error que puede ser tratado o no, el error es NO_DATA_FOUND.

Oracle abre,cierra y trata los cursores, nosotros tratamos los atributos.

MASTER ORACLE ONLINE OL02T

44

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejemplo Cursor Implcito Doblar el salario al empleado 7902 si existe, si no existe se inserta en la tabla EMP

BEGIN UPDATE EMP SET SAL=SAL *2 WHERE EMPNO=7902; IF SQL%NOTFOUND THEN INSERT INTO EMP(EMPNO,ENAME,JOB) VALUES (1234,'LUIS ', 'ANALISTA '); END IF; END; /

MASTER ORACLE ONLINE OL02T

45

OL-ORACLE02T

PL/ SQL

Mdulo 2

Cursores explcitos
Es el mecanismo de PL/SQL para tratar individualmente el conjunto de filas recuperado por una sentencia SELECT. Es una estructura en memoria que recupera filas de 1 o varias tablas, donde se accede a los datos de forma secuencial. Los cursores se tratan de la siguiente forma: 1. Declaracin del cursor 2. Apertura del cursor 3. Recogida de datos en variables PL 4. Cierre del cursor. Son definidos por el programador.

MASTER ORACLE ONLINE OL02T

46

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ciclo de vida de un cursor:


Declaracin Para poder tratar una a una las filas, debemos declarar el cursor como si fuese una variable. En la declaracin, no se crea el cursor, ya que no se ejecuta sentencia alguna. CURSOR nombre_cursor IS sentencia_select; Es necesario declarar tambin una variable de cursor para posteriormente tratar los valores ledos. Ejemplo: DECLARE CURSOR C1 IS SELECT * FROM empleados WHERE salario BETWEEN 1000 AND 2000; VAR_C1 .... BEGIN .. C1%ROWTYPE;

MASTER ORACLE ONLINE OL02T

47

OL-ORACLE02T

PL/ SQL

Mdulo 2

Apertura Tras haberlo declarado, el cursor se abre con la sentencia OPEN nombre_cursor; dentro de la seccin ejecutable. Al abrir el cursor se ejecuta el SELECT y almacena el resultado en la memoria principal, el cursor queda apuntando a la primera fila. Se puede abrir un cursor varias veces seguidas, lo que servira para ver si ha habido actualizaciones. Ejemplo: DECLARE CURSOR C1 IS SELECT * FROM empleados WHERE salario BETWEEN 1000 AND 2000; VAR_C1 C1%ROWTYPE; .... BEGIN OPEN C1; ..

MASTER ORACLE ONLINE OL02T

48

OL-ORACLE02T

PL/ SQL

Mdulo 2

Extraccin La extraccin de las filas para su tratamiento se realiza con la clasula FETCH:

FETCH nombre_cursor INTO variable1 [,variable2,...]; coincidir. FETCH nombre_cursor INTO registro;

los tipos deben

Ejemplo: DECLARE CURSOR C1 IS SELECT * FROM empleados WHERE salario BETWEEN 1000 AND 2000; VAR_C1 C1%ROWTYPE; .... BEGIN OPEN C1; FETCH C1 INTO VAR_C1; .

MASTER ORACLE ONLINE OL02T

49

OL-ORACLE02T

PL/ SQL

Mdulo 2

Cierre Cuando se han recorrido todas las filas con FETCH, se debe cerrar el cursor para liberar memoria. La clusula CLOSE cierra el cursor. Ejemplo: DECLARE CURSOR C1 IS SELECT * FROM empleados WHERE salario BETWEEN 1000 AND 2000; VAR_C1 C1%ROWTYPE; .... BEGIN OPEN C1; FETCH C1 INTO VAR_C1; . CLOSE C1;

MASTER ORACLE ONLINE OL02T

50

OL-ORACLE02T

PL/ SQL

Mdulo 2

Atributos devuelve true si el ltimo FETCH efectuado devolvi una nueva fila, %FOUND false en caso contrario. devuelve true si el ltimo FETCH no devolvi una nueva fila, se %NOTFOUND utiliza frecuentemente para salir de bucles. %ISOPEN Devuelve verdadero si el cursor est abierto. Devuelve el n de filas extradas hasta el momento.

%ROWCOUNT

MASTER ORACLE ONLINE OL02T

51

OL-ORACLE02T

PL/ SQL

Mdulo 2

Bucles de cursores
Puesto que se trata de conjunto de filas se necesita un bucle para procesar las filas: tenemos que leer una fila tratarla, leer otra, tratarla, ect.. Existen tres tipos:

LOOP Bsico WHILE (requiere una lectura previa) FOR, es un atajo para procesar cursores, ya que implcitamente lo abre, trabaja con l, sale y lo cierra. El registro est declarado de manera implcita.

MASTER ORACLE ONLINE OL02T

52

OL-ORACLE02T

PL/ SQL

Mdulo 2

BUCLE LOOP

DECLARE --Primero declaramos el cursor. CURSOR C1 IS SELECT.. VAR_CI C1%ROWTYPE; --Defino la variable para guardar los datos del cursor BEGIN OPEN CI; --Abrimos el cursor LOOP --Leemos con el cursor la primera fila y la guardamos en la variable. FETCH C1 INTO VAR_CI; -- salir si no hay datos EXIT WHEN C1%NOTFOUND; --tambin es posible: [IF C1%NOFOUND THEN EXIT; END IF:] .... --tratamiento de filas END LOOP; --Cerramos el cursor CLOSE CI; ..

MASTER ORACLE ONLINE OL02T

53

OL-ORACLE02T

PL/ SQL

Mdulo 2

BUCLE WHILE En este tipo de bucle la condicin se evala al principio.

DECLARE --LA PARTE DECLARATIVA ES IGUAL AL OTRO TIPO DE BUCLE CURSOR C1 IS SELECT.. VAR_CI C1%ROWTYPE; --Defino la variable para guardar los datos del cursor BEGIN OPEN CI; --Abrimos el cursor --Leemos con el cursor la primera fila y la guardamos en la variable. FETCH C1 INTO VAR_CI; --Mientras encuentres datos se trabaja WHILE C1%FOUND LOOP --tratamiento de filas --Antes de salir volvemos a leer. FETCH C1 INTO VAR_CI; END LOOP;

--Cerramos el cursor CLOSE C1; ..

MASTER ORACLE ONLINE OL02T

54

OL-ORACLE02T

PL/ SQL

Mdulo 2

BUCLE FOR

En el bucle for, no se declara la variable de cursor. No se abre si se cierra, no se hace un FETCH, est implicito. No se comprueba si se ha llegado al final de los datos. Es el ms cmodo de los tres, pero no siemptre se puede utilizar.

DECLARE --LA PARTE DECLARATIVA ES IGUAL AL OTRO TIPO DE BUCLE CURSOR C1 IS SELECT.. BEGIN FOR V_C1 IN C1 LOOP .. END LOOP; ..

MASTER ORACLE ONLINE OL02T

55

OL-ORACLE02T

PL/ SQL

Mdulo 2

FOR Loops con Subconsultas No es necesario declarar el cursor BEGIN FOR emp_record IN (SELECT apellido, departamento FROM empleados) LOOP -- Implcitamente se abre y carga IF emp_record.departmento = 80 THEN ...... END LOOP; -- se produce el cierre implcito END;

MASTER ORACLE ONLINE OL02T

56

OL-ORACLE02T

PL/ SQL

Mdulo 2

Cursores Avanzados
Cursores con parmetros A los cursores se les pueden pasar parmetros en el momento de su apertura, de manera que se puedan abrir con distintos datos segn los parmetros pasados en diferentes aperturas. Es un cursor variable, cuya clusula where no es siempre la misma depende del valor de un parmetro. Se puede abrir y cerrar las veces que queramos, y cada vez con valores distintos. Se puede utilizar con parmetros y con variables en la clusula where. Ningn parmetro debe tener longitud ni precisin.

MASTER ORACLE ONLINE OL02T

57

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejemplo: Realizamos un tratamiento distinto para los empleados que ganen 1000 y otro diferente para los que ganen 5000. Primero lo abrimos y realizamos la primera operacin, cerramos y realizamos la segunda operacin. DECLARE CURSOR C1(PARAMETRO1 NUMBER) IS SELECT * FROM EMP WHERE SAL < PARAMETRO1; BEGIN OPEN C1(1000); . CLOSE C1; OPEN C1(5000); CLOSE C1; .

Con un bucle for, ni se abre ni se cierra, y sera: FOR V_C1 IN C1(3000) LOOP

MASTER ORACLE ONLINE OL02T

58

OL-ORACLE02T

PL/ SQL

Mdulo 2

Cursores de Actualizacin (FOR UPDATE)


La clusula FOR UPDATE bloquea las filas que se van a actualizar hasta que concluye la transaccin con COMMIT o ROLLBACK. DECLARE CURSOR mi_cursor IS SELECT FROM ALUMNOS FOR UPDATE; - - FOR UPDATE debe ser la ltima clasula en la sentencia BEGIN OPEN mi_cursor; Ejemplo: FOR UPDATE DECLARE CURSOR emp_cursor IS SELECT employee_id, last_name, department_name FROM employees, departments WHERE employees.department_id = departments.department_id AND employees.department_id = 80 FOR UPDATE OF salary; WHERE CURRENT OF Referencia la fila actual del cursor para proceder a su tratamiento sin tener que recurrir a su ndice. Se debe utilizar junto con FOR UPDATE para bloquear las filas. BEGIN FOR mi_registro IN mi_cursor LOOP UPDATE alumnos SET edad = edad + 1 WHERE CURRENT OF mi_cursor; END LOOP; COMMIT;

MASTER ORACLE ONLINE OL02T

59

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejemplos: Listar a los empleados de la tabla emp que sean analistas 1) Con bucle loop

Primero : SET SERVEROUTPUT ON;

DECLARE CURSOR C1 IS SELECT ENAME,SAL,JOB FROM EMP WHERE JOB='ANALYST'; VAR_CI C1%ROWTYPE; BEGIN OPEN C1; LOOP FETCH C1 INTO VAR_CI; DBMS_OUTPUT.PUT_LINE('ANALISTAS:' || VAR_CI. ENAME); EXIT WHEN C1%NOTFOUND; END LOOP; CLOSE C1; END; /

MASTER ORACLE ONLINE OL02T

60

OL-ORACLE02T

PL/ SQL

Mdulo 2

2) Con bucle WHILE

Primero : SET SERVEROUTPUT ON;

DECLARE CURSOR C1 IS SELECT ENAME,SAL,JOB FROM EMP WHERE JOB='ANALYST';

VAR_CI C1%ROWTYPE; BEGIN OPEN C1; FETCH C1 INTO VAR_CI; WHILE C1%FOUND LOOP DBMS_OUTPUT.PUT_LINE('ANALISTAS:' || VAR_CI.ENAME); FETCH C1 INTO VAR_CI; END LOOP; CLOSE C1; END; /

MASTER ORACLE ONLINE OL02T

61

OL-ORACLE02T

PL/ SQL

Mdulo 2

3) Con bucle FOR

Primero : SET SERVEROUTPUT ON;

DECLARE CURSOR C1 IS SELECT ENAME,SAL,JOB FROM EMP WHERE JOB='ANALYST'; BEGIN FOR VAR_C1 IN C1 LOOP DBMS_OUTPUT.PUT_LINE('ANALISTAS:' || VAR_C1.ENAME); END LOOP; END; /

MASTER ORACLE ONLINE OL02T

62

OL-ORACLE02T

PL/ SQL

Mdulo 2

Gestin de Excepciones
Manejando Excepciones Una excepcin es un identificador que se lanza durante la ejecucin. Se utilizan para controlar errores en tiempo de ejecucin. Si no se contemplan y la situacin de error se produce el programa falla. Existen las predefinidas por Oracle y las definidas por el programador. Hablaremos tambin de RAISE_APPLICATION_ERROR. Se lanzan:

Al producirse un error en tiempo de ejecucin (de manera implcita). Al lanzarse explcitamente (por el programador).

Para manejarla se puede: Atraparla con un manejador, contemplarla en el programa. Propagarla al bloque superior.

MASTER ORACLE ONLINE OL02T

63

OL-ORACLE02T

PL/ SQL

Mdulo 2

Caractersticas.

Excepciones predefinidas : estn recogidas en el paquete STANDARD as NO_DATA_FOUND, TOO_MANY_ROWS, ZERO_DIVIDE, INVALID_CURSOR etc. Excepciones definidas por el programador : se deben declarar explcitamente en la seccin DECLARE. Las excepciones se pueden producir en cualquier parte del programa. Slo se pueden tratar de manera adecuada en la parte de tratamiento de excepciones. El mbito es el del bloque en la que se produzcan.

MASTER ORACLE ONLINE OL02T

64

OL-ORACLE02T

PL/ SQL

Mdulo 2

Generacin Las excepciones predefinidas se elevan de forma automtica en el momento de producirse. Se paraliza la ejecucin y busca algn gestor de excepciones, aplicndolo o concluyendo la ejecucin en caso que no lo haya. Tratamiento Se tratan en el bloque EXCEPTION que puede contener un conjunto de gestores, cada uno orientado a una excepcin. EXCEPTION WHEN NO_DATA_FOUND THEN <sentencias> - - Gestor 1 WHEN mi_excepcion THEN <sentencias> - - Gestor 2 WHEN OTHERS THEN <sentencias> - - Gestor 3, en este caso el gestor por defecto. END;

Ejemplo excepciones del programador: Caractersticas: -Se deben de declarar, porque es algo que se define el programador. -Estn en la parte ejecutable del programa. -Se tratan en el bloque de excepciones.

MASTER ORACLE ONLINE OL02T

65

OL-ORACLE02T
Ejemplo:

PL/ SQL

Mdulo 2

Bloque PL para comprobar si existen nombres nulos en la tabla EMP. DECLARE CURSOR CUR1 IS SELECT ENAME,JOB,EMPNO FROM EMP; NOMBRE_NULO EXCEPTION; NUM_EMP EMP.EMPNO%TYPE; BEGIN FOR X IN CUR1 LOOP IF X.ENAME IS NULL THEN NUM_EMP :=X.EMPNO; --ROMPE EL FLUJO DEL PROGRAMA, SE VA A BUSCAR LA EXCEPCIN A LA --ZONA DE EXCEPCIONES RAISE NOMBRE_NULO; END IF; DBMS_OUTPUT.PUT_LINE('EMPLEADO NUMERO: ' || X.EMPNO); END LOOP; EXCEPTION WHEN NOMBRE_NULO THEN DBMS_OUTPUT.PUT_LINE('EMPLEADO NUMERO' || NUM_EMP || 'TIENE EL NOMBRE A NULOS '); --ES NECESARIO VOLCAR EL NOMBRE EN UNA VARIABLE NUM_EMP PORQUE --AL SALIR DEL BUCLE DEL CURSOR LA VARIABLE X PIERDE SU VALOR Y SU MBITO END; /

MASTER ORACLE ONLINE OL02T

66

OL-ORACLE02T

PL/ SQL

Mdulo 2

Excepciones de Oracle.
Son las predefinidas por Oracle. Las diferencia con las anteriores:

No se declaran, el motor de la base de datos las conoce. No se lanzan con Raise, el programa detecta la condicin de error

Tienen en comn en que se tratan en la zona de excepciones, como las anteriores.

Listado de las ms usadas.

CURSOR_ALREADY_OPEN, si est ya abierto el cursor. DUP_VAL_ON_INDEX, valor duplicado en ndice, intentar insertar una fila duplicada en una columna indexada con un ndice nico. INVALID_CURSOR, ejecutar una operacin con un cursor cerrado. INVALID_NUMBER, se intenta convertir una cadena de caracteres a un numero. LOGON_DENIED, conexin a Oracle denegada, porque usuario o contrasea son incorrectos. NO_DATA_FOUND, Ejecutar una sentencia select que no devuelve ninguna fila, ejemplo: busco al empleado que gana ms de 6000 euros al mes. TOO_MANY_ROWS, Ejecutar una select que devuelve ms de una fila, buscar a los empleados que ganan entre 1000 y 1500 euros al mes.

MASTER ORACLE ONLINE OL02T

67

OL-ORACLE02T

PL/ SQL

Mdulo 2

NOT_LOGED_ON, acceder a la base de datos sin haber iniciado la sesin. STORAGE_ERROR, pl se queda sin memoria ejecutando una sentencia. TIMEOUT_ON_RESOURCE, se acaba el tiempo de espera para un determinado recurso. TRANSACTION_BACKED_OUT, una transaccin por el motivo que sea no se completa. VALUE_ERROR, error aritmtico de conversin o de truncado. ZERO_DIVIDE, cuando se intenta dividir por cero.

MASTER ORACLE ONLINE OL02T

68

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejemplo Pedir dos nmeros por pantalla para realizar una divisin. Se contempla que el divisor pueda ser 0. DECLARE --EJEMPLO DE EXCEPCION PREDEFINIDA POR ORACLE(ZERO DIVIDE) NUM1 NUMBER(2):=&NUMERO1; NUM2 NUMBER(2):=&NUMERO2; RESUL NUMBER(5,2);

BEGIN RESUL :=NUM1/NUM2; DBMS_OUTPUT.PUT_LINE('NUM1/NUM2 = ' || RESUL); EXCEPTION WHEN ZERO_DIVIDE THEN DBMS_OUTPUT.PUT_LINE('IMPOSIBLE DIVIDIR POR 0'); END; /

MASTER ORACLE ONLINE OL02T

69

OL-ORACLE02T

PL/ SQL

Mdulo 2

WHEN OTHERS
Existen ocasiones donde no nos interesar contemplar las excepciones una a una. Para ello existe una excepcin genrica OTHERS donde el programa bifurca cuando se produzca una condicin de error. Ejemplo: EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('SE HA PRODUCIDO UN ERROR');

SQLCODE, SQLERRM
Es posible saber en que acceso se ha producido el error, y tambin podemos saber el cdigo y el mensaje de error, accediendo a las variables: SQLCODE SQLERRM Cada error tiene su cdigo interno y su texto de error.

MASTER ORACLE ONLINE OL02T

70

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejemplo: Repitamos el anterior pero utilizando la excepcin genrica WHEN OTHERS. DECLARE V_NOMBRE EMP.ENAME%TYPE; V_EMPNO EMP.EMPNO%TYPE:=&EMPNO; V_CODIGO NUMBER; V_MENSAJE VARCHAR2(60); BEGIN SELECT ENAME INTO V_NOMBRE FROM EMP WHERE EMPNO=V_EMPNO; DBMS_OUTPUT.PUT_LINE('NOMBRE: ' || V_NOMBRE); EXCEPTION WHEN OTHERS THEN V_CODIGO:=SQLCODE; V_MENSAJE:=SUBSTR(SQLERRM,1,60); DBMS_OUTPUT.PUT_LINE('SE HA PRODUCIDO UN ERROR' || V_CODIGO || ' '|| V_MENSAJE); END; /

MASTER ORACLE ONLINE OL02T

71

OL-ORACLE02T
Propagacin

PL/ SQL

Mdulo 2

Si se produce una excepcin en un bloque interno y no es tratada en l, se transmite al bloque inmediatamente superior para su tratamiento.

RAISE_APPLICATION_ERROR
Este procedimiento se puede utilizar para propagar mensajes de error personalizados desde subprogramas almacenados. Tiene como caracterstica que para la ejecucin del programa all donde sea invocado. Tiene dos argumentos: un cdigo que va desde -20000 hasta -20999 y un texto de error. Las usaremos mas adelante en triggers. Ejemplo: BEGIN DELETE FROM EMP WHERE EMPNO= &NUMERO; IF SQL%NOTFOUND THEN RAISE_APPLICATION_ERROR (-20300, EL EMPLEADO NO EXISTE); END IF; END; /

MASTER ORACLE ONLINE OL02T

72

OL-ORACLE02T

PL/ SQL

Mdulo 2

Subprogramas
Un subprograma es un bloque PL / SQL nominado, que puede aceptar parmetros y ser invocado desde un entorno llamante. Provee modularidad (al estar basado en bloques PL / SQL), reusabilidad (al ser almacenable) y facilidad de mantenimiento. Tipos:

Procedimientos, que realizan una accin. Funciones, que computan y devuelven un solo valor. Paquetes, conjunto de procedimientos y funciones (admiten otros objetos) Triggers, son especiales porque estn asociados a una tabla y a una accin sobre esa tabla.

MASTER ORACLE ONLINE OL02T

73

OL-ORACLE02T

PL/ SQL

Mdulo 2

Funciones
Una funcin es un bloque nominado PL / SQL que devuelve un valor. Una funcin puede ser almacenada en una base de datos como un objeto para su reutilizacin continuada. Si la funcin est almacenada se denomina global y puede ser compartida por otros usuarios de la base de datos. Si no est almacenada se llama local y entonces forma parte de otra unidad de programacin pero no es independiente. Veremos un ejemplo ms adelante. Una funcin es llamada como parte de una expresin. Sintaxis de Creacin Funcin Global CREATE [OR REPLACE] FUNCTION nombre [(parametro1 [MODO] tipo, parametro2 [MODO] tipo,....)] RETURN tipo tipo de dato del valor devuelto IS | AS equivalente a DECLARE en un pl annimo Bloque PL/SQL; Existen en general, 3 tipos de parmetros: IN (entrada), OUT (salida), INOUT(entrada/salida) Puesto que las funciones devuelven valores a travs de la clusula RETURN slo . deberan declararse parmetros IN El bloque PL / SQL debe contener al menos una sentencia RETURN. Tras compilar SHOW ERRORS mostrara posibles errores de compilacin.

MASTER ORACLE ONLINE OL02T

74

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejemplo: CREATE OR REPLACE FUNCTION obten_sueldo (p_id IN empl.empno%TYPE) RETURN NUMBER IS v_sueldo emp.sal%TYPE : = 0; BEGIN SELECT sal INTO v_sueldo FROM empl WHERE empno = p_id; RETURN v_sueldo; END obten_sueldo; /

MASTER ORACLE ONLINE OL02T

75

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejecucin
Las funciones se invocan como parte de una expresin PL / SQL. Se debe crear una variable para recoger el valor devuelto por la funcin. Ejemplos de llamada: 1) A travs de la tabla dual: SQL> SELECT OBTEN_SUELDO(7902) FROM DUAL; devuelve el resultado por pantalla

2) Dentro de otro programa pl: DECLARE CUANTO_GANA NUMBER; BEGIN CUANTO_GANA:= OBTEN_SUELDO(&NUMERO_EMP); DBMS_OUTPUT.PUT_LINE(GANA || CUANTO_GANA); END; /

MASTER ORACLE ONLINE OL02T

76

OL-ORACLE02T

PL/ SQL

Mdulo 2

Localizacin de las Llamadas


Clasulas SELECT. Condiciones en las clasulas WHERE y HAVING. Comandos CONNECT BY, START WITH, ORDER BY y GROUP BY. En la parte VALUES de una orden INSERT. En la seccin SET de un comando UPDATE.

Restricciones en el Uso
Para poder ser invocadas desde expresiones SQL, una funcin definida por el usuario debe:

Ser una funcin almacenada. Aceptar nicamente parmetros IN. Aceptar nicamente tipos de datos vlidos para SQL, no tipos especficos de PL / SQL como son los parmetros. Devolver tipos de datos vlidos para SQL. Funciones llamadas desde sentencias UPDATE / DELETE en una tabla T no pueden contener DML, ni hacer consultas sobre la misma tabla T. Las funciones llamadas no pueden contener sentencias que finalicen las transacciones. Llamadas a subprogramas que contravengan estas limitaciones provocaran excepciones.

MASTER ORACLE ONLINE OL02T

77

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejemplo: CREATE OR REPLACE FUNCTION va_dar_error (p_sal NUMBER) RETURN NUMBER IS BEGIN INSERT INTO empleados (nuempl, apellido, feching, nombre) VALUES (00120, Perez,14-NOV-2001, Jose); RETURN (p_sal + 100); END va_dar_error; / UPDATE empleados SET salar = va_dar_error(12300) WHERE nuempl = 00152; ERROR at line 1 ORA-04091 table EMPLEADOS is mutating....

MASTER ORACLE ONLINE OL02T

78

OL-ORACLE02T

PL/ SQL

Mdulo 2

Eliminacin
Para borrar una funcin de la base de datos: Sintaxis: DROP FUNCTION nombre_funcion Ejemplo: DROP FUNCTION va_dar_error;

MASTER ORACLE ONLINE OL02T

79

OL-ORACLE02T

PL/ SQL

Mdulo 2

Funciones locales
Ejemplo: FUNCTION SUMAR (N1 IN NUMBER,N2 IN NUMBER) RETURN NUMBER IS -- ESTE IS ES COMO EL DECLARE DE UN BLOQUE PL, ES DECIR, DEBAJO DE -- EL Y ANTES DEL BEGIN VAN LAS VARIABLES DEL BLOQUE V_RESUL NUMBER(4); BEGIN V_RESUL := N1+N2; RETURN (V_RESUL); -- PODRIA SER TAMBIEN, RETURN N1+N2 END SUMAR; /

MASTER ORACLE ONLINE OL02T

80

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejecucin: Con un bloque pl. Recordar que no est almacenada en la bd, est dentro de otro programa! DECLARE NUM1 NUMBER(2):=&NUMERO1; NUM2 NUMBER(2):=&NUMERO2; V_RESULTADO NUMBER (4); FUNCTION SUMAR (N1 IN NUMBER,N2 IN NUMBER) RETURN NUMBER IS V_RESUL NUMBER(4); BEGIN V_RESUL := N1+N2; RETURN (V_RESUL); -- PODRIA SER TAMBIEN, RETURN N1+N2 END SUMAR;

BEGIN -- DEL BLOQUE PL V_RESULTADO:=SUMAR(NUM1,NUM2); DBMS_OUTPUT.PUT_LINE('EL RESULTADO ES '|| V_RESULTADO); END; /

MASTER ORACLE ONLINE OL02T

81

OL-ORACLE02T

PL/ SQL

Mdulo 2

Procedimientos
Un procedimiento es un bloque nominado PL / SQL que puede devolver de 0 a n valores. Un procedimiento puede ser almacenado en una base de datos como un objeto para su reutilizacin continuada. Si est almacenado se denomina global y puede ser compartido por otros usuarios de la base de datos. Si no est almacenado se llama local y entonces forma parte de otra unidad de programacin pero no es independiente. Veremos un ejemplo ms adelante.

Sintaxis de Creacin Procedimiento Global


CREATE [OR REPLACE] PROCEDURE nombre [(parametro1 [IN | OUT | IN OUT] tipo, parametro2,...)] IS | AS equivalente a DECLARE en un pl annimo Bloque PL / SQL; Existen en general, 3 tipos de parmetros: IN (entrada), OUT (salida), INOUT(entrada/salida) Tras compilar SHOW ERRORS mostrara posibles errores de compilacin.

MASTER ORACLE ONLINE OL02T

82

OL-ORACLE02T

PL/ SQL

Mdulo 2

Tipos de Parmetros Parmetros IN


CREATE OR REPLACE PROCEDURE subir_salario (p_nuempl IN empleados.nuempl%TYPE) IS BEGIN UPDATE empleados SET salar = salar 1.1 WHERE nuempl = p_nuempl; END subir_salario; /

Parmetros OUT
CREATE PROCEDURE cuadrado_cubo (p_numero IN NUMBER , p_cuadrado OUT NUMBER, p_cubo OUT NUMBER) IS BEGIN p_cuadrado : = p_numero* p_numero; p_cubo : = p_cuadrado * p_numero; END cuadrado_cubo; /

Sin parmetros
CREATE OR REPLACE PROCEDURE poner_departamentos (p_nombre IN departamentos.nomdep%TYPE DEFAULT Innominioso, p_numero IN departamentos.numdep%TYPE DEFAULT A01) IS BEGIN INSERT INTO departamentos (NUMDEP,NOMDEP) VALUES (p_numero, p_nombre); END poner_departamentos; /

MASTER ORACLE ONLINE OL02T

83

OL-ORACLE02T

PL/ SQL

Mdulo 2

Formato de Paso de Parmetros


BEGIN poner_departamentos; poner_departamentos (Formacin, F99); poner_departamentos (p_numero => AAA, p_nombre =>Domingo); poner_departamentos(p_numeros => BBB); END; / SELECT numdep, nomdep FROM departamentos;

Llamadas:
1) Desde bloques annimos BEGIN SUBIR_SALARIO(&NUMEMP,&SALARIO); ....... END; 2) Desde sql*plus: SQL> EXECUTE SUBIR_SALARIO(7902, 200);

MASTER ORACLE ONLINE OL02T

84

OL-ORACLE02T

PL/ SQL

Mdulo 2

Procedimientos locales
Ejemplo: DECLARE NUM1 NUMBER(2) := &NUMERO1;

NUM2 NUMBER(2) := &NUMERO2; V_RESUL NUMBER(4); PROCEDURE MULTIPLICAR (N1 IN NUMBER, N2 IN NUMBER,N3 OUT NUMBER) IS BEGIN N3:= N1 * N2; END MULTIPLICAR; BEGIN MULTIPLICAR(NUM1,NUM2,V_RESUL); DBMS_OUTPUT.PUT_LINE('EL RESULTADO ES ' || V_RESUL); END; / Es similar a lo dicho en funciones.

MASTER ORACLE ONLINE OL02T

85

OL-ORACLE02T

PL/ SQL

Mdulo 2

Eliminacin Para borrar un procedimiento de la base de datos:

Sintaxis DROP PROCEDURE nombre_procedimiento; Ejemplo DROP PROCEDURE poner_departamentos;

MASTER ORACLE ONLINE OL02T

86

OL-ORACLE02T

PL/ SQL

Mdulo 2

Paquetes
Agrupan lgicamente subprogramas, tipos PL / SQL y elementos que son homogneos. Consiste en dos partes:

Especificacin (cabecera) Cuerpo, desarrollo de los componentes declarados en la cabecera.

A diferencia de los procedimientos y funciones, los paquetes no pueden estar contenidos dentro de un bloque local, slo se pueden almacenar en la base de datos. Se compilan y se almacenan por separado. La especificacin de un paquete puede existir sin su cuerpo, pero lo contrario es imposible.

Sintaxis de la cabecera
CREATE [OR REPLACE] PACKAGE nombre IS | AS declaraciones de elementos y tipos especificacin de subprogramas END nombre; Las variables declaradas en la especificacin del paquete se inicializan como NULL por defecto. Todos los elementos declarados en el paquete son visibles a los usuarios con los privilegios concedidos para ello.

Sintaxis del Cuerpo


CREATE OR REPLACE PACKAGE BODY nombre IS | AS declaracin de tipos y elementos privados cuerpo de subprogramas END nombre;

MASTER ORACLE ONLINE OL02T

87

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejemplo: Parte declarativa de un paquete CREATE OR REPLACE PACKAGE EJEMPLO_PAQ IS PROCEDURE MULTIPLICAR (N1 IN NUMBER, N2 IN NUMBER); FUNCTION SUMAR(N1 IN NUMBER,N2 IN NUMBER) RETURN NUMBER; END EJEMPLO_PAQ;

Parte ejecutable de un paquete CREATE OR REPLACE PACKAGE BODY EJEMPLO_PAQ IS FUNCTION SUMAR(N1 IN NUMBER,N2 IN NUMBER) RETURN NUMBER IS V_RESUL NUMBER(4);

BEGIN V_RESUL := N1+N2 RETURN (V_RESUL); END SUMAR; PROCEDURE MULTIPLICAR (N1 IN NUMBER, N2 IN NUMBER,N3 OUT NUMBER) IS BEGIN N3:= N1 * N2; END MULTIPLICAR; END EJEMPLO_PAQ;

MASTER ORACLE ONLINE OL02T

88

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejecutar un procedimiento o funcin de un paquete


1.Ejecucin de un procedimiento desde sqlplus: EXEC EJEMPLO_PAQ.MULTIPLICAR(2,9); 2.Ejecucin de una funcin de un paquete DECLARE NUM1 NUMBER:=&NUM1; NUM2 NUMBER:=&NUM2; V_RESULTADO NUMBER; BEGIN V_RESUTADO:=EJEMPLO_PAQ.SUMAR(NUM1,NUM2); DBMS_OUPUT.PUT_LINE ('EL RESUTADO ES' ||V_RESULT); END;

MASTER ORACLE ONLINE OL02T

89

OL-ORACLE02T

PL/ SQL

Mdulo 2

Eliminacin Para eliminar tanto el cuerpo como la especificacin: DROP PACKAGE mi_paquete; Para eliminar slo el cuerpo: DROP PACKAGE BODY mi_paquete;

MASTER ORACLE ONLINE OL02T

90

OL-ORACLE02T

PL/ SQL

Mdulo 2

Triggers
En esta seccin veremos triggers que son bloques o procedimientos PL / SQL asociados a una tabla. Se disparan al producirse un evento (sentencia DML) sobre una tabla. Se asemejan con los procedimientos y funciones en que son bloques PL/SQL nominados con secciones declarativa, ejecutable y de manejo de excepciones y en que se almacenan en la base de datos. Se diferencian en que se ejecutan implcitamente cuando se ejecuta una sentencia de manipulacin de datos sobre una tabla (INSERT, UPDATE, DELETE), y en que el disparador no admite argumentos. Existen otros tipos de triggers que no sern vistos en esta seccin.

MASTER ORACLE ONLINE OL02T

91

OL-ORACLE02T

PL/ SQL

Mdulo 2

Uso de Triggers
Los disparadores se utilizan principalmente para:

Para el mantenimiento de restricciones de integridad complejas, que no sean posibles con las restricciones declarativas definidas en el momento de crear la tabla. En auditora de la informacin contenida en la tabla, registrando los cambios realizados y la identidad de quien lo llev a cabo. El aviso automtico a otros programas de que hay que llevar a cabo una determinada accin, cuando se realiza un cambio en la tabla.

MASTER ORACLE ONLINE OL02T

92

OL-ORACLE02T

PL/ SQL

Mdulo 2

Timing de los triggers

BEFORE: se ejecuta antes que el evento DML que ha lo ha lanzado. AFTER: se ejecuta despus que el evento que lo origina. INSTEAD OF; se ejecuta el cuerpo del trigger en vez de la sentencia que lo lanza. Se emplea en vistas que no son modificables de otra manera. No es muy comn.

MASTER ORACLE ONLINE OL02T

93

OL-ORACLE02T

PL/ SQL

Mdulo 2

Tipos de trigger
La tipologa depende de la frecuencia con la que queremos que se ejecute, as:

A nivel de sentencia: el cuerpo del trigger se ejecuta una nica vez al producirse el evento. Es el por defecto. Se dispara aunque no haya filas afectadas. A nivel de fila: el cuerpo se ejecuta una vez por cada fila afectada por el evento, no se dispara si el evento no afecta a fila alguna.

Secuencia de disparo
En caso de concurrencia de eventos, la secuencia de disparo los triggers, sera:


RESTRICCIONES

BEFORE statement trigger BEFORE row trigger (n veces) AFTER row trigger (n veces) AFTER Statement trigger

Hay determinadas expresiones que no se pueden poner en el cuerpo de un TRIGGER:

COMMIT, ROLLBACK, SAVEPOINT. No pueden realizar modificaciones de datos (INSERT, UPDATE, DELETE) sobre una tabla mutante (aquella que est siendo modificada por la instruccin que dispar el TRIGGER).

MASTER ORACLE ONLINE OL02T

94

OL-ORACLE02T

PL/ SQL

Mdulo 2

Una sentencia de trigger DML contiene:

Condicin de tiempo : BEFORE, AFTER Un evento: INSERT, UPDATE o DELETE. Una tabla: ON nombre_tabla | nombre_vista. Un tipo: sentencia o fila. Una clasula WHEN : condicin restrictiva. El cuerpo del trigger. CREATE [OR REPLACE] TRIGGER nombre timing event1 [OR event2] [OR event3] ON nombre_tabla trigger_body

Los nombres de los triggers deben ser nicos con respecto a otros triggers del mismo esquema.

MASTER ORACLE ONLINE OL02T

95

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ejemplos: Disparador de sentencia: CREATE OR REPLACE TRIGGER EJEMPLO1 AFTER INSERT ON DEPT BEGIN -- DISPARADOR DE SENTENCIA DBMS_OUTPUT.PUT_LINE('SE HA INSERTADO UN REGISTRO'); END; / Disparador de fila: OLD y NEW En un trigger a nivel de fila, se puede referenciar el valor de una columna antes y despus del cambio de datos. CREATE OR REPLACE TRIGGER EJEMPLO2 BEFORE UPDATE ON DEPT FOR EACH ROW BEGIN DBMS_OUTPUT.PUT_LINE('SE SUSTITUIRA LA SIGUIENTE FILA: '); DBMS_OUTPUT.PUT_LINE(:OLD.DEPTNO || ' ' || :OLD.DNAME ||' '|| :OLD.LOC); DBMS_OUTPUT.PUT_LINE('POR ESTA OTRA:'); DBMS_OUTPUT.PUT_LINE(:NEW.DEPTNO ||' '||:NEW.DNAME||' '||:NEW.LOC); END; / --DISPARADOR DE FILA

MASTER ORACLE ONLINE OL02T

96

OL-ORACLE02T

PL/ SQL

Mdulo 2

Restricciones a nivel de fila


Para restringir la accin del trigger a aquellas filas que satisfagan una determinada condicin se emplea la clusula WHEN CREATE OR REPLACE TRIGGER tigre2 BEFORE INSERT OR UPDATE OF salary ON employees FOR EACH ROW WHEN (NEW.job_id = SA_REP) BEGIN IF INSERTING THEN :NEW.commission_pct := 0; ELSIF :OLD.commission_pct IS NULL THEN :NEW.commission_pct := 0; ELSE :NEW.commission_pct := :OLD.commission_pct + 0.05; END IF; END;

MASTER ORACLE ONLINE OL02T

97

OL-ORACLE02T

PL/ SQL

Mdulo 2

Gestin de Triggers
Al crearse un TRIGGER se activa, se puede desactivar con la orden: SQL> ALTER TRIGGER Vigila DISABLE; Se puede volver a activar: SQL> ALTER TRIGGER Vigila ENABLE; La tabla USER_TRIGGERS es til para conseguir informacin sobre los disparadores. SQL> SELECT TRIGGER_NAME, TRIGGER_TYPE , TRIGGERING_EVENT FROM USER_TRIGGER;

Borrado La clasula DROP permite eliminar un trigger de la base de datos: DROP TRIGGER Vigila;

MASTER ORACLE ONLINE OL02T

98

OL-ORACLE02T

PL/ SQL

Mdulo 2

Ms acerca de triggers
Integridad de los datos con triggers Los triggers pueden complementar las herramientas propias del sistema, dando valores por defecto, implementando chequeos adicionales,... CREATE OR REPLACE TRIGGER check_salary BEFORE UPDATE OF salary ON employees FOR EACH ROW WHEN (NEW.salary < OLD.salary) BEGIN RAISE_APPLICATION_ERROR(-20508,No bajar el salario); END;

MASTER ORACLE ONLINE OL02T

99

Potrebbero piacerti anche