Está en la página 1de 19

Tema 19 Programacin avanzada en PL/SQL

TEMA 19 PROGRAMACIN AVANZADA


1.-INTRODUCCIN. 2.-TRIGGER. 3.-ELEMENTOS DE UN TRIGGER. 4.-VARIABLES NEW Y OLD. 5.-TIPOS DE DISPARADORES Y ORDEN DE EJECUCIN. 6.-MULTIPLES EVENTOS DE DISPAROS Y PREDICADOS CONCIONALES. 7.-RESTRICCIONES PARA LA CREACIN DE UN TRIGGER. 8.-DISPARADORES DE SUSTITUCIN. 9.-CONSIDERACIONES Y OPCIONES DE UTILIZACIN. 10.-ACTIVAR, DESACTIVAR. 11.-VISTAS CON INFORMACIN SOBRE TRIGGERS. 12.-REGISTROS EN PL/SQL. 13.-TABLAS PL/SQL. 14.-PAQUETES. ELEMENTOS DE UN PAQUETE. 15.-CREACIN DE UN PAQUETE. 16.UTILIZACIN DE LOS OBJETOS DEFINIDOS EN UN PAQUETE. 17.-DECLARACION DE CURSORES EN PAQUETES. 18.-AMBITOS Y OTRA CARACTERISTICAS DE LAS DECLARACIONES. 19.- CARACTERSTICAS DE ALMAECNAMIENTO Y COMPILACIN. 20.- PAQUETES SUMINISTRADOS POR ORACLE. 21.-SQL DINMICO. 22.- PASOS PARA UTILIZAR SQL DINAMICO. 23.-COMANDOS DE DEFINICIN DE DATOS. 24.-COMANDOS DE MANIPULACIN DE DATOS. 25.-CONSULTAS. 1.-INTRODUCCIN.
En los temas anteriores hemos utilizado pl/sql para crear procedimientos que se almacenen en la BD. Que deben ser invocados explcitamente para que se ejecuten. En sta unidad aprenderemos a utilizar triggers, que se dispararn automticamente al realizar determinadas operaciones en una tabla, as como de empaquetar los procedimientos junto con variables, tipos, cursores y otros elementos del lenguaje. Definiremos nuestros propios tipos usando sql dinmico para crear y modificar la definicin de las tablas y usuarios y trabajaremos con objetos cuyas caractersticas se conocen en tiempo de compilacin.

Tema 19 Programacin avanzada en PL/SQL

Tema 19 Programacin avanzada en PL/SQL

2.-TRIGGER.
Los triggers son bloques PL/SQL almacenados asociados a una tabla que se ejecutan o disparan automticamente, cuando se producen ciertos eventos o sucesos que afectan a la tabla, como puede ser una insercin, borrado o una modificacin de sus filas. Los triggers se pueden utilizar para: 1. Implementar restricciones complejas de seguridad o integridad. 2. Prevenir transacciones errneas. 3. Implementar reglas administrativas complejas. 4. Generar automticamente valores derivados. 5. Auditar las actualizaciones e incluso enviar alertas 6. Gestionar rplicas remotas e tablas. CREATE [OR REPLACE] TRIGGER name_trigger {BEFORE|AFTER} {DELETE|INSERT|UPDATE} OF [lista_columnas] [or {BEFORE|AFTER} {DELETE|INSERT|UPDATE} [OF <lista_columnas>] ON nombre_tabla [FOR EACH {STATEMENT|ROW} [WHEN (condicin)]}] DECLARE.. Crear un trigger que se llame modificar_pais. Se disparar despus de cada modificacin de la tabla pas en la tabla cliente. Su efecto ser insertar una fila en la tabla audita_cliente con el valor antiguo y el nuevo para ese cliente modificado. Clt_num, old_pais,newpais. create table audita_clt( clt_num integer, a_pais char, n_pais char ); Commit; Creamos el trigger: create or replace trigger modifica_pais after update of clt_pais on clientes for each row begin insert into audita_clt values(:old.clt_num,:old.clt_pais,:new.clt_pais); end; / Para hacer referencia al antiguo registro utilizaremos la clusula :old.nombre_campo, y para el nuevo :new.nombre_campo. SQL> update clientes 2 set clt_pais='R' 3 where clt_pais like 'F'; 4 rows updated. SQL> select * from audita_clt; CLT_NUM A N --------- - 3FR 4FR 6FR 8FR

Tema 19 Programacin avanzada en PL/SQL

Tema 19 Programacin avanzada en PL/SQL

