You are on page 1of 47

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Introduccin a PL/SQL
PL/SQL es un lenguaje de programacin estructurado. Es un lenguaje procedimental que ampla la funcionalidad de SQL, aadiendo estructuras habituales en otros lenguajes de programacin, entre las que se encuentran:
Variables y Tipos

Estructuras de control Procedimientos y Funciones Tipos de Objetos y Mtodos. La unidad bsica en PL/SQL es el bloque. Todos los programas PL/SQL estn compuestos por bloques que pueden estar anidados. Un bloque PL/SQL est compuesto de tres partes principales: Seccin declarativa (opcional). Contiene las variables, constantes ... Seccin ejecutable (obligatoria). Contiene rdenes SQL para manipular datos De la base de datos y rdenes PL/SQL para manipular los datos del bloque Seccin de excepciones (opcional). Especifica las acciones a realizar en caso de error o cuando se producen excepciones en la ejecucin. La estructura general es: [DECLARE variables, constantes, excepciones de usuario...] BEGIN rdenes SQL rdenes PL/SQL [EXCEPTION acciones a realizar al ocurrir un error] END; / Para ejecutar un bloque PL/SQL siempre hay que colocar al final la barra /.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Podemos crear diferentes tipos de bloques: Bloques annimos: Se construyen de forma dinmica y se suelen ejecutar una sola vez. Bloques nominados: Igual que los annimos pero con una etiqueta que les da nombre. Subprogramas: Procedimientos, paquetes y funciones, almacenados en la base de datos y que se ejecutan en mltiples ocasiones. Los subprogramas se ejecutarn mediante una llamada. Disparadores (Triggers): Bloques nominados que se almacenan en la base de datos y que se ejecutan ante algn suceso. Para poner nombre a un bloque se le pone una etiqueta antes del DECLARE encerrado por <<...>>. Por ejemplo para darle el nombre Mi_Bloque a un bloque PL/SQL pondramos: <<Mi_Bloque>> DECLARE BEGIN END; /

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Declaracin de Identificadores PL/SQL


Variables Identificadores Un identificador es un nombre para las unidades de PL/SQL, las cuales pueden ser:

Constantes Variables Excepciones Cursores Variables de cursor Sub programas

Paquetes

