Sentencias Select, Operadores de Conjuntos, PL/SQL, Procedimientos Almacenados, Funciones, Triggers y Cursores .
Contenidos:
1. SENTENCIAS SELECT 2. OPERADORES DE CONJUNTOS (UNIN, UNIN ALL, INTERSECT, MINUS) 3. INTRODUCCION AL LENGUAJE PL/SQL 4. PROCEDIMIENTOS ALMACENADOS 5. FUNCIONES 6. TRIGGERS 7. CURSORES
Objetivo:
Que el alumno aprenda a desarrollar e implementar procedimientos almacenados, funciones para operaciones en la base de datos en Oracle. Que comprendan la utilidad de los disparadores (triggers) para operaciones de manipulacin o creacin de datos.
2
1- SENTENCIAS SELECT
La sentencia SELECT se utiliza para seleccionar(consultar) datos desde una base de datos. En su mayoria, estas consultas se hacen sobre tablas o vistas de la base de datos, y el resultado obtenido puede variar desde cero, una o mas filas.
SELECT Palabra clave que indica que la sentencia de SQL que queremos ejecutar es de seleccin. ALL Indica que queremos seleccionar todos los valores.Es el valor por defecto y no suele especificarse casi nunca. DISTINCT Indica que queremos seleccionar slo los valores distintos. FROM Indica la tabla (o tablas) desde la que queremos recuperar los datos. En el caso de que exista ms de una tabla se denomina a la consulta "consulta combinada" o "join". En las consultas combinadas es necesario aplicar una condicin de combinacin a travs de una clusula WHERE. WHERE Especifica una condicin que debe cumplirse para que los datos sean devueltos por la consulta. Admite los operadores lgicos AND y OR. GROUP BY Especifica la agrupacin que se da a los datos. Se usa siempre en combinacin con funciones agregadas. HAVING Especifica una condicin que debe cumplirse para los datos. Especifica una condicin que debe cumplirse para que los datos sean devueltos por la consulta. Su funcionamiento es similar al de WHERE pero aplicado al conjunto de resultados devueltos por la consulta. Debe aplicarse siempre junto a GROUP BY y la condicion debe estar referida a los campos contenidos en ella. ORDER BY Presenta el resultado ordenado por las columnas indicadas. El orden puede expresarse con ASC (orden ascendente) y DESC (orden descendente). El valor predeterminado es ASC.
Las consultas se pueden hacer sobre una sola tabla y sobre varias tablas. A continuacion crearemos 2 tablas para ejemplificar ambos casos. Es necesario dejar en claro que este curso no es un curso de fundamentos de bases de datos, sino mas bien de administracion y seguridad, por lo que es responsabilidad del alumno profundizar mas en todos los aspectos de la sentencia SELECT. Esta practica se limitara a explicar solo aquellos puntos que se estiman importantes.
3
2- OPERADORES DE CONJUNTOS
Hay tres operadores de conjuntos: UNION, INTERSECT y MINUS.
PARA EJEMPLIFICAR CADA OPERADOR PRIMERO CREAREMOS LAS SIGUIENTES TABLAS DE PRUEBAS. Una academia de msica da clases de guitarra y de piano; en su base de datos existe una tabla Para los alumnos de guitarra llamada guitarra y otra para los alumnos de piano llamada piano. La academia necesita el nombre y direccion de todos los alumnos, de todos los cursos para enviarles una tarjeta de felicitacin para el da del alumno.
create table alumnos_guitarra( cod int primary key, nombre varchar2(50), direccion varchar2(100) ); create table alumnos_piano( cod int primary key, nombre varchar2(50), direccion varchar2(100) ); --alumnos de guitarra insert into alumnos_guitarra values(1,'juan','dicc juan'); insert into alumnos_guitarra values(2,'jose','dicc jose'); insert into alumnos_guitarra values(3,'pedro','dicc pedro'); --alumnos de piano --OJO: juan tambien estudia piano insert into alumnos_piano values(1,'juan','dicc juan'); insert into alumnos_piano values(2,'marta','dicc marta'); insert into alumnos_piano values(3,'anita','dicc anita');
UNION Se usan cuando los datos que se quieren obtener pertenecen a distintas tablas y no se puede acceder a ellos con una sola consulta. Es necesario que las tablas referenciadas tengan tipos de datos similares, la misma cantidad de campos y el mismo orden de campos en la lista de seleccin de cada consulta. SINTAXIS SELECT1 UNION SELECT2;
EJEMPLO --La academia quiere enviar la tarjeta a TODOS sus alumnos
--UNION (NO muestra los repetidos) select nombre, direccion from alumnos_guitarra union select nombre, direccion from alumnos_piano; --UNION ALL (SI muestra los repetidos) select nombre, direccion from alumnos_guitarra union all select nombre, direccion from alumnos_piano;
4
INTERSECT Devuelve la interseccin de las consultas involucradas; es decir, el resultado retornar los registros que se encuentran en la primera y segunda consulta (y dems si las hubiere), o sea, los registros que todas las consultas tienen en comn.
SINTAXIS SELECT1 INTERSECT SELECT2;
EJEMPLO --La academia quiere enviar la tarjeta SOLO a los alumnos inscritos en ambos instrumentos.
--INTERSECT (solo los registros que estn en ambas tablas) select nombre, direccion from alumnos_guitarra intersect select nombre, direccion from alumnos_piano;
MINUS Devuelve los registros de la primera consulta que no se encuentran en segunda consulta, es decir, aquellos registros que no coinciden. Es el equivalente a "except" en SQL.
SINTAXIS SELECT1 MINUS SELECT2;
EJEMPLO --La academia quiere enviar la tarjeta SOLO a los alumnos de guitarra.
--MINUS (solo los registros que estan en la primera pero no en la segunda tabla) select nombre, direccion from alumnos_guitarra minus select nombre, direccion from alumnos_piano;
NOTA:
Tanto UNION, UNION ALL, INTERSECT Y MINUS puede combinarse con la clusula "order by".
5
3- INTRODUCCION AL LENGUAJE PL/SQL
PL/SQL (Procedural Language/Structured Query Language) En espaol significa: Lenguaje de Procedimiento/Lenguaje de Consulta Estructurado. Es un lenguaje de programacin incorporado en Oracle y todas sus herramientas: forms, reports, SQL Developer, etc. Permite soportar todas las consultas, ya que la manipulacin de datos que se utiliza es la misma que en SQL, incluyendo nuevas caractersticas: El manejo de variables, Estructuras modulares, Estructuras de control de flujo y toma de decisiones, Control de excepciones.
BLOQUE PL/SQL Bloque es la unidad de estructura bsica en los programas PL/SQL. Supone una mejora en el rendimiento, pues se envan los bloques completos al servidor para ser procesados en lugar de enviar cada secuencia SQL. Un programa est compuesto como mnimo de un bloque. Los bloques de PL/SQL pueden ser de los siguientes tipos: Bloques annimos y Subprogramas Estructura de un Bloque Los bloques PL/SQL presentan una estructura especfica compuesta de tres partes bien diferenciadas: 1- La seccin declarativa en donde se declaran todas las constantes y variables que se van a utilizar en la ejecucin del bloque. 2- La seccin de ejecucin que incluye las instrucciones a ejecutar en el bloque PL/SQL. 3- La seccin de excepciones en donde se definen los manejadores de errores que soportar el bloque PL/SQL. Cada una de las partes anteriores se delimita por una palabra reservada, de modo que un bloque PL/SQL se puede representar como sigue:
6
OPERADORES EN PL/SQL
IDENTIFICADORES
Un identificador es un nombre que se le pone a un objeto de esquema (variables, constantes, tablas, vistas, procedimientos, excepciones, cursores, etc). Debe tener un mximo de 30 caracteres que empiece siempre por una letra, y puede contener letras, nmeros, los smbolos $, #, _, y maysculas y minsculas indiferentemente. Los identificadores no pueden ser palabras reservadas (SELECT, INSERT, DELETE, UPDATE, DROP).
EJEMPLOS alumnos_guitarra alumnos_piano
VARIABLES
Las variables son nombres para procesar los elementos de los datos. Tambin se puede definir una variable a partir de un campo mediante los atributos %TYPE, con esto damos el mismo tipo y longitud de otra variable u objeto ya definido.
SINTAXIS variable_name datatype [NOT NULL := value ];
variable_name: es el nombre de la variable. datatype: es cualquier tipo de dato valido de PL/SQL que tendr la variable. NOT NULL: es opcional, si se coloca, la variabla TIENE que ser inicializada.
EJEMPLOS --variable saludo de tipo: varchar2 saludo varchar2(10);
--variable nom_alu de tipo: el que tenga la columna nombre, -- de la tabla alumnos_guitarra nom_alu alumnos_guitarra.nombre%TYPE;
7
EJEMPLO: A continuacin se presenta el uso de dichas variables mediante un BLOQUE al ejecutar este bloque se abrir una caja de dialogo pidiendo una opcin si se digita 1, mostrar la tabla de los alumnos de guitarra si se digita 2, mostrar la tabla de alumnos de piano
if(opcion = '1') then dbms_output.put_line('GUITARRISTAS'); dbms_output.put_line('---------------------------------------------'); for contador in 1..3 loop select nombre into nom_alu from alumnos_guitarra where cod = contador; dbms_output.put_line(saludo || ' guitarrista ' || contador || ' : '|| nom_alu); end loop; else dbms_output.put_line('PIANISTAS'); dbms_output.put_line('---------------------------------------------'); for contador in 1..3 loop select nombre into nom_alu from alumnos_piano where cod = contador; dbms_output.put_line(saludo || ' pianista ' || contador || ' : '|| nom_alu); end loop; end if; end;
Para poder visualizar el resultado del bloque anterior debemos activar la Salida de DBMS asi:
8
4- PROCEDIMIENTOS ALMACENADOS
Un procedimiento es un subprograma que ejecuta una accin especfica y que no devuelve ningn valor. Un procedimiento tiene un nombre, un conjunto de parmetros (opcional) y un bloque de cdigo.
SINTAXIS:
El uso de OR REPLACE permite sobreescribir un procedimiento existente. Si se omite, y el procedimiento existe, se producir, un error. La sintaxis es muy parecida a la de un bloque annimo, salvo porque se reemplaza la seccion DECLARE por la secuencia PROCEDURE ... IS en la especificacin del procedimiento. Debemos especificar el tipo de datos de cada parmetro. Al especificar el tipo de dato del parmetro no debemos especificar la longitud del tipo. Los parmetros pueden ser de entrada (IN), de salida (OUT) o de entrada salida (IN OUT). El valor por defecto es IN, y se toma ese valor en caso de que no especifiquemos nada.
EJEMPLO: Construyamos un procedimiento que me permita insertar un nuevo alumno ya sea guitarrista o pianista. Una vez terminado el procedimiento, solo lo mandamos a invocar cuando necesitemos insertar, y de esta manera nos ahorramos estar haciendo LARGAS sentencias insert.
--procedimiento create or replace procedure insertarGuitarra(cod integer, nombre varchar2, direccion varchar2) is begin insert into alumnos_guitarra values(cod,nombre,direccion); end; --prueba begin insertarGuitarra(4,'carlos','dicc carlos'); commit; end; --verificando el insert select * from alumnos_guitarra;
9
5- FUNCIONES
Una funcin es un subprograma que devuelve un valor.
SINTAXIS
Nuevamente, El uso de OR REPLACE permite sobreescribir una funcin existente. Si se omite, y la funcin existe, se producir, un error. La sintaxis de los parmetros es la misma que en los procedimientos almacenado, exceptuando que solo pueden ser de entrada.
EJEMPLO: Construyamos una funcion que me permita saber que dia caera el ultimo dia del mes actual, si la funcin se corre en Septiembre, devolver lunes.
--funcion create or replace function ultimo_dia_mes(fecha_actual in date) return varchar2 is ultimo_dia varchar2(10); begin select to_char(last_day(fecha_actual), 'day') into ultimo_dia from dual; return ultimo_dia; end; --prueba declare ud varchar2(10); begin ud := ultimo_dia_mes(sysdate); dbms_output.put_line(ud); end;
10
6- TRIGGERS
Un trigger es un bloque PL/SQL asociado a una tabla, que se ejecuta como consecuencia de una determinada instruccin SQL (una operacin DML: INSERT, UPDATE o DELETE) sobre dicha tabla.
SINTAXIS:
Valor Descripcin INSERT, DELETE, UPDATE
Define qu tipo de orden DML provoca la activacin del disparador. BEFORE , AFTER
Define si el disparador se activa antes o despus de que se ejecute la orden.
FOR EACH ROW 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.
11
EJEMPLO: Un aeropuerto tiene aviones privados (jets) con destino a Europa. Estos jets tienen capacidad unicamente para 5 pasajeros. Se desea crear un trigger que se dispare cuando se intente ingresar al 6to pasajero.
OJO: primero debemos crear un usuario diferente a SYS y logearnos (crear un nuevo esquema) con ese usuario. NO SE PUEDEN CREAR TRIGGERS SOBRE EL USUARIO SYS.
-- creamos la tabla europa create table europa( no_reserva int not null primary key, nombre varchar2(50) not null );
-- creacion de trigger create or replace trigger max_5_reservaciones after insert on europa declare var int; begin select count(no_reserva) into var from europa; if(var > 5) then RAISE_APPLICATION_ERROR(-20010,'RESERVACIONES AGOTADAS'); end if; end;
--hacemos la prueba uno por uno... EL 6to INSERT disparar el TRIGGER!
insert into europa (no_reserva, nombre) values(1,'persona1'); insert into europa (no_reserva, nombre) values(2,'persona2'); insert into europa (no_reserva, nombre) values(3,'persona3'); insert into europa (no_reserva, nombre) values(4,'persona4'); insert into europa (no_reserva, nombre) values(5,'persona5'); insert into europa (no_reserva, nombre) values(6,'persona6');
12
7- CURSORES
PL/SQL utiliza cursores para gestionar las instrucciones SELECT. Un cursor es un conjunto de registros devuelto por una instruccin SQL. Tcnicamente los cursores son fragmentos de memoria que reservados para procesar los resultados de una consulta SELECT.
Podemos distinguir dos tipos de cursores:
Cursores implicitos. Este tipo de cursores se utiliza para operaciones SELECT INTO. Se usan cuando la consulta devuelve un nico registro. Cursores explicitos. Son los cursores que son declarados y controlados por el programador. Se utilizan cuando la consulta devuelve un conjunto de registros. Ocasionalmente tambin se utilizan en consultas que devuelven un nico registro por razones de eficiencia. Son ms rpidos. Un cursor se define como cualquier otra variable de PL/SQL y debe nombrarse de acuerdo a los mismos convenios que cualquier otra variable. Los cursores implicitos no necesitan declaracin.
El tipo de cursor mas utilizado es el CURSOR EXPLICITO.
Los cursores explicitos se emplean para realizar consultas SELECT que pueden devolver cero filas, o ms de una fila. Para trabajar con un cursor explicito necesitamos realizar las siguientes tareas:
Declarar el cursor. Abrir el cursor con la instruccin OPEN. Leer los datos del cursor con la instruccin FETCH. Cerrar el cursor y liberar los recursos con la instruccin CLOSE.
SINTAXIS:
declare cursor nombre_cursor is sentencia_select; begin open fetch close end;
13
EJEMPLO: ocupamos un cursor para cargar en memoria la taba alumnos_guitarra.
declare cursor c_guitarra is select cod, nombre, direccion from alumnos_guitarra;
codigo alumnos_guitarra.cod%TYPE; nombre alumnos_guitarra.nombre%TYPE; direcc alumnos_guitarra.direccion%TYPE; begin open c_guitarra; loop fetch c_guitarra into codigo, nombre, direcc; exit when c_guitarra%notfound; dbms_output.put_line(codigo || ' ' || nombre || ' ' || direcc); end loop; close c_guitarra; end;
EJEMPLO: uso de %ROWTYPE
declare cursor c_guitarra is select cod, nombre, direccion from alumnos_guitarra;
fila c_guitarra%ROWTYPE; begin open c_guitarra; loop fetch c_guitarra into fila; exit when c_guitarra%notfound; dbms_output.put_line(fila.cod || ' ' || fila.nombre || ' ' || fila.direccion); end loop; close c_guitarra; end;