3.-ELEMENTOS DE UN TRIGGER.
Un trigger esta compuesto de los siguientes elementos: a)Nombre del trigger b)Evento de disparo: Es el suceso que producir la ejecucin del trigger y ser siempre una orden dml: insert, update y delete. En el caso del update se podrn especificar opcionalmente las columnas cuya modificacin producir el disparo. Se puede especificar varios eventos de disparo para un mismo trigger utilizando las clusulas or. En el evento de disparo de incluye la tabla a la que el trigger queda asociado mediante la clusula On seguida del nombre de la tabla. c)Tipos de trigger: Hace referencia a dos cuestiones 1: el momento en el que se ejecute, que pude ser after o before de que se ejecute la orden de manipulacin de datos. 2: EL nivel de disparo del trigger que puede ser a su vez: A nivel de orden: El trigger se ejecutara una sola vez para cada orden independientemente del numero de filas afectadas por ella. Se puede incluir la clusula FOR EACH STATEMENT, aunque no es necesario ya que se asume por omisin. A nivel de Filas: El trigger se activara por cada fila una vez, afectada por al orden. Para ello se incluir la clusula FOR EACH ROW. d)Restriccin del trigger: La clusula when seguida de una condicion restringe. Esta condicion tiene algunas limitaciones: 1. Solamente se pueden utilizar los Triggers a nivel de fila. 2. Se trata de una condicin SQL. 3. No puede incluir una consulta vistas. e) Cuerpo del trigger: Es el cdigo que se ejecutar cuando se cumplan las especificaciones incluidas en la cabecera. Se trata de un bloque PL/SQL. Creamos un trigger que audite la tabla tienda. Para ello crearemos una tabla llamada tiendas_borradas. /*hemos creado la tabla ya!!*/ create or replace trigger audita_tiendas after delete on tiendas for each row begin insert into tiendas_borradas values(:old.tda_num,:old.tda_pob,:old.tda_ger); end; / SQL> delete from tiendas where tda_num=1; 1 row deleted. SQL> select * from tiendas_borradas; TDA_NUM TDA_POB TDA_GER --------- --------------- ------------------------1 MADRID-Batn CONTESFOSQUES, Jordi

Tema 19 Programacin avanzada en PL/SQL

Tema 19 Programacin avanzada en PL/SQL

4.-VARIABLES NEW Y OLD.


Se puede hacer referencia a los valores anteriores o posteriores a una actualizacin a nivel de filas, mediante: :OLD.NOMBRE_COLUMNA :NEW.NOMBRE_COLUMNA IF :NEW.SALARIO <:OLD.SALARIO ---NO LO ACTUALIZO Al actualizar los valores old y new, deberemos de tener en cuenta los elementos de disparo. 1. Cuando el evento que dispara el trigger es delete, deberemos hacer referencia a :old.nombre_columna, ya que el valor de new es NULL. 2. Paralelamente cuando el evento es insert, el valor a tratar es el new, ya que el antiguo no existe. 3. Para los Triggers para el que el evento de disparo es el update, tiene sentido el old y new. En el caso de que queramos hacer referencia a los valores new y old, al indicar la restriccin del trigger en la clusula when, lo haremos sin poner los dos puntos. Por ejemplo when new.salario<old.salario. Si queremos que en lugar de old y new aparezcan otras palabras, lo indicaremos con la clusula referencing. Referencing new as nuevo ,old as viejo. Conviene recordar que slo se puede hacer referencia a los valores new y old en los disparadores a nivel de fila.

5.-TIPOS DE DISPARADORES Y ORDEN DE EJECUCIN.


Una misma tabla puede tener varios Triggers. El orden ser el siguiente: 1. Antes de comenzar a ejecutar la orden que produce el disparo, se ejecutaran los Triggers before..for each statement. Para cada fila afectada por el orden se ejecutaran los disparadores before for each row. Se ejecuta la actualizacin de la fila(insert,update,delete) y en este momento se bloquea la fila hasta que e la transaccin se confirme. 2. Se ejecutan los disparadores after for each row. Una vez ejecutado el comando DML. Observaciones: Cuando se dispara un trigger, ste forma pare de la operacin de actualizacin que lo dispar, de manera que si el trigger falla, Oracle dar por fallida la actualizacin completa. Aunque el fallo sea de una sola fila, Oracle har rollback de todos las actualizaciones realizadas. En ocasiones en lugar de asociar varios Triggers a una sola tabla, podremos optar por la actualizacin de un solo trigger con mltiples eventos de disparos, como veremos a continuacin......

6.-MULTIPLES EVENTOS DE DISPAROS Y PREDICADOS


Un mismo trigger puede ser disparado por distintas operaciones o eventos de disparo. Para indicarlo se utilizar el indicador OR. En stos casos es probable que una parte de las acciones pl/sql dependa del tipo de evento que dispar el trigger. Para

Tema 19 Programacin avanzada en PL/SQL

Tema 19 Programacin avanzada en PL/SQL


facilitar este control, Oracle permite la utilizacin de predicados condicionales, que devolvern un valor verdadero o falso para cada una de las posibles operaciones. Tipos de predicados:

INSERTING: Devuelve true si el comando es un insert. DELETING: devuelve true si el comando que se dispar es un delete. UPDATING: Devuelve true si el comando que se dispar es un update. UPDATING(COLUMNA)