Un identificador consiste de letras seguidas de manera opcional por ms letras, numerales, underscores, hasta un mximo de 30 caracteres adems que debe comenzar con una letra. Otros caracteres como guiones (-), diagonales (/) y espacios no son aceptados. Ejemplos invlidos: Hombre&mujeres: no es valido por el ampersand. Debito-total: no es valido por el guin. On/off: no es valido por la diagonal. User id: no es valido por los espacios. ` Ejemplos validos: Total$endolares No#Emp User_id

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

El nombre del identificador puede ir en maysculas o minsculas, para PL/SQL no hay diferencia al respecto. Los siguientes significan lo mismo: Apellido_parterno APELLIDO_PATERNO

Palabras reservadas Algunos identificadores llamados palabras reservadas tienen un significado especial para PL/SQL. Por ejemplo las palabras BEGIN y END son reservadas.

Identificadores entre comillas Para flexibilidad PL/SQL permite tener identificadores entre comillas. Ejemplos: X+Y apellido paterno on/off Aunque anterior mente se menciono que no era posible tener caracteres raros en el nombre, en el caso que se utilice un identificador entre comillas este puede contener cualquier carcter. Las variables se definen en la seccin declarativa de los bloques PL/SQL dnde tambin pueden inicializarse. La asignacin de nuevos valores a las variables puede hacerse en la parte ejecutable del bloque.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Pueden utilizarse para pasar valores como argumentos a subprogramas. Estas podrn ser de tipo IN (variable de entrada, OUT, variable de salida o INOUT, variable de entrada/salida). Tambin podrn utilizarse para almacenar valores devueltos o requeridos por una orden SQL. Todas las variables tienen un tipo. Los posibles tipos de una variable son: Escalar. Almacenan un valor nico. Son los mismos que los de las columnas de las tablas (VARCHAR2, NUMBER, DATE, CHAR, LONG, LONG_RAW, BINARY_INTEGER, LAW_INTEGER) ms el BOOLEAN Compuesto. Grupos de datos: tablas PL/SQL, registros... Puntero. Designan elementos de otros programas. LOB (Large OBjects). Almacenan gran cantidad de informacin. Las variables de tipo LOB permiten almacenar datos no estructurados (imgenes, texto...) de hasta 4 GB de tamao Declaracin de variables Sintaxis: <identificador> [CONSTANT] <tipo_de_dato> [NOT NULL] [{:= | DEFAULT <expresin>}]; Ejemplo: DECLARE fecha DATE; dep_num NUMBER(2) NOT NULL := 10; ciudad VARCHAR2(10) := Ciudad Real; Km_a_milla CONSTANT NUMBER := 1.4; Las variables declaradas como NOT NULL siempre deben ser inicializadas. La inicializacin puede hacerse utilizando := o la palabra reservada DEFAULT.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Si una variable no se inicializa contendr el valor NULL. Las constantes deben ser inicializadas. Asignacin de valores a variables Sintaxis: <identificador> := <valor>; Atributo %TYPE El atributo %TYPE se utiliza para declarar una variable con el mismo tipo que una columna de una tabla o que otra variable definida anteriormente. Sintaxis: <identificador> {<tabla>.<columna> | <nombre_variable>}%TYPE; Ejemplo: var_nombre Empleados.nombre%TYPE; balance NUMBER; balance_minimo balance%TYPE := 10; Variables BOOLEANAS Las variable BOOLEANAS pueden tomar el valor TRUE, FALSE o NULL. Las variables pueden combinarse mediante operadores lgicos (NOT, AND, OR). Las expresiones pueden devolver valores BOOLEANOS utilizando operadores relacionales (<, <=...).

Expresiones y operadores.
Al igual que otros lenguajes la unin de variables mediante operadores aritmticos y lgicos forman las expresiones aritmticas y lgicas a continuacin estos operadores

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Operador de asignacin Operadores aritmticos

:= (dos puntos + igual) + (suma) - (resta) * (multiplicacin) / (divisin) ** (exponente)

Operadores relacionales o de comparacin

= (igual a) <>,!= (distinto de) < (menor que) > (mayor que) >= (mayor o igual a) <= (menor o igual a)

Operador de concatenacin Comentarios

|| /* comentario de dos o ms lneas */ -- comentario de una lnea

Identificacin de Estructura de Bloque PL/SQL


Estructuras de control.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Estructura de Seleccin IF. Su Sintaxis es la siguiente: IF <expresin1> THEN <Secuencia_ordenes1>; [ELSIF <expresin2> THEN <Secuencia_ordenes2>;] . [ELSE <Secuencia_ordenesN>;] END IF; Ejemplo: SET ServerOutput ON; SET VERIFY OFF; DECLARE v_num NUMBER := &v; BEGIN IF v_num < 50 THEN DBMS_OUTPUT.PUT_LINE('Valor pequeo'); ELSIF v_num < 100 THEN DBMS_OUTPUT.PUT_LINE('Valor mediano'); ELSE DBMS_OUTPUT.PUT_LINE('Valor grande'); END IF; END; / Orden LOOP

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Los bucles LOOP son bucles que se utilizan para ejecutan instrucciones repetitivas, para salir de ellos tendremos que poner una instruccin de salida dentro del bucle. Su Sintaxis es: LOOP [EXIT WHEN <condicin>] END LOOP; Ejemplo: SET ServerOutput ON; SET VERIFY OFF; DECLARE num NUMBER :=1; BEGIN LOOP DBMS_OUTPUT.PUT_LINE('Valor: '|| num); num := num +1; EXIT WHEN num > 10; END LOOP; END; / rden FOR Los bucles FOR se repiten un nmero determinado de veces. Sintaxis: FOR <contador> IN <min>..<max> [REVERSE] LOOP ... END LOOP; Ejemplo: SET ServerOutput ON; SET VERIFY OFF; DECLARE num NUMBER; BEGIN

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

FOR num IN 1..10 LOOP DBMS_OUTPUT.PUT_LINE('Valor: '|| num); END LOOP; END; / rden WHILE Los bucles WHILE son iguales que en otro lenguajes de programacin. Sintaxis: WHILE <condicion> LOOP ... END LOOP; Ejemplo: SET ServerOutput ON; SET VERIFY OFF; DECLARE num NUMBER:=1; BEGIN WHILE num <=10 LOOP DBMS_OUTPUT.PUT_LINE('Valor: '|| num); num := num + 1; END LOOP; END; /

Tipos de datos compuestos


Los tipos de datos compuestos o colecciones pueden ser o bien registros PL/SQL o bien tablas PL/SQL REGISTRO PL/SQL Un registro PL/SQL es un grupo de elementos de datos relacionados en campos. Cada uno con su propio nombre. Caractersticas

Cada registro debe tener al menos un campo y tantos como sea necesario

Un registro NO es una fila de una tabla de sql Son tratados como unidades lgicas

Fundacin Cdigo Libre


www.codigolibre.org

Lic. Alfredo Leger

Son apropiados para recuperar el contenido de una fila de una tabla sql. Son tipos de variables. Por lo que hay que declarar primero el tipo de variable para despus poder usarla

SINTAXIS TYPE nombre IS RECORD (DECLARACIN DE CAMPOS) donde (declaracin de campos) es: nombre_de_campo {tipo de dato} donde {tipo de dato} puede ser: nombre_de_campo{tipo de dato | variable%TYPE | tabla.columna%TYPE| tabla%ROWTYPE} [ [NOT NULL]{:= | DEFAULT} expresion]

EJEMPLO DECLARE TYPE currante_tipo_de_record IS RECORD (nombre varchar2(20), curro varchar2(10), cobra number(7,2)); -- hasta aqui he declarado el tipo de variable currantes currante_tipo_de_record ; -- aqui uso la variable BEGIN SELECT first_name, job_id, salary INTO currantes FROM employees WHERE employee_id = 200; END; / ESTRUCTURA DEL REGISTRO PL/SQL A los campos de un registro pl/sql se accede por el nombre. As en el registro usado en el ejemplo anterior se accedera mediante currantes.cobra. %ROWTYPE Es lo mismo que %TYPE pero en este caso sirve para declarar que una variable es igual que una lnea de una tabla. O sea, que la variable contiene tantos campos y del mismo tipo que una tabla. Tiene la ventaja que no tienes que declarar el tipo de variable y puedes usarlo directamente. Adems de

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

estar seguro de que no vas a tener problemas de tipos distintos entre el origen de los datos y tu registro EJEMPLO DECLARE currantes employees%ROWTYPE; -- aqui uso la variable BEGIN SELECT * INTO currantes FROM employees WHERE employee_id = 200; END; / TABLAS PL/SQL Una tabla PL/SQL es un como una tabla normal de la base de datos con las siguientes caractersticas

Debe contener una clave primaria del tipo BINARY_INTEGER

Debe contener una columna de tipo escalar o de registro

SINTAXIS TYPE nombre_de_tipo_de_tabla IS TABLE OF {tipo de columna | variable%TYPE | tabla.columna%TYPE }[NOT NULL] INDEX BY BINARY_INTEGER; EJEMPLO SET PAGESIZE 100000 DECLARE TYPE tabla_como_empleados IS TABLE OF employees%ROWTYPE INDEX BY BINARY_INTEGER; currelas tabla_como_empleados; c_max INTEGER; BEGIN select count(*) into c_max from employees; DBMS_OUTPUT.PUT_LINE(''); DBMS_OUTPUT.PUT_LINE('number of employees' || c_max); -- start of the bucle.... FOR i IN 1..c_max LOOP -- tantas vueltas como valores

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

SELECT * INTO currelas(i) FROM employees -- en cada vuelta inserto una lnea WHERE employee_id=(99+i); -- el primer empleado es el 100... DBMS_OUTPUT.PUT_LINE('getting employe : ' || (99+i)); END LOOP; --Desplegando employees... FOR i IN 1..c_max LOOP -- tantas vueltas como valores DBMS_OUTPUT.PUT_LINE(currelas(i).last_name); END LOOP; END; /

Uso de Cursores
Cursores Los cursores son reas de trabajo que permiten ejecutar sentencias SQL y procesar la informacin obtenida de ellos. Hay dos tipos de cursores: implcitos y explcitos. PL/SQL declara implcitamente un cursor para todas las sentencias de manipulacin de datos, incluyendo las consultas que retornan slo una fila. Para consultas que devuelven ms de una fila, es posible declarar explcitamente un cursor que procese las filas en forma individual. Sintaxis.CURSOR Nombre_Cursor|(Par1 tipo, Par2 Tipo, Par3 Tipo, Parn Tipo) IS Consulta_SQL; Por ejemplo: DECLARE CURSOR curs_01 IS Ejemplo: CURSOR Empleados_Dpto10 IS SELECT empno, ename, job FROM emp WHERE deptno=20; El conjunto de filas retornado se denomina "set de resultados". Su tamao est determinado por el nmero de filas que calzan con el criterio de seleccin de la consulta que implementa el cursor. Las filas son procesadas de a una cada vez.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

La figura anterior ilustra la recuperacin de filas a travs de un cursor

Apertura de un Cursor.La Setencia OPEN abre y prepara un cursor para ser usado OPEN Nombre_Cursor | (Par1, Par2, Par3, ParN); Ejemplo: OPEN Empleados_Dpto10;

Pasando columnas de un cursor a Variables


FETCH Nombre_Cursor INTO Var1, Var2, Var3VarN; Ejemplo: FETCH Empleados_Dpto10 INTO v_empno, v_ ename, v_job Uso de %NOTFOUND Este Atributo toma valor verdadero (TRUE) cuando ya no quedan mas filas que recuperar en el cursor y Falso (FALSE) cuando aun quedan filas. Ejemplo: IF Empleados_Dpto10%NOTFOUND THEN EXIT END IF; Uso de %ISOPEN El mismo toma el valor verdadero (TRUE) cuando un cursor se encuentra abierto. De otra manera, retorna FALSO.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

IF Empleados_Dpto10%ISOPEN THEN CLOSE Empleados_Dpto10 END IF; Uso de %ROWCOUNT Cuando un cursor es abierto, este atributo es seteado en 0 (cero). En adelante, cada vez que se recuperen filas exitosamente con un FETCH, este valor se ir incrementando en uno.

Cuando se utiliza con cursores implcitos, este atributo devuelve el total de filas afectadas por una instruccin del tipo INSERT, UPDATE o DELETE. Cierre de un Cursor La sentencia que deshabilita un cursor, CLOSE, se utiliza de la siguiente manera: CLOSE cursor; Una vez que un cursor ya ha sido cerrado, es posible volverlo a abrir sin tener que declararlo otra vez. Cualquier otra operacin que se desee efectuar sobre un cursor no operativo (cerrado) provocar una excepcin del tipo "invalid_cursor". Ejemplo: DECLARE V_Ename Emp.Ename%TYPE; V_Sal Emp.Sal%TUPE; CURSOR Cur01 IS SELECT Ename, Sal FROM Emp; BEGIN OPEN Cur01; LOOP FETCH Cur01 INTO V_Ename, V_Sal; EXIT WHEN Cur01%NOTFOUND; INSERT INTO Emp2 VALUES(V_Ename, V_Sal); END LOOP; CLOSE Cur01;

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

END; /

Manejo de Excepciones Excepciones predefinidas


Las excepciones predefinidas no necesitan ser declaradas. Simplemente se utilizan cuando estas son gatilladas por algn error determinado. La siguiente es la lista de las excepciones predeterminadas por PL/SQL y una breve descripcin de cundo son accionadas: Nombre Excepcin Gatillada cuando SQLCO DE

ACCESS_INTO_NULL

El programa intent asignar -6530 valores a los atributos de un objeto no inicializado El programa intent asignar -6531 valores a una tabla anidada an no inicializada El programa intent abrir un -6511 cursor que ya se encontraba abierto. Recuerde que un cursor de ciclo FOR automticamente lo abre y ello no se debe especificar con la sentencia OPEN El programa intent almacenar valores duplicados en una columna que se mantiene con restriccin de integridad de un ndice nico (unique index) -1

COLLECTION_IS_NULL

CURSOR_ALREADY_OPEN

DUP_VAL_ON_INDEX

INVALID_CURSOR

El programa intent efectuar -1001

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

una operacin no vlida sobre un cursor INVALID_NUMBER En una sentencia SQL, la -1722 conversin de una cadena de caracteres hacia un nmero falla cuando esa cadena no representa un nmero vlido El programa intent conectarse a Oracle con un nombre de usuario o password invlido -1017

LOGIN_DENIED

NO_DATA_FOUND

Una sentencia SELECT +100 INTO no devolvi valores o el programa referenci un elemento no inicializado en una tabla indexada El programa efectu una llamada a Oracle sin estar conectado PL/SQL tiene un problema interno Los elementos de una asignacin (el valor a asignar y la variable que lo contendr) tienen tipos incompatibles. Tambin se presenta este error cuando un parmetro pasado a un subprograma no es del tipo esperado El parmetro SELF (el primero que es pasado a un mtodo MEMBER) es nulo La memoria se termin o est corrupta -1012

NOT_LOGGED_ON

PROGRAM_ERROR ROWTYPE_MISMATCH

-6501 -6504

SELF_IS_NULL

-30625

STORAGE_ERROR SUBSCRIPT_BEYOND_COUNT

-6500

El programa est tratando de -6533

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

referenciar un elemento de un arreglo indexado que se encuentra en una posicin ms grande que el nmero real de elementos de la coleccin SUBSCRIPT_OUTSIDE_LIMIT El programa est referenciando un elemento de un arreglo utilizando un nmero fuera del rango permitido (por ejemplo, el elemento "-1") -6532

SYS_INVALID_ROWID

La conversin de una cadena -1410 de caracteres hacia un tipo rowid fall porque la cadena no representa un nmero Se excedi el tiempo mximo de espera por un recurso en Oracle Una sentencia SELECT INTO devuelve ms de una fila Ocurri un error aritmtico, de conversin o truncamiento. Por ejemplo, sucede cuando se intenta calzar un valor muy grande dentro de una variable ms pequea -51

TIMEOUT_ON_RESOURCE

TOO_MANY_ROWS

-1422

VALUE_ERROR

-6502

ZERO_DIVIDE

El programa intent efectuar -1476 una divisin por cero

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Excepciones definidas por el usuario PL/SQL permite al usuario definir sus propias excepciones, las que debern ser declaradas y gatilladas explcitamente utilizando otros comandos del lenguaje. Declaracin Las excepciones slo pueden ser declaradas en el segmento "Declare" de un bloque, subprograma o paquete. Se declara una excepcin escribiendo su nombre seguida de la palabra clave EXCEPTION. Las declaraciones son similares a las de variables, pero recuerde que una excepcin es una condicin de error, no un tem de datos. Aun as, las mismas reglas de alcance aplican tanto sobre variables como sobre las excepciones. Ejemplo: DECLARE error_01 EXCEPTION; Reglas de Alcance Una excepcin no puede ser declarada dos veces en un mismo bloque. Tal como las variables, una excepcin declarada en un bloque es local a ese bloque y global a todos los sub-bloques que comprende. La sentencia "RAISE" La sentencia RAISE permite gatillar una excepcin en forma explcita. Es factible utilizar esta sentencia en cualquier lugar que se encuentre dentro del alcance de la excepcin.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Ejemplo: DECLARE out_of_stock EXCEPTION; -- declaracin de la excepcin total NUMBER(4); BEGIN IF total < 1 THEN RAISE out_of_stock; -- llamado a la excepcin END IF; EXCEPTION WHEN out_of_stock THEN -- manejar el error aqu WHEN OTHERS THEN END; / Finalmente, cabe destacar la existencia de la excepcin OTHERS, que simboliza cualquier condicin de excepcin que no ha sido declarada. Se utiliza comnmente al final del bloque de excepciones para absorber cualquier tipo de error que no ha sido previsto por el programador. En ese caso, es comn observar la sentencia ROLLBACK en el grupo de sentencias de la excepcin o alguna de las funciones SQLCODE SQLERRM, que se detallan en el prximo punto. Uso de SQLCODE y SQLERRM Al manejar una excepcin es posible apoyarse con las variables predefinidas SQLCode y SQLErrm para aclarar al usuario la situacin de error acontecida. Sqlcode siempre retornar el nmero del error de Oracle y un "0" (cero) en caso exitoso al ejecutarse una sentencia SQL. Por otra parte, Sqlerrm retornar el correspondiente mensaje de error para la situacin ocurrida. Tambin es posible entregarle a la funcin SQLERRM un nmero negativo que represente un error de Oracle y sta devolver el mensaje asociado.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Estas funciones son muy tiles cuando se utilizan en el bloque de excepciones, para aclarar el significado de la excepcin OTHERS, cuando sta ocurre. Estas funciones no pueden ser utilizadas directamente en una sentencia SQL, pero s se puede asignar su valor a alguna variable de programa y luego usar esta ltima en alguna sentencia. Ejemplo: DECLARE err_num NUMBER; err_msg VARCHAR2(100); BEGIN EXCEPTION WHEN OTHERS THEN err_num := SQLCODE; err_msg := SUBSTR(SQLERRM, 1, 100); INSERT INTO errores VALUES(err_num, err_msg); END ;/

Creacin de Procedimientos Almacenados


Para crear procedimientos almacenas se utiliza la Sentencia CREATE, los procedimientos pueden recibir o devolver valores a travs de parmetros que se definen en la misma creacin del procedimiento y la sintaxis es como sigue: CREATE PROCEDURE Esta sentencia se utiliza para crear un procedimiento almacenado en la base de datos y su sitaxis es: CREATE [OR REPLACE] PROCEDURE Nombre_Procedimiento [(Par1 IN OUT Tipo_Dato, Par2 IN OUT Tipo_Dato, Par3 IN OUT Tipo_Dato,

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

ParN IN OUT Tipo_Dato)] IS NOTA: [OR REPLACE] es Condicional, si no se ha creado lo crea y si ya esta creado lo reemplaza.

Funciones definidas por el Usuario


Adems de las mltiples funciones que posee ORACLE, es posible crear tus propias funciones y utilizarlas tanto en una consulta, como en procedimientos, dichas funciones pueden ser Procedimentales o no, las primeras devuelven mas de un valor y solo pueden ser utilizadas en Procedimientos u otras funciones, las funciones normales devuelven un solo valor y por tanto pueden ser utilizadas en las consultas. CREATE FUNCTION Esta se utiliza para crear funciones, la sintaxis es como sigue: CREATE [OR REPLACE] FUNTION Nombre_Funcion (Par1 IN OUT, Par2 IN OUT, Par3 IN OUT, ParN IN OUT) RETURN Tpo_Dato_Returna IS Existen dos tipos de funciones

Funciones Procedimentales
Estas pueden retornar ms de un valor pero solo pueden ser utilizadas dentro de procedimientos, triguers y otras funciones. CREATE [OR REPLACE] FUNCTION Nombre_Funcion (Par1 IN OUT, Par2 IN OUT, Par3 IN OUT, ParN IN OUT) RETURN Tipo_dato_Retorna IS

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Funciones que retornan un solo valor


Estas pueden ser usadas en una sentencia SQL, otros procedimientos, Triguers y otras funciones. CREATE [OR REPLACE] FUNCTION Nombre_Funcion (Par1 IN, Par2 IN, Par3 IN, ParN IN) RETURN Tipo_Dato_Retorna IS

Creacin de Disparadores Definicin de trigger


Los disparadores son procedimientos que se ejecutan cuando se produce un suceso de base de datos (una operacin DML: INSERT, UPDATE o DELETE) en una tabla especfica. El acto de ejecutar un disparador se conoce como disparo. Uso de los triggers Los disparadores pueden emplearse para muchas cosas diferentes, incluyendo: 1.El mantenimiento de restricciones de integridad complejas, que no sean posibles con las restricciones declarativas definidas en el momento de crear la tabla. 2.La auditora de la informacin contenida en una tabla, registrando los cambios realizados y la identidad del que los llev a cabo. 3.El aviso automtico a otros programas de que hay que llevar a cabo una determinada accin, cuando se realiza un cambio en una tabla. Sintaxis general de trigger La sintaxis general para crear un disparador es: CREATE [OR REPLACE] TRIGGER nombre_disparador { BEFORE | AFTER ? suceso_disparo ON referencia_tabla

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

[FOR EACH ROW [ WHEN condicin_disparo ]] cuerpo_disparador, Donde: Nombre_disparador es el nombre del disparador, Suceso_disparo especifica cundo se activa el disparador, Referencia_tabla es la tabla para la cual se define el disparador y cuerpo_disparador es el cdigo principal del disparador. Antes se evala la condicin_disparo incluida en la clusula WHEN, si es que est presente. El cuerpo del disparador se ejecuta slo cuando dicha condicin se evala como verdadera. Componentes de un disparador Los componentes de un disparador son el nombre, el suceso de disparo y el cuerpo. La clusula WHEN es opcional. Nombres de disparadores El espacio de nombres para los disparadores es diferente del de otros subprogramas. El espacio de nombres es el conjunto de identificadores vlidos que pueden emplearse como nombres de un objeto. Los disparadores existen en un espacio de nombres separado del de los procedimientos, paquetes y tablas, por lo que un disparador puede tener el mismo nombre que una tabla o procedimiento. Sin embargo dentro de un mismo esquema deben tener nombres diferentes entre s. Tipos de disparadores

El suceso de disparo determina el tipo de disparador. Los disparadores pueden definirse para las operaciones INSERT, UPDATE o DELETE, y

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

pueden dispararse antes o despus de la operacin. Finalmente, el nivel de los disparadores puede ser la fila o la orden. La Figura 1 muestra los tipos de disparadores: Categora Valores Comentarios Orden INSERT, DELETE, UPDATE Define qu tipo de orden DML provoca la activacin del disparador. Temporizacin BEFORE o AFTER Define si el disparador se activa antes o despus de que se ejecute la orden (disparador previo o posterior). Nivel Fila u orden Los disparadores con nivel de fila se activan una vez por cada fila afectada por la orden que provoc el disparo. Los disparadores con nivel de orden se activan slo una vez, antes o despus de la orden. Los disparadores con nivel de fila se identifican por la clusula FOR EACH ROW en la definicin del disparador. Figura 1. Tipos de disparadores [2] Disparadores de sustitucin Oracle proporciona un tipo adicional de disparador. Los disparadores de sustitucin ( INSTEAD OF ) pero tienen una serie de restricciones [3]: INSTEAD OF es una clusula vlida solo para vistas; no se puede especificar un disparador INSTEAD OF en una tabla.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Si una vista tiene un disparador INSTEAD OF, cualquier vista creada sobre sta debe tener a su vez un disparador INSTEAD OF. Cuando definimos disparadores INSTEAD OF para columnas LOB, podemos leer tanto el seudo-registro :OLD como el seudo-registro :NEW, pero no se puede modificar sus valores. Restricciones de los disparadores El cuerpo de un disparador es un bloque PL/SQL. Cualquier orden que sea legal en un bloque PL/SQL, es legal en el cuerpo de un disparador, con las siguientes restricciones: 1.Un disparador no puede emitir ninguna orden de control de transacciones: COMMIT, ROLLBACK o SAVEPOINT. 2.El disparador se activa como parte de la ejecucin de la orden que provoc el disparo, y forma parte de la misma transaccin que dicha orden. Cuando la orden que provoca el disparo es confirmada o cancelada, se confirma o cancela tambin el trabajo realizado por el disparador. 3.Por razones idnticas, ningn procedimiento o funcin llamado por el disparador puede emitir rdenes de control de transacciones. 4.El cuerpo del disparador no puede contener ninguna declaracin de variables LONG o LONG RAW. 5.Existen restricciones acerca de a qu tablas puede acceder el cuerpo de un disparador. Dependiendo del tipo de disparador y de las restricciones que afecten a las tablas. Eliminacin y deshabilitacin de los disparadores La sintaxis de la orden que elimina un disparador es: DROP TRIGGER nombre_disparador; donde nombre_disparador es el nombre del disparador que se desea eliminar. Esta orden elimina el disparador de forma permanente del diccionario de datos. La sintaxis de la orden que deshabilita un disparador es : ALTER TRIGGER nombre_disparador [DISABLE | ENABLE]

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

donde nombre_disparador es el nombre del disparador. Todos los disparadores estn habilitados en el momento de su creacin. Cuando se deshabilita un disparador continua existiendo en el diccionario de datos. Tambin se puede habilitar o deshabilitar todos los disparadores de una tabla determinada, utilizando la orden ALTER TABLE con la clusula ENABLE ALL TRIGGERS o DISABLE ALL TRIGGERS. 1.Orden de activacin de los disparadores

Los disparadores se activan al ejecutarse la orden DML. El algoritmo de ejecucin de una orden DML es el siguiente: 2.Ejecutar, si existe, el disparador de tipo BEFORE (disparador previo) con nivel de orden. Para cada fila a la que afecte la orden: Ejecutar, si existe, el disparador de tipo BEFORE con nivel de fila. Ejecutar la propia orden. Ejecutar, si existe, el disparador de tipo AFTER (disparador posterior) con nivel de fila. Ejecutar, si existe, el disparador de tipo AFTER con nivel de orden. Utilizacin de :old y :new en los disparadores con nivel de fila Un disparador con nivel de fila se ejecuta una vez por cada fila procesada por la orden que provoca el disparo. Dentro del disparador puede accederse a la fila que est siendo actualmente procesada utilizando, para ello, dos seudoregistros, :old y :new. La Figura 2 muestra este concepto: Orden de disparo :old

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

:new INSERT No definido; todos los campos toman valor NULL. Valores que sern insertados cuando se complete la orden. UPDATE Valores originales de la fila, antes de la actualizacin. Nuevos valores que sern escritos cuando se complete la orden. DELETE Valores, antes del borrado de la fila. No definidos; todos los campos toman el valor NULL. Figura 2. :old y :new El tipo de estos seudo-registros es : tabla_disparo%ROWTYPE; donde tabla_disparo es la tabla sobre la que se ha definido el disparador. Los registros :new y :old son slo vlidos dentro de los disparadores con nivel de fila. Si se intenta Hacer referencia a cualquiera de los dos dentro de un disparador con nivel de orden, se obtendr un error de compilacin. Puesto que un disparador con nivel de orden se ejecuta una sola vez, incluso si la orden procesa varias filas, entonces :old y :new no tienen ningn sentido ya que no se sabe a que fila se estn refiriendo. La clusula WHEN La clusula WHEN slo es vlida para los disparadores con nivel de fila. Si est presente, el cuerpo del disparador slo se ejecutar para las filas que cumplan la condicin especificada en la clusula.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

La clusula WHEN tiene la forma: WHEN condicin Donde condicin es una expresin booleana que ser evaluada para cada fila. Se puede hacer tambin referencia a los registros :new y :old dentro de la condicin, pero en ese caso no se utilizan los dos puntos.

Utilizacin de predicados de los disparadores: INSERTING, UPDATING y DELETING Dentro de un disparador en el que se disparan distintos tipos de rdenes DML (INSERT, UPDATE y DELETE), hay tres funciones booleanas que pueden emplearse para determinar de qu operacin se trata. Estos predicados son INSERTING, UPDATING y DELETING. Su comportamiento es el siguiente: La Figura 3 muestra el comportamiento de INSERTING, UPDATING y DELETING Predicado Comportamiento INSERTING TRUE si la orden de disparo es INSERT; FALSE en otro caso. UPDATING TRUE si la orden de disparo es UPDATE; FALSE en otro caso. DELETING TRUE si la orden de disparo es DELETE; FALSE en otro caso. Figura 3. INSERTING, UPDATING y DELETING [2] Ejemplo

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Un ejemplo de su uso es proporcionar una facilidad de auditoria donde se realiza automticamente un registro de actividades siempre que se cambia una fila de una tabla. Sin los disparadores de bases de datos esta funcin sera implementada en los programas de seccin de entrada (front-end) que realizan el cambio en la base de datos; sin embargo alguien que se pase por alto el cdigo de los programas de seccin de entrada (utilizando SQL*Plus, por ejemplo) no pasara por las comprobaciones y el procesamiento definidos. Su pngase que tenemos una tabla llamada SAL (en la que almacenamos los salarios de los empleados de la empresa) y resulta necesario conocer cundo esta siendo accedida la tabla y el tipo de operacin que se realiza. El ejemplo que presentamos a continuacin contiene un paquete de muestra que rastrea esta informacin registrando la hora y la accin ejecutada (UPDATE, DELETE, o INSERT) en la tabla SAL. Mediante una variable global, STAT.ROWCNT, inicializada a cero por el trigger BEFORE e incrementada cada vez que un disparador con nivel de fila es ejecutado, tenemos la informacin estadstica que necesitamos salvar en el disparador AFTER.

DROP TABLE stat_tab; CREATE TABLE stat_tab(utype CHAR(8), rowcnt INTEGER, uhour INTEGER);

CREATE OR REPLACE PACKAGE stat IS rowcnt INTEGER; END;

CREATE TRIGGER bt BEFORE UPDATE OR DELETE OR INSERT ON sal BEGIN stat.rowcnt := 0;

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

END;

CREATE TRIGGER rt BEFORE UPDATE OR DELETE OR INSERT ON sal FOR EACH ROW BEGIN stat.rowcnt := stat.rowcnt + 1; END; CREATE TRIGGER at AFTER UPDATE OR DELETE OR INSERT ON sal DECLARE typ CHAR(8); hour NUMBER; BEGIN IF updating THEN typ := 'update'; END IF; IF deleting THEN typ := 'delete'; END IF; IF inserting THEN typ := 'insert'; END IF;

hour := TRUNC((SYSDATE - TRUNC(SYSDATE)) * 24); UPDATE stat_tab SET rowcnt = rowcnt + stat.rowcnt WHERE utype = typ AND uhour = hour; IF SQL%ROWCOUNT = 0 THEN

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

INSERT INTO stat_tab VALUES (typ, stat.rowcnt, hour); END IF;

EXCEPTION WHEN dup_val_on_index THEN UPDATE stat_tab SET rowcnt = rowcnt + stat.rowcnt WHERE utype = typ AND uhour = hour TABLAS MUTANTES Una tabla que est "mutando" es una tabla que est siendo modificada por un INSERT, un DELETE o un UPDATE o una tabla que podra modificarse por los efectos de un ON DELETE CASCADE (integridad referencial). Una tabla est "restringiendo" (tabla de restriccion o tabla padre) si una sentencia activadora podra necesitar leerlo directamente, por una sentencia SQL, o indirectamente, por una restriccin de Integridad referencial.

Paquetes.Los paquetes tienen el objetivo de agrupar procedimientos y funciones de forma lgica. De esta manera, se consigue agrupar en un nico objeto, toda la casustica asociada a un determinado tipo de tarea. Por ejemplo, si tenemos un conjunto de procedimientos y funciones para realizar clculos matemticos complejos, los podemos poner en un paquete. La ventaja de los paquetes es que la primera vez que se invoca, es cargado en memoria, por lo que las siguientes veces ya no ser necesario hacerlo de nuevo. Adems, el paquete mantiene una copia en memoria para todos los usuarios. Otra ventaja, es que podemos encapsular procedimientos y funciones que no forman parte de la interfaz de usuario. Podemos ocultar ciertos objetos y solo hacer pblicos los que se necesiten. Tambin se permite la sobrecarga dentro de los paquetes.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

El paquete se divide en

Especificacin Cuerpo

Especificacin Es obligatorio en la creacin de un paquete. Se declaran todos los subprogramas pblicos. Lo lgico es declarar en esta seccin aquellos procedimientos o funciones que actan como interfaz. Tambin se declaran las variables o constantes que se quieren tratar como globales y que se puedan cambiar o referenciar fuera del paquete. La sintaxis sera CREATE [OR REPLACE] PACKAGE nombre_paquete IS | AS declaraciones de variables, cursores ... subprogramas en PLSQL END nombre_paquete Cuerpo En el cuerpo es donde se definen los procedimientos y funciones pblicos y privados. La sintaxis sera CREATE [OR REPLACE] PACKAGE BODY nombre_paquete IS | AS declaraciones de variables, cursores... subprogramas en PLSQL END nombre_paquete Para realizar llamadas a objetos dentro de un paquete, habra que diferenciar si la llamada es desde un subprograma dentro del mismo paquete o si la llamada es externa al paquete:

Llamada interna Se pone el nombre del subprograma y entre parntesis los parmetros que se deben pasar.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Por ej. para llamar a la funcin "Multiplica(real r1, real r2)" desde la funcin "CalculaBeneficios", se pondra "r3:= Multiplica(2.5,3.5)"

Llamada externa Hay que preceder el nombre del paquete al nombre del procedimiento o funcin. Adems, el subprograma llamado debe ser pblico para que pueda ser referenciado. Por ej. para llamar a la funcin Multiplica que se encuentra en el paquete "OperacionesMatematicas" desde un procedimiento externo al paquete sera "r3:= OperacionesMatematicas.Multiplica(2.5,3.5)"

Para eliminar un paquete de la base de datos tanto la especificacin como el cuerpo: DROP PACKAGE nombre_paquete Oracle proporciona algunos paquetes que permiten la realizacin de distintas tareas muy comunes al desarrollar o administrar la base de datos. Entre estos paquetes se pueden destacar:

DBMS_SQL: Para acceder a la base de datos con SQL dinmico.


DBMS_UTILITY: Para el anlisis de objetos. Por ejemplo se pueden compilar todos los objetos que se encuentran en un determinado esquema de base de datos.

UTL_FILE: Aade capacidades de entrada/salida a ficheros.

Obtenido de "http://es.wikipedia.org/wiki/Paquetes_en_PLSQL"
Declaracin de la especificacin

- Un paquete se compone de dos elementos; La Especificacin y El cuerpo - En la especificacin se declaran todos los procedimientos y funciones que formaran parte del mismo y la sintaxis es como sigue: CREATE [OR REPLACE] PACKAGE package_name [AUTHID {CURRENT_USER | DEFINER}] {IS | AS} [PRAGMA SERIALLY_REUSABLE;] [collection_type_definition ...] [record_type_definition ...] [subtype_definition ...] [collection_declaration ...] [constant_declaration ...] [exception_declaration ...] [object_declaration ...]

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

[record_declaration ...] [variable_declaration ...] [cursor_spec ...] [function_spec ...] [procedure_spec ...] [call_spec ...] [PRAGMA RESTRICT_REFERENCES(assertions) ...] END [package_name];

cuerpo de un paquete.
[CREATE [OR REPLACE] PACKAGE BODY package_name {IS | AS} [PRAGMA SERIALLY_REUSABLE;] [collection_type_definition ...] [record_type_definition ...] [subtype_definition ...] [collection_declaration ...] [constant_declaration ...] [exception_declaration ...] [object_declaration ...] [record_declaration ...] [variable_declaration ...] [cursor_body ...] [function_spec ...] [procedure_spec ...] [call_spec ...] [BEGIN sequence_of_statements] END [package_name];]

- Sobrecarga de paquetes. Los paquetes pueden ser compilados y almacenados en una base de datos Oracle y su contenido puede ser compartido por varias aplicaciones. Cuando un paquete es llamado para su ejecucin, ste se almacena completamente en memoria la primera vez. Las siguientes llamadas no requieren efectuar este procedimiento cada vez y por esto aumentan la eficiencia de los programas.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Uso de Paquetes Suministrados por Oracle en el Desarrollo de Aplicaciones Son numerosos los paquetes proporcionados por ORACLE, en este manual mencionaremos algunos, si el estudiante esta interesado o tiene la necesidad puede indagar por su cuenta. DBMS_ALERT: Procedimientos y funciones que permiten a las aplicaciones nombrar y emitir seales de alerta sin sondeo. DBMS_AQ DBMS_AQADM: Procedimientos y funcipones para poner en cola la ejecucin de transacciones y administrar los mecanismos de encolamiento. DBMS_DDL DBMS_UTILITY: Procedimiento que permite el acceso a un numero determinado de sentencias DDL dentro de los programas PL/SQL. DBMS_DESCRIBE: Procedimiento que describe la API de funciones y procedimientos almacenados. DBMS_JOB: Procedimientos y funciones que administran los mecanismos de las tareas de encolamiento de una bas de datos. DBMS_LOB: Procedimientos y Funciones que manipulan BLOB, CLOB, NCLOB y BFILE. DBMS_LOCK: Procedimientos y funciones que permiten a las aplicaciones coordinar el acceso a los recursos compartidos. DBMS_OUTPUT: Procedimientos y funciones que permiten a un programa PL/SQL generar salida de Terminal. DBMS_PIPE: Procedimientos y funciones que permiten a las sesiones de base de datos comunicarse usando conductos (canales de comunicacin). DBMS_ROWID: Procedimientos y funciones que permiten a las aplicaciones interpretar fcilmente un carcter ROWID externo de base 64. DBMS_SESSION: Procedimientos y funciones que controla la sesion de usuario de una aplicacin.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

DBMS_SQL: Procedimientos y funciones que realizan SQL dinamico desde dentro de un programa PL/SQL. DBMS_TRANSACTION: Procedimientos que realizan un control limitado de las transacciones. UTL_FILE: Procedimientos y funciones que permiten a un programa PL/SQL leer y escribir archivos de texto al sistema de archivos del servidor.

SQL Dinmico y Metadatos


Sentencias DML con SQL dinamico PL/SQL ofrece la posibilidad de ejecutar sentencias SQL a partir de cadenas de caracteres. Para ello debemos emplear la instruccin EXECUTE IMMEDIATE. Podemos obtener informacin acerca de nmero de filas afectadas por la instruccin ejecutada por EXEXUTE IMMEDIATE utilizando SQL %ROWCOUNT. El siguiente ejemplo muestra la ejecucin de un comando SQL dinamico. DECLARE ret NUMBER; FUNCTION fn_execute RETURN NUMBER IS sql_str VARCHAR2(1000); BEGIN sql_str := 'UPDATE DATOS SET NOMBRE = ''NUEVO NOMBRE'' WHERE CODIGO = 1'; EXECUTE IMMEDIATEsql_str; RETURN SQL%ROWCOUNT; END fn_execute ; BEGIN ret := fn_execute(); dbms_output.put_line(TO_CHAR(ret)); END; Podemos adems parametrizar nuestras consultas a travs de variables host. Una variable host es una variable que pertenece al programa que est ejecutando la sentencia SQL dinmica y que podemosasignar enel interior de

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

la sentencia SQL con la palabra clave USING. Las variables host van precedidas de dos puntos ":". El siguiente ejemplo muestra el uso de variables host para parametrizar una sentencia SQL dinamica. DECLARE ret NUMBER; FUNCTION fn_execute (nombre VARCHAR2, codigo NUMBER) RETURN NUMBER IS sql_str VARCHAR2(1000); BEGIN sql_str := 'UPDATE DATOS SET NOMBRE = :new_nombre WHERE CODIGO = :codigo'; EXECUTE IMMEDIATEsql_str USING nombre, codigo; RETURN SQL%ROWCOUNT; END fn_execute ; BEGIN ret := fn_execute('Devjoker',1); dbms_output.put_line(TO_CHAR(ret)); END; Cursores con SQL dinmico Con SQL dinmico tambin podemos utilizar cursores. Para utilizar un cursor implcito solo debemos construir nuestra sentencia SELECT en una variable de tipocarcter y ejecutarla con EXECUTE IMMEDIATEutilizando la palabra clave INTO. DECLARE str_sql VARCHAR2(255); l_cntVARCHAR2(20); BEGIN str_sql := 'SELECT count(*) FROM PAISES'; EXECUTE IMMEDIATE str_sql INTO l_cnt; dbms_output.put_line(l_cnt); END;

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Trabajar con cursores explcitos es tambin muy fcil. nicamente destacar el uso de REF CURSOR para declarar una variableparareferirnos al cursorgenerado con SQL dinmico. DECLARE TYPE CUR_TYP IS REF CURSOR; c_cursor CUR_TYP; fila PAISES%ROWTYPE; v_query VARCHAR2(255); BEGIN v_query := 'SELECT * FROM PAISES'; OPEN c_cursor FOR v_query; LOOP FETCH c_cursor INTO fila; EXIT WHEN c_cursor%NOTFOUND; dbms_output.put_line(fila.DESCRIPCION); END LOOP; CLOSE c_cursor; END; / Las varibles host tambien se pueden utilizar en los cursores. DECLARE TYPE cur_typ IS REF CURSOR; c_cursor CUR_TYP; fila PAISES%ROWTYPE; v_query VARCHAR2(255); codigo_pais VARCHAR2(3) := 'ESP'; BEGIN v_query := 'SELECT * FROM PAISES WHERE CO_PAIS = :cpais'; OPEN c_cursor FOR v_query USING codigo_pais; LOOP FETCH c_cursor INTO fila; EXIT WHEN c_cursor%NOTFOUND; dbms_output.put_line(fila.DESCRIPCION); END LOOP; CLOSE c_cursor; END;/

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Consideraciones de Diseo para Cdigo PL/SQL


Esta parte de nuestro Manuel es muy subjetiva y se basa en lo que para mi resulta cmodo y fcil de atender, no representa la verdad absoluta en PL/ SQL y mis consideraciones son: Identar los bloques.- para los que no manejan, la palabra identar, es escribir todas las sentencias que estn subordinadas o entre el comienzo y el final de un bloque a 1 o 2 o 3 o las columnas que consideren prudente. Ejemplo; BEGIN IF Sal > 24000 THEN Sal_Des := sal 24000; Identado a tres columnas del IF ELSE Sal_Des := 0; END IF; END; / Siempre que se usa un SQL, dentro de un PL, encerrarlo en un bloque tratando de manejar los posibles errores que devolver ese SQL. EjEMPLO; BEGIN UPDATE emp SET sal = 8000 WHERE NoEmp = V_NoEmp; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE(No existe el empleado : ||V_NoEmp); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(No existe el empleado : ||V_NoEmp); END; /

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Recomiendo poner una letra delante de las variables que indique que corresponden a: Una Variable (V), un Cursor (C), una Excepcin (E), un Parmetro (P), Separar con un guin bajo ( UnderScore _ ), las variables que tengan mas de una letra Ejemplo; VSueldo_Bruto En general en programacin muchos autores recomiendan: Escribir las palabras reservadas del lenguaje en maysculas (UPDATE) , variables y nombres de campos en Capitalize (Primera letra en maysculas y las siguientes en minsculas). En fin tratar de hacer el cdigo limpio y entendible para usted y cualquier otra persona. Gestin de Dependencias Dependencias Recompilacin de objetos descompilados del esquema. Las actualizaciones, parches y cambios de libreras pueden invalidar objetos del esquema. Una vez realizados los cambios los objetos dependientes sern revalidados de forma automtica cuando se usan. Esto puede tardar un rato e incluso tardar un tiempo inaceptable por lo que lo lgico es recompilar las dependencias antes de las llamadas de los usuarios. Esto adems permite descubrir si los cambios han afectado al resto del cdigo.

Identificacin de objetos descompilados


COLUMN object_name FORMAT A30 SELECT owner, object_type, object_name, status FROM dba_objects WHERE status = 'INVALID' ORDER BY owner, object_type, object_name; Con esta informacin podemos decidir que metodo seguir para recompilar.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Recompilacin manual Para un nmero pequeo de objetos es probable que la recompilacin manual sea suficiente. ALTER PACKAGE my_package COMPILE; ALTER PACKAGE my_package COMPILE BODY; ALTER PROCEDURE my_procedure COMPILE; ALTER FUNCTION my_function COMPILE; ALTER TRIGGER my_trigger COMPILE; ALTER VIEW my_view COMPILE; Hay que tener en cuenta que es necesario recompilar cabecera y cuerpo del paquete por separado. Alternativamente podemos usar el paquete DBMS_DDL: EXEC DBMS_DDL('PACKAGE', 'MY_SCHEMA', 'MY_PACKAGE'); EXEC DBMS_DDL('PACKAGE BODY', 'MY_SCHEMA', 'MY_PACKAGE'); EXEC DBMS_DDL('PROCEDURE', 'MY_SCHEMA', 'MY_PROCEDURE'); EXEC DBMS_DDL('FUNCTION', 'MY_SCHEMA', 'MY_FUNCTION'); EXEC DBMS_DDL('TRIGGER', 'MY_SCHEMA', 'MY_TRIGGER'); Este metodo esta limitado a los objetos PL/SQL por lo que no es aplicable a vistas. Script a medida En algunos casos puede ser interesante escribir un script para identificar y compilar objetos descompilados. Un ejemplo para PACKAGE y PACKAGE BODY seria: SET SERVEROUTPUT ON SIZE 1000000 BEGIN FOR cur_rec IN (SELECT owner, object_name, object_type, DECODE(object_type, 'PACKAGE', 1, 'PACKAGE BODY', 2, 2) AS recompile_order FROM dba_objects

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

WHERE object_type IN ('PACKAGE', 'PACKAGE BODY') AND status != 'VALID' ORDER BY 4) LOOP BEGIN IF cur_rec.object_type = 'PACKAGE' THEN EXECUTE IMMEDIATE 'ALTER ' || cur_rec.object_type || ' "' || cur_rec.owner || '"."' || cur_rec.object_name || '" COMPILE'; ElSE EXECUTE IMMEDIATE 'ALTER PACKAGE "' || cur_rec.owner || '"."' || cur_rec.object_name || '" COMPILE BODY'; END IF; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.put_line(cur_rec.object_type || ' : ' || cur_rec.owner || ' : ' || cur_rec.object_name); END; END LOOP; END; / Con este mtodo hay que tener mucho cuidado ya que puedes acabar recompilando algunos objetos varias veces dependiendo del orden de ejecucin de la recompilacin. Los procedimientos que nos da oracle y que estn explicados a continuacin si que tiene en cuenta el orden adecuado. DBMS_UTILITY.compile_schema El procedimiento COMPILE_SCHEMA del paquete DBMS_UTILITY compila todos los procedures, functions, packages, y triggers de un esquema. Hay que tener muy en cuenta que tampoco recompila las vistas. EXEC DBMS_UTILITY.compile_schema(schema => 'SCOTT'); UTL_RECOMP El paquete UTL_RECOMP contiene 2 procedimientos para recompilar objetos descompilados. RECOMP_SERIAL recompila los objetos uno por uno mientras que RECOMP_PARALLEL recompila en paralelo usando el numero de threads especificado.

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

PROCEDURE RECOMP_SERIAL( schema IN VARCHAR2 DEFAULT NULL, flags IN PLS_INTEGER DEFAULT 0); PROCEDURE RECOMP_PARALLEL( threads IN PLS_INTEGER DEFAULT NULL, schema IN VARCHAR2 DEFAULT NULL, flags IN PLS_INTEGER DEFAULT 0); los parametros son: - schema - El esquema a recompilar, si es nulo se recompilan todos los objetos descompilados de la base de datos. - threads - El numero de threads a utilizar, si es nulo se usa el valor de "job_queue_processes". Un valor adecuado es el numero de CPU's disponibles. - flags - Se usa para pruebas y diagnostico interno. EXEC UTL_RECOMP.recomp_serial('SCOTT'); EXEC UTL_RECOMP.recomp_parallel(4, 'SCOTT'); Database level. EXEC UTL_RECOMP.recomp_serial(); EXEC UTL_RECOMP.recomp_parallel(4); Using job_queue_processes value. EXEC UTL_RECOMP.recomp_parallel(); EXEC UTL_RECOMP.recomp_parallel(NULL, 'SCOTT'); Restricciones del paquete: -La ejecucion en paralelo utiliza la cola de trabajos. Todos los trabajos se dehabilitan hasta que la operacin termina. -Debe ejecutarse con el usuario SYS u otros con permisos de SYSDBA. Deber existir STANDARD, DBMS_STANDARD, DBMS_JOB and DBMS_RANDOM. -El ejecutar comandos DDL a la vez puede provocar interbloqueos. Explicacin de la sintaxis utilizada para los comandos: - Las palabras en mayusculas son comandos de oracle. - Las palabras en minusculas son opiones modificables - Las partes enmarcadas con [] son opcionales - Las palabras en negrita son las opciones por defecto - Las partes enmarcadas con {} son alternativas (una u otra). - El simbolo | indica OR

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

ANEXO 1 Tipos de Datos y Conversiones Cada constante y variable posee un tipo de dato el cual especifica su forma de almacenamiento, restricciones y rango de valores vlidos. Con PL/SQL se proveen diferentes tipos de datos predefinidos. Un tipo escalar no tiene componentes internas; un tipo compuesto tiene otras componentes internas que pueden ser manipuladas individualmente. Un tipo de referencia almacena valores, llamados punteros, que designan a otros elementos de programa. Un tipo lob (large object) especifica la ubicacin de un tipo especial de datos que se almacenan de manera diferente. En la figura 3-1 se muestran los diferentes tipos de datos predefinidos y disponibles para ser utilizados.

Figura 3-1: Tipos de datos de PL/SQL

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

Conversiones Algunas veces se hace necesario convertir un valor desde un tipo de dato a otro. En PL/SQL se aceptan las conversiones de datos implcitas y explcitas. Una conversin explcita es aquella que se efecta utilizando las funciones predefinidas. Por ejemplo, para convertir un valor de carcter a fecha o nmero se utiliza TO_DATE o TO_NUMBER. Existe una cantidad limitada de funciones de conversin, que implementan esta caracterstica de conversin explcita. Cuando se hace necesario, PL/SQL puede convertir un tipo de dato a otro en forma implcita. Esto significa que la interpretacin que se dar a algn dato ser el que mejor se adecue dependiendo del contexto en que se encuentre. Tampoco significa que todas las conversiones son permitidas. Algunos ejemplos de conversin implcita ms comunes se dan cuando variables de tipo char se operan matemticamente para obtener un resultado numrico. Si PL/SQL no puede decidir a qu tipos de dato de destino puede convertir una variable se generar un error de compilacin. Tabla de conversiones implcitas Hasta BIN_I CH NT AR Desde BIN_IN T CHAR DATE LONG NUMB ER PLS_IN T RAW X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X DA LON NUMB PLS_I RA ROW VARCH TE G ER NT W ID AR2

Fundacin Cdigo Libre

www.codigolibre.org

Lic. Alfredo Leger

ROWID VARC HAR2 X

X X X X X X X X

You might also like