Trigger que controlara insert,update y delete de la tabla clientes. Insert-Fila INSERTADA Delete-fila eliminada Delete(clt_pais)- se actualizo un pais!! create or replace trigger controla_cliente after insert or delete or update on clientes for each row begin if inserting then dbms_output.put_line('Fila insertada!!'); end if; if deleting then dbms_output.put_line('Fila Borrada'); end if; if updating('clt_pais') then dbms_output.put_line('Pais Introducido!!'); end if; end; /

7.-RESTRICCIONES PARA LA CREACIN DE UN TRIGGER.


El bloque PL/SQL no puede contener sentencias de control de transacciones como commit, rollback o savepoint. No puede usar comandos DDL. Un trigger no puede contener instrucciones que consulten o modifiquen tablas mutantes. Una tabla mutante es aquella que esta siendo modificada por una sentencia insert, delete, update en la ltima sesin. No se puede cambiar valores de las columnas que sea calves primarias nicas ajenas de tablas de restriccin. Los triggers a nivel de comandos for each statement no se vern afectados para las restricciones de tablas mutantes y tablas de restriccin, excepto cuando el trigger se dispare como resultado de una restriccin delete cascade.

Tema 19 Programacin avanzada en PL/SQL

Tema 19 Programacin avanzada en PL/SQL

8.-DISPARADORES DE SUSTITUCIN
Se pueden crear triggers que no se ejecuten ni antes ni despus,( sino en lugar de instead of,) en lugar de la orden de manipulacin que da lugar al disparo del trigger, se denominan disparadores de sustitucin. CREATE OR REPLACE TRIGGER nombre INSTEAD OF{delete|insert|update [of <lista cols>]} [OR {DELETE|INSERT|UPDATE [of <lista cols>]} ON nombre_vista [FOR EACH ROW] [DECLARE Los disparadores de sustitucin tienen estas caractersticas referenciales a. Solo se usan en Triggers asociados a vistas, y son especialmente tiles para realizar operaciones complejas de actualizacin. b. Actan siempre a nivel de fila, no a nivel de orden, por tanto a diferencia de lo que ocurra en los disparadores asociados a una tabla la opcin por omisin es FOR EACH ROW. c. No se puede especificar una restriccin de disparo mediante la clusula when, pero se puede conseguir la funcionalidad similar usando estructuras alternativas del bloque PL/SQL. Creamos un vista clientes_ventas. Trigger borrar que cuando borre en la vista se borren en las tablas originales. /******************vista**********************/ create view clientes_ventas as (select clientes.clt_num,clientes.clt_apell,clientes.clt_nom,clientes.clt_pais,clientes.clt_pob,venta s.vnt_tda,ventas.vnt_art,ventas.vnt_cant,ventas.vnt_precio,ventas.vnt_fch from clientes,ventas where clientes.clt_num=ventas.vnt_clt); /********************************************/ create or replace trigger borrar INSTEAD OF delete or insert or update ON clientes_ventas FOR EACH ROW begin if deleting then delete from ventas where ventas.vnt_clt=:old.clt_num; dbms_output.put_line('Se borraron registros de la tabla ventas!!'); delete from clientes where clientes.clt_num=:old.clt_num; dbms_output.put_line('Se borraron registros de la tabla clientes!!'); end if; end; /

Tema 19 Programacin avanzada en PL/SQL

Tema 19 Programacin avanzada en PL/SQL

9.-CONSIDERACIONES Y OPCIONES DE UTILIZACIN.


Para crear un trigger hay que tener privilegios de create trigger, as como los correspondientes privilegios sobre la/s tabla y otros objetos referenciados por el trigger. Con el nombre del trigger se puede especificar el esquema en el que queremos crear el trigger, usando la notacin del punto. En el nivel fsico estn todas las tablas, y en el nivel usuario hay tantos usuarios como haya. Por omisin, nuestro esquema actual es el que usamos al crear el trigger. EL privilegio create any trigger, permite crear Triggers en cualquier esquema. Normalmente un trigger se asocia a una tabla. Normalmente un trigger se asocia a una tabla pero tambin se puede asociar a una vista. As mismo la tabla o vista puede pertenecer a un esquema distinto del actual, siempre que se tengan los privilegios correspondientes, en este caso se utilizar la notacin del punto. No se puede asociar un trigger a una tabla o esquema sys. Un trigger forma parte de la operacin de actualizacin que lo dispar, y si falla Oracle dar por fallida la operacin. Esta caracterstica pede servir para impedir desde el trigger que se realice una determinada operacin. Haremos una excepcin dentro de un trigger para que salte.!!!

10.-ACTIVAR, DESACTIVAR, COMPILAR Y ELIMINAR UN TRIGGER.


ALTER TRIGGER NOMBRE {ENABLE|DISABLE|COMPILE}

11.-VISTAS CON INFORMACIN SOBRE Triggers.


USER_Triggers SQL> SELECT TRIGGER_BODY FROM USER_TRIGGERS; TRIGGER_BODY -------------------------------------------------------------------------------begin insert into tiendas_borradas values(:old.tda_num,:old.tda_pob,:old.tda_ger begin if deleting then delete from ventas where ventas.vnt_clt=:old.clt_nu begin if inserting then dbms_output.put_line('Fila insertada!!'); end if begin insert into audita_clt values(:old.clt_num,:old.clt_pais,:new.clt_pais); SQL> DESC DBA_TRIGGERS; Name Null? Type ----------------------------------------------------- -------- ---------------OWNER VARCHAR2(30) TRIGGER_NAME VARCHAR2(30) TRIGGER_TYPE VARCHAR2(16) TRIGGERING_EVENT VARCHAR2(75) TABLE_OWNER VARCHAR2(30)

Tema 19 Programacin avanzada en PL/SQL

Tema 19 Programacin avanzada en PL/SQL


BASE_OBJECT_TYPE TABLE_NAME COLUMN_NAME REFERENCING_NAMES WHEN_CLAUSE STATUS DESCRIPTION ACTION_TYPE TRIGGER_BODY VARCHAR2(16) VARCHAR2(30) VARCHAR2(4000) VARCHAR2(128) VARCHAR2(4000) VARCHAR2(8) VARCHAR2(4000) VARCHAR2(11) LONG

12.-REGISTROS EN PL/SQL
El concepto de registro en PL/SQL es igual a la mayora de los lenguajes de programacin. Se trata de una estructura compuesta de otras ms simples(campos) que pueden ser de diferentes tipos. Para crear una estructura de datos idntica a la fila de una tabla. Esta estructura de datos es un registro. Esta forma de crear los registros es muy sencilla y rpida, pero plantea alguna limitations 1) Con el ROWTYPE todos los nombre de sus campos con sus tipos, quedaran determinados por los nombres y tipos de las columnas de la tabla, sin que exista la posibilidad de variar algunos de ellos o de incluir/excluir ms campos. 2) No se incluyen restricciones como not null ni valores por defecto. 3) La posibilidad de creacin de variables de registro utilizando este formato, quedara condicionada a la existencia de la tabla y sus posibles variaciones. PL/SQL permite salvar todas estas limitaciones definiendo nosotros mismos el registro y declarando despus todas las variables de este tipo que necesitemos. Para ello procederemos segn la sintaxis.

SINTAXIS DE LOS REGISTROS


1. Declaracin del tipo del registro: TYPE nombre_tipo IS RECORD ( nombre_campo tipo_campo [ NOT NULL] [{:=DEFAULT } VALOR INICIAL], ..... ); Los tipos de los campos se pueden especificar con %type y %rowtype. Los tipos que contengan el valor not null deben ser inicializados. Por ejemplo: TYPE PERSONA IS RECORD ( DNI VARCHAR2(10) NOT NULL :=00000000-Z, NOMBRE VARCHAR2(20) :=Pepe ); 2. Declaracin de la variable del tipo registro. Se declaran las variables que se necesitan segn la siguiente sintaxis: V_persona Persona; Podemos usar sta anotacin para asignar valores, como si se tratasen de cualquier variable, pero debemos tener cuidado con la asignacin var1:= var2 ya que slo funcionar cuando ambas variables hayan sido definidas sobre el

Tema 19 Programacin avanzada en PL/SQL

Tema 19 Programacin avanzada en PL/SQL


mismo tipo base.(No podemos igualar dos variables de distinto tipo en los registros!!). En caso contrario an cuando coincidan los tipos longitudes de los tipos, y nombres de los campos, dara error. Un campo en un registro puede ser a su vez un registro. Crear un tipo cliente e igualarlo a otra variable. Type T_Cliente /*Declaracion del registro*/ ( clt_num integer not null, clt_pob varchar2(1) ); V_Cliente T_Cliente; /*Declaracin de la variable del tipo T_Cliente*/ Ejemplo: Type T_Venta /*Declaramos un registro T_Venta*/ (cantidad integer, precio integer, datos T_Cliente ); /*declaramos una variable del tipo T_Cliente para hacer /*referencia a clientes*/ V_ventas T_Ventas; Para hacer referencia a apellidos usaremos la next sintaxis: T_Ventas.Datos.Apellidos

13.-TABLAS PL/SQL.
El tipo de datos table en PL/SQL sirve para definir estructuras similares a los arrays, que usan otros lenguajes Por tanto es completamente diferente del concepto de tabla que usan lo SGBDR. Los tables PL/SQL tienen unas caractersticas que les hace distintas de lo que suelen ser los arrays en los lenguajes de programacin. Tienen 2 columnas: La primera es el ndice o clave de tipo binario entero. (Binary_Integer) La segunda es la columna que guardar la informacin, cuyo tipo deber definir el programador. El ndice no tiene que ser necesariamente secuencial y los elementos no ocupan posiciones correlativas en memoria. No tienen una longitud predeterminada. En cualquier lenguaje hay que especificar el tamao del array, pero con Oracle no. El nmero de filas puede incrementarse dinmicamente. El lmite lo determina el rango de los Binary_Integer. 1. Definicin del tipo de table y declaracin de variables TYPE nombre_tipo IS TABLE OF tipo_elementos [NOT NULL] INDEX BY BINARY_INTEGER; Nombre_tipo: Especificador que indica base del table y se usar para definir las tablas.

Tema 19 Programacin avanzada en PL/SQL

Tema 19 Programacin avanzada en PL/SQL


Tipo_elementos: Especifica el tipo de elementos que va a contener. Puede hacerse de varias maneras. a) Indicando el tipo de y longitud si se produce como si fuera una columna de una tabla. b) Indicando nombre_variable%type, indicando nombre_tabla.nombre_columna%type(haciendo referencia al tipo de la columna). Ejemplo tabla(T_tabla_clientes) que contenga la tabla clientes. Declare Type V_tabla_clientes type of clientes%rowtype index by binary_integer; /*como vemos el primer campo del registro V_table_clientes ser de tipo binary_integer, pero el segundo ser del tipo de una fila de la tabla clientes(clt_num,clt_nom,....)*/ Una vez declarado el tipo base se pueden declarar tables como se desee, usando el formato: Nombre_table Nombre_tipo; Ejemplo: V_T_tabla_clientes T_tabla_clientes; 2. Utilizacin de variables de tabla: Para referenciar a los elementos de una variable del tipo table: Nombre_tabla y entre parntesis el nmero de elemento. Haremos lo mismo para introducir valores. Los elementos pueden ser usados, cmo si se tratasen de cualquier variable. V_T_tabla_clientes(1) Cuando los elementos de la table son de tipo registro, usaremos la notacin del punto, segn el siguiente formato: Nombre_table(numero).nombre_campo; Asignar al cliente n1 a ese vector: Select * into V_T_tabla_clientes(1) from clientes where clt_num=1; 3. Atributos de las tables PL/SQL. Los atributos de las tables facilitan la gestin de las variables de tipo table, permitiendo recorrer la table, contar y borrar elementos de sta. VARIABLE_TABLA.ATRIBUTO[(elemento)] Los elementos hacen referencia a los valores de ndice. FIRST: Devuelve el valor BINARY_INTEGER de la clave ndice del primer elemento ndice de la tabla. Variable.first(variable del tipo table) LAST: Devuelve el valor BINARY_INTEGER de la clave ndice del ltimo elemento de la table. Para recorrer una table con valores relativos:

Tema 19 Programacin avanzada en PL/SQL

10

Tema 19 Programacin avanzada en PL/SQL


For variable.first .. variable.last PRIOR: Devuelve el valor BINARY_INTEGER de la clave ndice del anterior elemento N. Variable.prior(n) NEXT: Devuelve el valor BINARY_INTEGER de la clave ndice del siguiente elemento de n. Variable.next(n) Prior y next se pueden utilizar para recorrer una table en cualquier sentido. Siempre y cuando sea correlativa. No obstante debemos tener cuidado con los valores que devolver en ambos extremos, ya que puede ser basura de memoria. I:variable.first; While i is not null loop .. i:=variable.next; End loop; COUNT: Devuelve el nmero de filas que tiene un table Variable.count EXIST: Devuelve true si existe el elemento n. En caso contrario se usa para evitar el error ORA-1403, que se produce cuando accedemos a un elemento que no existe y se levanta la excepcin no_data_foun. Variable.exist(n) DELETE: Se usan para borrar elementos de la table. Variable.delete. Borra todo el table. Variable.delete(n): Borra el elemento n. Si el valor es null, no har nada Variable(n1,n2): Borra el intervalo de n1 a n2. (Si n1 es menor que n2). Una table se borra al salir del mbito dl programa bloque en que se cre.( Desaparece de memoria)free^^.

14.-PAQUETES. ELEMENTOS DE UN PAQUETE.


Un paquete se usa para guardar subprogramas y otros objetos de la B.D. En los paquetes podemos encontrar habitualmente dos elementos diferenciados: 1. Especificacin: Contiene declaraciones pblicas, accesible desde cualquier parte de la aplicacin, subprogramas, tipos, constantes, variables, cursores. Actan como una interfaz con otros programas.(Se parece a la cabecera de los programas en C).

Tema 19 Programacin avanzada en PL/SQL

11

Tema 19 Programacin avanzada en PL/SQL


2. Cuerpo: Contiene los detalles de implementacin y declaraciones privadas, accesibles solamente desde los objetos del paquete. Es una caja negra para los dems programas. CREATE [OR REPLACE] PACKAGE BODY nombre_paquete AS <declaraciones de tipos, constantes, variables, cursores, excepciones y otros objetos pblicos> <especificaciones de subprogramas> END[nombre_paquete]; Crearemos la cabecera de un paquete buscar_cliente <Crear tipo_registro T_registro-reg_cliente procedimiento ver_por_numero procedimiento ver_por_apellido procedimiento ver_por_nombre Funcin que se llame datos()as datos del cliente; funcin ver_cliente(

15.-CREACIN DE UN PAQUETE.
Una vez creada la cabecera del paquete, el cuerpo del paquete tendr el cdigo correspondiente a las declaraciones formales realizadas. Podr incluir otros objetos locales al paquete, como pueden ser tipos, variables de tipo registro, excepciones.... CREATE OR REPLACE PACKAGE busca_cliente AS type T_cliente is record (codigo clientes.clt_num%type, apellido clientes.clt_apell%type, nombre clientes.clt_nom%type, pais clientes.clt_pais%type, pob clientes.clt_pob%type ); procedure ver_por_num(numero clientes.clt_num%type); procedure ver_por_nombre(nombre clientes.clt_nom%type); procedure ver_por_apellido(apellido clientes.clt_apell%type); end busca_cliente; / SQL> @yo Package created. CREATE OR REPLACE PACKAGE BODY busca_cliente AS V_Cliente T_cliente; procedure mostrar_datos; procedure mostrar_datos is begin dbms_output.put_line('El nombre es : '|| V_Cliente.nombre); dbms_output.put_line('El apellido es :'|| V_cliente.apellido); dbms_output.put_line('El Numero cliente es :'|| V_cliente.codigo);

Tema 19 Programacin avanzada en PL/SQL

12

Tema 19 Programacin avanzada en PL/SQL


dbms_output.put_line('La Ciudad es :'||V_Cliente.pob); dbms_output.put_line('El pas es :'||V_Cliente.pais); end mostrar_datos; procedure ver_por_num(numero clientes.clt_num%type) is begin select * into V_cliente from clientes where clt_num=numero; mostrar_datos; exception when no_data_found then dbms_output.put_line('No se encontr cliente!!!'); end ver_por_num; procedure ver_por_apellido(apellido clientes.clt_apell%type) is begin select * into V_Cliente from clientes where clt_apell=apellido; mostrar_datos; exception when no_data_found then dbms_output.put_line('No se encontr cliente!!!'); end ver_por_apellido; procedure ver_por_nombre(nombre clientes.clt_nom%type) is begin select * into V_cliente from clientes where clt_nom=nombre; mostrar_datos; exception when no_data_found then dbms_output.put_line('No se encontr cliente!!!'); end ver_por_nombre; END busca_cliente; / Tenemos que compilarlos independientemente, de lo contrario producira error.

16.UTILIZACIN DE LOS OBJETOS DEFINIDOS EN UN PAQUETE.


1.Llamada a un procedimiento desde dentro del paquete: Desde el mismo paquete todos los objetos pueden ser usados desde el propio paquete

Tema 19 Programacin avanzada en PL/SQL

13

Tema 19 Programacin avanzada en PL/SQL


Todos los objetos declarados en el paquete pueden ser usados por los dems objetos con independencia de que hayan sido declarados en la especificacin. Adems, no necesitan utilizar la anotacin de punto para referirse a los objetos del mismo paquete. Los procedimientos ver_por_num y ver apell, llaman al procedimiento mostrar_datos que no est en la especificacin. procedure ver_por_apellido(apellido clientes.clt_apell%type) is begin select * into V_Cliente from clientes where clt_apell=apellido; mostrar_datos; exception when no_data_found then dbms_output.put_line('No se encontr cliente!!!'); end ver_por_apellido; 2. Llamada a un procedimiento desde fuera de un paquete:

Los subprogramas y otros objetos contenidos en el paquete son accesibles desde fuera solamente si han sido declarados en la especificacin. Todo lo no declarado no podr ser llamado. En nuestro ejemplo no se puede llamar al procedimiento mostar_datos desde fuera del paquete. Para ejecutar un procedimiento de un paquete desde SQL/PLUS usaremos: EXECUTE NOMBRE_PAQUETE.NOMBRE_PROCEDIMIENTO (lista parmetros).

17.-DECLARACION DE CURSORES EN PAQUETES.


Para declarar cursores en paquetes, de forma que estn accesibles en la especificacin, deberemos separar la declaracin del cursor del cuerpo. La declaracin del cursor se incluir en la cabecera del paquete, indicando el nombre del cursor, los parmetros si procede y el tipo que devuelve, ste ltimo se indicar mediante:

RETURN tipo_dato;
Para cursores que devuelvan filas enteras: %ROWTYPE; CREATE PACKAGE NO MBRE AS .. CURSOR CUR1 RETURN CLIENTES%ROWTYPE; END NOMBRE; Declaracin de un cursor dentro del cuerpo: CREATE PACKAGE BODY NOMBRE1 AS CURSOR CUR1 RETURN CLIENTES%ROWTYPE; SELECT * FROM CLIENTES WHERE CLT_POB=E; END NOMBRE1;

Tema 19 Programacin avanzada en PL/SQL

14

Tema 19 Programacin avanzada en PL/SQL

18.-AMBITOS Y OTRA CARACTERISTRICAS DE LAS DECLARACIONES.


Los objetos declarados en la declaracin del paquete, son globales al paquete y locales al contexto. As mismo todas las variables declaradas en la especificacin del paquete, mantienen su valor durante la sesin. Tambin cabe destacar respecto a las constantes, variables declarados en un paquete, lo siguiente: El propietario es la sesin Cuando se crean los objetos su valor ser nulo, salvo que se inicialicen. Durante la sesin los valores pueden cambiarse. En la sesin no se crean los objetos hasta que se referencia al paquete. Al salir de la sesin, os valores se pierden.

19.- CARACTERSTICAS DE ALMACENAMIENTO Y COMPILACIN.


Tanto el cdigo fuente, como el cdigo compilado, se almacena en la BD. Al igual que ocurra con los subprogramas almacenados, puede temer dos estados(VALID/INVALID). Cuando se borra o modifica algunos de los elementos referenciados el paquete pasar a invalid. Si la especificacin del paquete se encuentra invalid, ORACLE invalida cualquier objeto que haga referencia al paquete. Cuando recompilamos la especificacin todos los objetos que hacen referencia al paquete, pasan a invalid hasta que sean compilados de nuevo. Cualquier referencia o llamado a algunos de stos objetos, producir que ORACLE los recompile por su cuenta. Si se cambia el cuerpo de un procedimiento o funcin incluido en un paquete, no hay que recompilar todos los programas que llaman al subprograma, a no ser que se cambie la especificacin de dicho paquete.

20.- PAQUETES SUMINISTRADOS POR ORACLE.


Oracle incluye con su SGBD paquetes como: STANDARD Se declaran tipos, funciones, excepciones disponibles desde el entrono PL/SQL. ABS: FUNCTION ABS(NUMBER) RETURN NUMBER; TO_CHAR DBMS_OUTPUT Put_line DBMS_STANDARD Incluye utilidades como el procedimiento raise_application_error. DBMS_SQL Utiliza procedimiento y funciones que permiten utilizar SQL dinmico. ENABLE/DISABLE: Configura y borra el buffer.

21.-SQL DINMICO.
Tema 19 Programacin avanzada en PL/SQL

15

Tema 19 Programacin avanzada en PL/SQL

Cuando se compila un procedimiento PL/SQL comprueba en el diccionario de datos y completa todas las referencias a objetos de la BD, como pueden ser tablas, columnas, usuarios... De sta forma si el objeto no existe en el momento de compilacin y saltar la excepcin correspondiente. Esa manera de trabajar tiene importantes ventajas, especialmente en cuanto a la velocidad de ejecucin y en la seguridad de que la referencia a los objetos han sido comprobadas previamente, pero tambin tiene inconvenientes: 1. Todos los procedimientos tienen. 2. No se pueden crear objetos nuevos con el programa. 3. No se puede cambiar la definicin de los objetos. Esta forma de trabajar con SQL, se denomina esttico.

22.- PASOS PARA UTILIZAR SQL DINAMICO.


El paquete DBMS_SQL permite superar estas limitaciones y ejecutar instrucciones de definiciones de datos, as como resolver referencias a objetos en el momento de la ejecucin(SQL DINMICO). El paquete DBMS_SQL tendr una serie de procedimientos: i. ii. Open_cursor: Abre el cursor y devuelve un nmero de identificacin(entero) para poder utilizarlo. Parse: Analiza la instruccin que se va a ejecutar. Este paso es necesario ya que cuando se compil el programa la instruccin no pudo ser analizada, pues aun no se haba construido. DBMS_SQL.PARSE(ID,INSTRUCCIN,DBMS_SQL.V8|native); iii. iv. Execute : Encargado de la ejecucin. Close_cursor: Cierra el cursor.

Ejercicio: Procedimiento que cree un usuario que le paso el nombre/pass dum1/dum1. create or replace procedure crear_user(login char,pass char) is instruccion char(40); id integer; begin instruccion:='create user '||login||' identified by '||pass; id:=dbms_sql.open_cursor; dbms_sql.parse (id,instruccion,dbms_sql.native); dbms_sql.close_cursor(id); end crear_user; /

23.-COMANDOS DE DEFINICIN DE DATOS.


Crear una tabla con 3 campos; CREATE OR REPLACE PROCEDURE CREA_TABLA(NOMBRE CHAR,CAMPO1 CHAR,CAMPO2 CHAR,CAMPO3 CHAR) IS INSTRUCCION CHAR(150); CUR_ID INTEGER; RESULTADO INTEGER; BEGIN CUR_ID := DBMS_SQL.OPEN_CURSOR;

Tema 19 Programacin avanzada en PL/SQL

16

Tema 19 Programacin avanzada en PL/SQL


INSTRUCCION := 'CREATE TABLE '||NOMBRE||' ('||CAMPO1||' CHAR(50) PRIMARY KEY,'||CAMPO2||' CHAR(50),'||CAMPO3||' CHAR(50))'; DBMS_SQL.PARSE(CUR_ID,INSTRUCCION,DBMS_SQL.NATIVE); RESULTADO := DBMS_SQL.EXECUTE(CUR_ID); DBMS_SQL.CLOSE_CURSOR(CUR_ID); END CREA_TABLA; / SQL> @tu Input truncated to 1 characters Procedure created. SQL> exec crea_tabla('a','b','c','d'); PL/SQL procedure successfully completed. SQL> desc a Name Null? Type ----------------------------------------------------- -------- -------B NOT NULL CHAR(50) C CHAR(50) D CHAR(50)

24.-COMANDOS DE MANIPULACIN DE DATOS.


EJEMPLO CON UN TABLA DE UN CAMPO: CREATE OR REPLACE PROCEDURE CREA_TABLA(NOMBRE CHAR,CAMPO1 CHAR) IS INSTRUCCION CHAR(150); CUR_ID INTEGER; RESULTADO INTEGER; BEGIN CUR_ID := DBMS_SQL.OPEN_CURSOR; INSTRUCCION := 'CREATE TABLE '||NOMBRE||' ('||CAMPO1||' CHAR(50) PRIMARY KEY)'; DBMS_SQL.PARSE(CUR_ID,INSTRUCCION,DBMS_SQL.NATIVE); RESULTADO := DBMS_SQL.EXECUTE(CUR_ID); DBMS_SQL.CLOSE_CURSOR(CUR_ID); END CREA_TABLA; / SQL> @TU Input truncated to 1 characters Procedure created. SQL> EXEC CREA_TABLA('B','A'); PL/SQL procedure successfully completed DBMS_SQL.BIND_VARIABLE(ID,:VARIABLE_1,VALOR);

ste procedimiento interno de Oracle se posiciona en donde apunte el cursor y sustituye la cadena :variable por valor. Insercion: CREATE OR REPLACE PROCEDURE INSERTA(TABLA CHAR,VALOR CHAR) IS ID INTEGER;

Tema 19 Programacin avanzada en PL/SQL

17

Tema 19 Programacin avanzada en PL/SQL


INSTRUCCION CHAR(60); RESULTADO INTEGER; BEGIN ID:=DBMS_SQL.OPEN_CURSOR; INSTRUCCION:='INSERT INTO '||TABLA||' VALUES(:mi_variable)'; DBMS_SQL.PARSE(ID,INSTRUCCION,DBMS_SQL.NATIVE); DBMS_SQL.BIND_VARIABLE(ID,':mi_variable',valor); resultado:=dbms_sql.execute(id); DBMS_SQL.CLOSE_CURSOR(ID); END INSERTA; / Como vemos mi variable es una variable implcita del procedimiento.

25.-CONSULTAS.
Hacer un consulta dinmica en clientes, donde el clt_num sea mayor que cinco; Le pasaremos una condicin y un valor; P a(cond, valor) Dentro del procedimiento declararemos tantas variables como campos tiene la tabla clientes.nuevo procedimiento llamado dbms_sql.define_colum(id,1,variable[,tamao]) Define sirve para especificar las variables que recibirn los valores de la seleccin. Se utilizar una llamada para cada variable indicando: el id del cursor, el numero de la columna de la que recibir el valor, el nombre de la variable(si la variable es de tipo char, varchar2, o raw, hay que especificar la longitud, como cuarto parmetro). Una vez tenemos el define colum, el siguiente es dbms_sql.colum_value(id,1,variable[,tamao]) deposita el valor recuperado, cuya posicin se especifica en una variable SQL. Otro procedimiento con el dbms_sql.fetch_rows. create or replace procedure seleccionar(condicion char,valor integer) is id integer; resultado integer; instruccion char(100); nombre clientes.clt_nom%type; apellido clientes.clt_apell%type; begin id:=dbms_sql.open_cursor; instruccion:= 'select clt_nom, clt_apell from clientes where '|| condicion||':mi_variable'; dbms_sql.parse(id,instruccion,dbms_sql.native); dbms_sql.bind_variable(id,':mi_variable',valor); resultado:=dbms_sql.execute(id); dbms_sql.define_column(id,1,nombre,10); dbms_sql.define_column(id,2,apellido,10); while dbms_sql.fetch_rows(id)>0 loop dbms_sql.column_value(id,1,nombre); dbms_output.put_line(nombre); dbms_sql.column_value(id,2,apellido); dbms_output.put_line(apellido); end loop;

Tema 19 Programacin avanzada en PL/SQL

18

Tema 19 Programacin avanzada en PL/SQL


end seleccionar; /

Tema 19 Programacin avanzada en PL/SQL

19