Expresiones Join SQL2

Anuncio
15/10/2014
Expresiones Join SQL2
En SQL2 hay varias clases de operadores Join disponibles.
Las expresiones Join, al producir relaciones, pueden ser usadas
en la cláusula FROM de una expresión Seleccione-De-Cuando.
La forma más simple de expresión Join es el CROSS JOIN,
término sinónimo del producto cartesiano. Por ejemplo, si
queremos realizar el producto de dos relaciones:
Películas (titulo, año, longitud, tipo, estudio)
Estrellas (tituloPelicula, añoPelicula, nombreActor)
Podemos hacerlo asi:
Películas CROSS JOIN Estrellas;
Suponga que deseo unir las relaciones Películas y Estrellas con
la condición de unir solo aquellas tuplas que se refieran a la
misma película. Es decir, que tituloPelicula y año deben ser el
mismo.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
1
Expresiones Join SQL2
El resultado puede ser:
Películas JOIN Estrellas ON
titulo = tituloPelicula AND año = añoPelicula;
El resultado es una relacion de ocho columnas con los mismos
atributos del CROOSJOIN donde las tuplas resultantes provienen
de aquellas tuplas de Películas y Estrellas que al combinarlas
coincidan en el titulo y el año de la película.
Cuando una expresión Join aparece en una cláusula FROM, la
relación denotada por la expresión Join es tratada como una
tabla base o una vista en la cláusula FROM.
Ejemplo: Si consideramos que el ejemplo anterior tiene dos
componentes redundantes, toda la expresión del ejemplo se
pueden colocar en la cláusula FROM y usar una cláusula SELECT
para remover los atributos no deseados:
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
2
1
15/10/2014
Expresiones Join SQL2
SELECT titulo, año, longitud, tipo, estudio, nombreActor
FROM Películas JOIN Estrellas ON
Titulo = tituloPelicula AND año = añoPelícula ;
JOIN NATURAL EN SQL2
Como se recuerda el Join natural difiere del Join theta en:
1. La condición join es que todos los atributos que se
emparejan, de las dos relaciones tienen un nombre comun
que se iguala, y no hay otras condiciones.
2. Uno solo de los atributos que se igualan son proyectados.
SQL2 funciona exactamente así, la palabra clave NATURAL
JOIN debe aparecer entre las relaciones para expresar el
operador ⊲⊳ .
Bases de Datos I - Mauricio E. Fernández N
15/10/2014
3
Expresiones Join SQL2
Ejemplo: se quiere calcular el join natural de las relaciones:
EstrellasPelicula (nombre, dirección, sexo, fechaNacmto)
EjecutivosCine (nombre, dirección, codProductor, ingresoNeto)
La consulta será:
EstrellasPelicula NATURAL JOIN EjecutivosCine ;
OUTERJOIN EN SQL2
Al calcular el join R ⊲⊳ S, si una tupla t de R no se iguala con una
tupla de S, todos los datos de t desaparecen del resultado.
El outerjoin difiere del join ordinario ( o “inner” ) al adicionar al
resultado cualquier tupla de cualquier relación que no iguale
con al menos una tupla de la otra relación. Las tuplas colgantes
se rellenan con NULL en los atributos que no se igualan.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
4
2
15/10/2014
Expresiones Join SQL2
Queremos obtener aquellos individuos que son estrellas pero no
ejecutivos o los ejecutivos que no son estrellas. Entonces se
debe utilizar “natural full outer join”:
EstrellasPelicula NATURAL FULL OUTER JOIN
EjecutivosCine;
El resultado es una relación con seis atributos, con dos tipos de
tuplas: a)
los individuos que son estrellas pero no
ejecutivos (los atributos de EjecutivosCine con NULL); y b)
las que representan ejecutivos pero no estrellas (los
atributos de EstrellasPelicula con NULL).
Existen muchas variaciones de la reunión externa (outerjoin)
disponibles en SQL2.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
5
Expresiones Join SQL2
a) El left outerjoin, donde solo las tuplas colgadas de la relación
izquierda son rellenadas con nulos e incluidas en el resultado:
EstrellasPeliculas NATURAL LEFT OUTER JOIN EjecutivosCine;
b) El right outerjoin, donde se rellena e incluye solo las tuplas
colgadas de la segunda relación (derecha):
EstrellasPeliculas NATURAL RIGHT OUTER JOIN EjecutivosCine;
Otra variación en los outerjoin es cuando se especifica la condición
que las tuplas que igualen deben cumplir. En vez de la palabra
NATURAL, al join debe seguirle el ON y una condición que al
igualar las tuplas, estas deban satisfacer:
c) El FULLOUTERJOIN, donde después de igualar tuplas, se
rellenan las tuplas colgantes de cualquiera de las relaciones con
valor NULL, incluyendo en el resultado las tuplas rellenadas.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
6
3
15/10/2014
Expresiones Join SQL2
Queremos unir la relaciones Película y Estrellas, usando la
condición que el titulo y el año coincidan, debemos modificar la
consulta así:
Películas FULL OUTER JOIN Estrellas ON
titulo = tituloPelicula AND año = añoPelicula;
La palabra clave FULL puede ser reemplazada por LEFT o
RIGHT en el anterior tipo de outerjoin:
d) Películas LEFT OUTER JOIN Estrellas ON
titulo = tituloPelicula AND año = añoPelicula;
e) Películas RIGHT OUTER JOIN Estrellas ON
Titulo = tituloPelicula AND Año = añoPelicula;
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
7
Restricciones en SQL2
La integridad de los datos en una base de datos es un
aspecto muy importante a tener en cuenta en la
implementación de un diseño. Existen al menos dos formas
de mantenerla:
a. Incorporando las restricciones en los programas de aplicación
(se multiplica el código específico que implementa restricciones
en las aplicaciones).
b. Incorporando declaraciones al SMBD, formando parte del
esquema de la base de datos.
SQL2 provee una variedad de técnicas para implementar
Restricciones de integridad como parte del esquema de la
base de datos.
Veamos los diferentes tipos de restricción previstos en SQL:
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
8
4
15/10/2014
Restricciones en SQL2
Declaración de Llaves
Es el tipo de restricción más importante en una base de datos.
Se prohibe que dos tuplas de una relación coincidan en el
atributo declarado como llave.
La llave se declara dentro del comando SQL CREATE TABLE.
Hay dos formas similares de declarar una llave: usando la
cláusula PRIMARY KEY o la cláusula UNIQUE.
Hay dos formas de declarar una llave primaria:
1) Se puede declarar un atributo como llave primaria cuando se
define el esquema relacional.
CREATE TABLE Hospital (
numeroH smallint PRIMARY KEY
...
);
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
9
Restricciones en SQL2
2) Se puede agregar al esquema ya declarado, una nueva declaración
que defina la llave de la relación:
CREATE TABLE Personal (
hospitalNro smallint, codigo smallint, nombre varchar (40), ...
PRIMARY KEY (hospitalNro, codigo)
... );
Para utilizar la cláusula UNIQUE basta con reemplazar la palabra
PRIMARY KEY por UNIQUE. Tiene la misma importancia de
una declaración de llave primaria. Sin embargo, en una tabla
puede haber varias declaraciones UNIQUE pero solo una llave
primaria.
Muchas versiones SQL ofrecen la creación de índices que usan la
cláusula UNIQUE para declarar el (o los) atributos (s) que serán
llave al mismo tiempo que crea un índice sobre dicho atributo:
CREATE UNIQUE INDEX indiceAño ON Películas (año);
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
10
5
15/10/2014
Restricciones en SQL2
Integridad Referencial y Llaves Foráneas
Un segundo tipo de restricción en el esquema de la base de
datos es que los valores de algunos atributos deben ser lógicos.
Estamos hablando de la “integridad referencial”, concepto que
esta estrechamente relacionado con el de Llave Foránea, que
establece que el valor de un atributo puede ser nulo o su valor
exista como valor en la llave primaria de otra tabla.
La llave foráneas permite implementar relaciones uno a muchos.
CREATE TABLE Medico (
hospitalNro smallint, codigo smallint, nombre varchar (40),...
CONSTRAINT fkHosp FOREIGN KEY (hospitalNro)
REFERENCES Hospital (numeroH)
... );
donde fkHosp es el nombre de la restricción.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
11
Restricciones en SQL2
Declaración de restricciones de la llave
foránea
En SQL podemos declarar uno o varios atributos como llave
foránea, referenciando el (los) atributo(s) de otra relacion (que
puede ser la misma relación).
Esta declaración trae las siguientes implicaciones:
1. Los atributos referenciados en la segunda relación deben
ser declarados como llave primaria de su relacion.
2. Un valor del atributo de la llave foránea en la primera tabla,
también debe aparecer en el correspondiente atributo de la
segunda relación: restricción de integridad referencial .
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
12
6
15/10/2014
Restricciones en SQL2
Declaración de restricciones de la llave
foránea
Hay dos formas de declarar llaves foráneas:
a. Si la llave foránea es una tributo simple, podemos usar:
REFERENCES <tabla> (<atributos>)
b. Anexar a la lista de atributos (CREATE TABLE) una o más
declaraciones enunciando que un conjunto de atributos son
una llave foránea. Indicamos despues la tabla y sus atributos
(que son llave primaria). La forma es:
FOREING KEY <atributos> REFERENCES <tabla> (<atributos>)
Ejemplo:
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
13
Restricciones en SQL2
CREATE TABLE Estudio (
nombreEst CHAR ( 30) PRIMARY KEY,
direcciónEst VARCHAR (225),
codProductor INT REFERENCES EjecutivosCine (codProductor)
);
Una forma alternativa será:
CREATE TABLE Estudio (
nombreEst CHAR (30) PRIMARY KEY,
direcciónEst VARCHAR (225),
codProductor INT,
FOREIGN KEY codProductor REFERENCES
EjecutivosCine (codProductor)
);
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
14
7
15/10/2014
Restricciones en SQL2
Mantenimiento de la Integridad Referencial
En SQL se dispone de varias formas de implementar la conservación
de las restricciones de integridad referencial.
Rechazar las modificaciones que violan la integridad referencial lo
cual es la política por defecto en SQL. Las siguientes acciones serán
rechazadas por el sistema (error en tiempo de ejecución):
 Intento de insertar una tupla cuyo valor en la llave foránea no es
nulo o no existe como valor de la llave primaria.
 Intento de actualizar una tupla cuya valor de llave foránea no existe
como valor en la llave primaria. La tupla original permanece igual.
 Intento de eliminar una tupla en la tabla de la llave primaria cuando
su componente aparece como valor en la llave foránea de la
segunda relación en una o más tuplas. Se rechaza eliminación y se
conservan las demás tuplas.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
15
Restricciones en SQL2
Política en cascada
Cuando se borran o actualizan tuplas en la tabla que posee
la llave primaria, se borran o se actualizan las tuplas
relacionadas en la tabla que posee la llave foránea.
Política de asignar valor nulo
En la cual ante retiros o modificaciones de tuplas en la tabla
que posee la llave primaria, se modifican los valores de la
tabla que maneja la llave foránea, cambiándolos a NULL.
Política de asignar valor por defecto
En la cual ante retiros o modificaciones de tuplas en la tabla
que posee la llave primaria, se modifican los valores de la
tabla que maneja la llave foránea cambiándolos al valor
DEFAULT.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
16
8
15/10/2014
Restricciones en SQL2
Veamos la sintaxis:
FOREIGN KEY ( a1, , ... , aj)
REFERENCES R (K1, ... , Kj)
[ON DELETE {SET DEFAULT | SET NULL | CASCADE | NO ACTION}]
[ON UPDATE {SET DEFAULT | SET NULL | CASCADE | NO ACTION}]
En el ejemplo:
CREATE TABLE Estudio (
nombreEst CHAR ( 30) PRIMARY KEY,
direcciónEst VARCHAR (225),
codProductor INT REFERENCES EjecutivosCine (codProductor)
ON DELETE SET NULL
ON UPDATE CASCADE );
Las acciones alternativas son SET DEFAULT, SET NULL,
CASCADE y NO ACTION. La acción por defecto es (no hacer
nada) NO ACTION.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
17
Restricciones en SQL2
Restricciones de los Valores de Atributos
Un tercer grupo de restricciones lo constituyen las
restricciones que limitan los valores que pueden aparecer
en los componentes de algunos atributos. Se pueden
expresar como una restricción al atributo dentro de la
definición del esquema o, como una restricción de dominio
del atributo en cuestión.
Algunas de las formas de implementación de este tipo de
restricciones se pueden expresar mediante:
Restricciones NO NULAS
Se asocia a la opción NOT NULL; especifica que no se
puede ingresar un valor nulo para el atributo. Ejemplo:
codProductor INT NOT NULL,
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
18
9
15/10/2014
Restricciones en SQL2
Restricciones CHECK Basadas en Atributos
Se pueden incorporar restricciones más complejas a la
declaración de un atributo mediante la palabra clave CHECK,
seguida de una condición entre paréntesis.
En la práctica es una limitación simple sobre valores, aunque
en teoría la condición puede ser cualquier cosa que le siga al
where en una consulta SQL.
Una restricción CHECK basada en atributo se verifica siempre
que una tupla cualquiera reciba en ella un nuevo valor
(actualización, o inserción).
La restricción CHECK basada en atributo NO se verifica
necesariamente, si una modificación de la BD no cambia el
valor del atributo al cual se asocia la restricción; esta
limitación puede hacer que se viole la restricción.
Bases de Datos I - Mauricio E. Fernández N
15/10/2014
19
Restricciones en SQL2
Sintaxis:
CHECK (Condición de búsqueda)
Ejemplos:Suponga que se requiere que el codProductor sea de al
menos 6 dígitos en la relación Estudio:
codProductor INT REFERENCES EjecutivosCine (codProductor)
CHECK (codProductor >=100000);
Ejemplo: verificar el sexo en las relación EjecutivosCine que tenga
un carácter y que pueda tomar los siguientes valores `F´ o `M´:
sexo CHAR (1) CHECK (sexo IN ( `F´,`M´) )
CREATE TABLE Hospital (
...
camas smallint CHECK (camas < 1000),
... );
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
20
10
15/10/2014
Restricciones en SQL2
CREATE TABLE Hospital (
...
camas smallint CHECK
(camas <= (SELECT count (*)/10 FROM Personal) )
... );
CREATE TABLE Paciente (
...
cuota decimal (8,2),
nroFarmacia smallint,
consuSinCargo smallint
...
CHECK ((cuota between 50 and 500) and
(nroFarmacia between 10 and 100) and
(consuSinCargo between 1 and 20) )
... );
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
21
Restricciones en SQL2
CREATE TABLE Medico (
...
especial char (5) CHECK (
(especial IN (‘clini’, ’pedia’, ’traum’, ’obste’, ’cardi’, ‘otras’ ) )
... );
Restricciones de Dominios
También se puede restringir los valores de un atributo al
declarar un dominio con una restricción similar y declarando
que el dominio es el tipo de dato para el atributo. En SQL2 se
usa la palabra reservada VALUE para referirse a un valor del
dominio.
Ejemplo: declarar un domino, dominioSexo con los caracteres
`F´ y `M´ como unión de valores permitidos:
CREATE DOMAIN dominioSexo CHAR (1)
CHECK (VALUE IN (`F´, M´) );
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
22
11
15/10/2014
Restricciones en SQL2
Por lo tanto, el definir el atributo sexo en la relación
EjecutivosCine puedo hacerlo así:
sexo dominioSexo,
Ejemplo: Crear un dominio para el atributo codProductor
número de al menos 6 dígitos en la relación Estudio :
CREATE DOMAIN dominioProductor INT
CHECK (VALUE >= 100000);
Y luego al reescribir la declaración de codProductor:
codProductor dominioProductor
REFERENCES EjecutivosCine (codProductor)
Obtenemos la restricción deseada. Ejemplos:
CREATE DOMAIN clave AS integer CHECK (Value > 30)
CHECK (Value is NOT NULL);
CREATE DOMAIN color AS char (10) DEFAULT ´Sin color´
CHECK (Value IN (´Sin color´, ´Azul´, Ámarillo´, ´Rojo´, ´Negro´));
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
23
Restricciones en SQL2
Restricciones Globales
Corresponden al tipo de declaración de restricciones más
complejas; se refieren a las relaciones entre varios atributos o
incluso a relaciones diversas. Son de dos tipos:
Restricciones CHECK basadas en tuplas, que limitan cualquier
aspecto de las tuplas de una sola relación.
Aserciones, son aquellas que pueden incluir relaciones enteras o
algunas variables de tuplas que abarcan la misma relación.
Restricciones CHECK Basadas en Tuplas
Para declarar una restricción sobre tuplas de una tabla, al definirla
(CREATE TABLE) podemos agregar a la lista de atributos y a las
declaraciones de llaves o llaves foráneas la palabra clave CHECK
seguida de una condición entre paréntesis.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
24
12
15/10/2014
Restricciones en SQL2
La restricción CHECK basada en tuplas se evalúa cada vez que
se realice una inserción o una actualización sobre la tabla R. Si
la condición menciona alguna relación en una subconsulta, y si
una modificación de esta relación vuelve falsa la condición en
alguna tupla de R, la verificación no mostrará ese cambio.
Ejemplo:
CREATE TABLE EstrellasPelicula (
nombre CHAR (30) UNIQUE,
dirección VARCHAR (25) ,
sexo CHAR (1),
fechaNacmto DATE,
CHECK (sexo = `F´ OR nombre NOT LIKE `Sra.%´ );
Se recomienda utilizar aserciones para definir restricciones más
complejas.
Bases de Datos I - Mauricio E. Fernández N
15/10/2014
25
Restricciones en SQL2
Aserciones
Una aserción es una restricción a la base de datos que restringe
el contenido de la base de datos como un todo. Al igual que en las
rectricciones check, una restricción se especifica como una
condición de búsqueda. Pero se diferencia en que la condición de
la aserción puede restringir el contenido de varias tablas y las
relaciones entre ellas.
Por esta razón la aserción se especifica como parte de la
definición del esquema de la base de datos, por medio de la
instrucción SQL2 CREATE ASSERTION.
Su forma general es:
CREATE ASSERTION nombreRestricción
CHECK (condición de búsqueda);
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
26
13
15/10/2014
Restricciones en SQL2
CREATE TABLE Orden (
nOrden INTEGER NOT NULL, fechaOrden DATE NOT NULL,
codCliente INTEGER NOT NULL, Producto CHAR (5),
Cantidad INTEGER NOT NULL, valorOrden NUMBER (10,2));
CREATE TABLE Cliente (
nroCliente INTEGER NOT NULL,
nomEmpresa VARCHAR (25) NOT NULL,
direccionCli VARCHAR (25) NOT NULL,
limiteCredito NUMBER (10,2));
Suponga que queremos restringir el contenido de las base de datos tal
que el total de las ordenes para cualquier cliente no puede exceder el
límite de su crédito:
CREATE ASSERTION limiteDelCredito CHECK
( (Cliente. nroCliente = Orden.codCliente) AND
(sum (valorOrden ) <= límiteCredito ));
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
27
Restricciones en SQL
Ejemplo:
CREATE ASSERTION presidentesRicos CHECK
(NOT EXISTS
(SELECT *
FROM Estudio, EjecutivosCine
WHERE Estudio.codProductor = EjecutivosCine. codProductor
AND ingresoNeto < 10000000) );
De esta forma la restricción se cumple (es verdadera) cuando la
consulta sea vacía.
Ejemplo:
CREATE ASSERTION totalSalarios CHECK
(((SELECT sum (sueldo) FROM Personal) +
(SELECT sum (sueldo) FROM Medico)) < 100000000);
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
28
14
15/10/2014
Disparadores en SQL
Los disparadores, llamados reglas Evento-Condición-Acción (o
siglas ECA), difieren de las restricciones previamente discutidas
en tres formas:
1. Los triggers solo son probados cuando ocurren ciertos
eventos, especificado por el programador de la BD. Eventos
permitidos: son inserciones, borrados, actualizaciones y el fin de
una transacción.
2. En lugar de prevenir inmediatamente el evento que activa la
acción, un trigger prueba una condición. Si esta no se satisface,
entonces no ocurre nada en el trigger en respuesta al evento.
3. Si la condición del trigger se cumple, la acción definida con el
triggers es realizada por el DBMS. La acción puede impedir que
ocurra el evento, o podría deshacer el evento (como borrar una
tupla insertada). La acción podrá ser cualquier secuencia de
operaciones sobre la base de datos.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
29
Disparadores en SQL2
La base de datos es incapaz de programarse para especificar:
• Cuando verificar una restricción,
• Que hacer exactamente cuando se verifica la restricción.
Un trigger o disparador tiene 3 partes:
• Un evento (ejemplo: actualizar un atributo)
• Una condición (ejemplo: una condición a evaluar)
• Una acción (borrado, actualización, inserción)
NOTA: los triggers pueden causar efectos en cascada.
¡Los vendedores de bases de datos no esperaron estándares con
disparadores!
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
30
15
15/10/2014
Disparadores en SQL
Características de los Triggers
1. La acción puede ser ejecutada antes, después o durante el
evento definido en el trigger.
2. La acción puede referirse a valores viejos o nuevos que se
insertaron, borraron o actualizaron en el evento que dispara la
acción del trigger.
3. Los eventos de actualización pueden especificar un atributo
particular o un conjunto de atributos.
4. Una condición puede ser especificada con una cláusula WHEN,
y la acción solo se ejecutará si la regla es activada y se cumple
la condición cuando el evento definido en el trigger ocurre.
5. El programador tiene la opción de especificar que la acción sea
realizada:
a) Una vez en cada tupla modificada
b) Una vez en todas las tuplas que cambian en la operación
Bases de Datos I - Mauricio E. Fernández N
15/10/2014
31
Disparadores en SQL
Para crear un trigger se usa el comando CREATE TRIGGER.
Veamos su sintaxis:
CREATE [OR REPLACE] TRIGGER <nombreTrigger>
BEFORE | AFTER
--Tiempo del evento
{ {INSERT | UPDATE} [OF columna(s) ] |DELETE }
ON <nombreTabla>
-- Eventos disparadores
FOR EACH ROW
--Tipo de Trigger
[WHEN (<condición>) ]
-- Restricción al Trigger
<Bloque PL/SQL>
--Cuerpo del trigger
END;
-- Fin del disparador
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
32
16
15/10/2014
Disparadores en SQL
Ejemplo: Trigger a nivel de tupla
CREATE TRIGGER No-Baja-Precios
AFTER UPDATE OF precio ON Producto
REFERENCING
OLD AS OldTuple
NEW AS NewTuple
WHEN (OldTuple.precio > NewTuple.precio)
UPDATE Producto
SET precio = OldTuple.precio
WHERE nombre = NewTuple.nombre
FOR EACH ROW
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
33
Disparadores en SQL
Trigger a nivel de Instrucción
CREATE TRIGGER mantiene_precio-promedio
INSTEAD OF UPDATE OF precio ON Producto
REFERENCING
OLD_TABLE AS TablaOld
NEW_TABLE AS TablaNew
WHEN (1000 <
(SELECT AVG (precio)
FROM ((Producto EXCEPT TablaOld) UNION TablaNew))
DELETE FROM Producto
WHERE (nombre, precio, empresa) IN TablaNew;
INSERT INTO Producto
(SELECT * FROM TablaOld)
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
34
17
15/10/2014
Disparadores en SQL
Sea la relación
EjecutivosCine (nombre, dirección, codProductor, ingresoNeto)
Vamos a aplicar un disparador que opere sobre actualizaciones al
atributo ingresoNeto. El efecto de esta regla es restaurar el
valor inicial por cualquier intento de reducir el ingreso neto de
un ejecutivo:
1) CREATE OR REPLACE TRIGGER ingresoNetoTrigger
2) AFTER UPDATE OF ingresoNeto on EjecutivosCine
3) REFERENCING
4) OLD AS oldTuple
5) NEW AS newTuple
6) WHEN (oldTuple.ingresoNeto > newTuple.ingresoNeto)
7) UPDATE EjecutivosCine
SET ingresoNeto = Oldtuple.ingresoNeto
WHERE codProductor = Newtuple.codProductor
8) FOR EACH ROW;
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
35
Disparadores en SQL
A continuación mostraremos otras alternativas:
 A la cláusula AFTER: { BEFORE | INSTEAD OF }
 En reemplazo del UPDATE: { INSERT | DELETE }.
 La acción puede ser cualquier
número de intrucciones
separadas por punto y coma.
 Cuando el evento del trigger es una actualización, entonces
habrá una tupla vieja y otra nueva, los cuales son las tuplas
antes y después de la actualización: OLD AS y NEW AS.
 Si se omite (FOR EACH ROW) entonces el trigger a nivel de
tupla se convierte en un trigger a nivel de instrucción, el cual se
ejecuta una vez por cada instrucción que genere uno o más
eventos definidos para el trigger. En un trigger a nivel de
instrucción nos tendremos que referir al conjunto de tuplas
viejas y nuevas, (declaraciones tales como OLD_TABLE AS
ViejosValores y NEW_TABLE AS NuevosValores.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
36
18
15/10/2014
Disparadores en SQL
Ejemplo. Se desea prevenir que el promedio del ingresoNeto de los
ejecutivos del cine caiga por debajo de los $5.000.000. Esta
restricción podrá ser violada por una inserción, retiro o actualización
del atributo ingresoNeto en la relación EjecutivosCine. Se necesita
un trigger para cada uno de estos eventos. En el ejemplo siguiente se
muestra el trigger para el evento de una actualización:
1) CREATE OR REPLACE TRIGGER promedioIngresoNetoTrigger
2) AFTER UPDATE OF ingresoNeto ON EjecutivosCine
3) REFERENCING
4)
OLD TABLE AS viejosDa
5)
NEW TABLE AS nuevosDa
6) WHEN (5 000 000 >=
7)
(SELECT AVG (ingresoNeto)
FROM ((EjecutivosCine EXCEPT viejosDa) UNION nuevosDa)))
8)
DELETE FROM EjecutivosCine WHERE
(nombre, dirección, codProductor, ingresoNeto) IN nuevosDa;
9)
INSERT INTO EjecutivosCine (SELECT * FROM viejosDa);
10) END.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
37
Disparadores en SQL
En el ejemplo siguiente se muestra el trigger a nivel de
instrucción para el evento de un borrado:
1) CREATE OR REPLACE TRIGGER TriggerPromIngreNetoRet
2) AFTER DELETE OF ingresoNeto ON EjecutivosCine
3) REFERENCING
OLD TABLE AS tablaVieja
4) WHEN ((SELECT AVG (ingresoNeto)
FROM (EjecutivosCine)) <= 5 000000 )
5) INSERT INTO EjecutivosCine
(SELECT * FROM tablaVieja);
6) END.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
38
19
15/10/2014
Disparadores en SQL
Se recomienda seguir las siguientes reglas para la definición de
triggers de mantenimiento de integridad:
Identifique operaciones y tablas críticas para la restricción de
integridad
Por cada una de tales tablas verifique
Si la restricción puede ser verificada a nivel de fila entonces
Si la fila verificada es modificada en el trigger entonces
Use un trigger de fila con before
De lo Contrario Use un trigger de fila con After
De lo Contrario Use un trigger de instrucción con After
Los triggers no son exclusivamente utilizados para mantener la
integridad. También se puede usar para:
 Propósitos de monitoreo de acceso de usuarios y modificaciones a
ciertas tablas
 Acciones de seguridad sobre tablas
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
39
Ejercicio en SQL
Sea la siguiente base de datos:
Empleado : nDI(numérico), nombre (10 caracteres), salario (numérico),
numDep (10 caracteres), sexo (1 carácter “M” o “F”)
Departamento: numDep (10 caract.), nombre (10 caract.), presupto (numérico)
Utilizar SQL para crear las tablas de la base de datos, incluyendo las restricciones
de integridad que se solicitan.
Crear todas las tablas, especificando en cada caso las claves primarias y foráneas.
Especificar en la tabla Empleado que: a) el salario este en el rango 1,500.000 a
5.000.000, b) el nombre y salario no deben ser nulos.
Especificar el sexo del empleado creando un dominio.
En la tabla Empleado, especificar que si un departamento es retirado en la tabla
Departamento, se eliminan los registros en Empleado. Si el departamento
cambia de numDep, sus registros en Empleado serán actualizados.
El total del presupto de un Departamento debe ser mayor o igual al 50% de la
suma de los salarios de los empleados que laboran en dicho departamento.
Diseñar un disparador que al insertar un nuevo empleado, automáticamente
actualice el presupuesto total del Departamento al que el empleado pertenece,
añadiéndole el salario devengado por el nuevo empleado.
Diseñar un disparador que al modificar el salario de un empleado, actualice
automáticamente el presupuesto total del Departamento.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
40
20
15/10/2014
Disparadores en SQL
Considere las siguientes relaciones:
Mascota (nroChip, nombre, raza, peligrosidad, fechaNacimto, dIP)
Propietario (dIP, fechaAlta)
Persona (dIP, fechaNacimto, lugarNacimto, nombre, direccion)
Indique cómo definiría las siguientes restricciones de integridad en SQL:
1.
2.
3.
4.
5.
6.
No puede haber dos mascotas con el mismo número de chip
Todo propietario es una persona
El campo peligrosidad sólo puede tomar los valores 0 (falso) 1 ( verdadero)
Un propietario pueden serlo de varias mascotas
Las mascotas no tienen porque vivir en la misma dirección que sus propietarios
Se quiere almacenar más información sobre las razas de los animales de forma que ,
para cada raza, se almacena un identificador (para distinguir una raza de todas las
demás), el nombre de la raza, el tipo (perro, gato, reptil, equino), el color , el tipo de
pelo (largo, corto), y su peligrosidad (0 para las no peligrosas y 1 para las peligrosas)
7. No todas las personas deben ser propietarias de mascotas
8. Sólo pueden ser propietarios de mascotas las personas mayores de 18 años
9. Cuando una mascota muere (se eliminan sus datos de la tabla mascota), tiene que
dejar de estar asociada a su propietario
10. Toda mascota tiene que tener un nombre
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
41
SQL Embebido
El lenguaje huésped manipula variables, valores, punteros .
El SQL manipula relaciones.
No hay construcciones en el lenguaje huésped para la manipular relaciones.
¿Por qué no utilizar solamente un lenguaje ?
 Olvidar el SQL: ¡definitivamente no una buena idea!
 El SQL no puede hacer todo que el lenguaje huésped puede hacer.
Hay dos razones por las que podríamos utilizar SQL desde un lenguaje
huésped:
 Hay consultas que no se pueden formular con SQL puro (por ejemplo,
las consultas recursivas) . Para realizar esas consultas necesitamos un
lenguaje de huésped de mayor poder expresivo que el SQL .
 Si queremos acceder a una base de datos desde una aplicación que
está escrita en el lenguaje del huésped (p.e. un sistema de reserva de
tiquetes con una interface gráfica escrita en Java y donde la información
sobre los tiquetes está almacenada en una base de datos que puede
accederse utilizando SQL embebido).
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
42
21
15/10/2014
SQL Embebido
 Un programa que utiliza SQL embebido en un lenguaje de host
consiste en instrucciones del lenguaje del host e instrucciones de SQL
embebido. Cada instrucción de SQL Embebido empieza con las
palabras claves EXEC SQL.
 Estas instrucciones se transforman en instrucciones del lenguaje del
host mediante un precompilador (que habitualmente inserta llamadas a
rutinas de librerías que ejecutan los variados comandos de SQL).
 Cuando ejecutamos una instrucción SELECT vemos que el resultado
de las consultas es un conjunto de tuplas . La mayoría de los lenguajes
huésped no están diseñados para operar con conjuntos, de modo que
necesitamos un mecanismo para acceder a cada tupla única del
conjunto de tuplas devueltas por una instrucción SELECT.
 Este mecanismo puede ser proporcionado declarando un cursor . Tras
ello, podemos utilizar el comando FETCH para recuperar una tupla y
apuntar el cursor hacia la siguiente tupla.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
43
SQL Embebido
Lenguaje Huesped + SQL Embebido
Preprocesador
Preprocessor
Lenguaje Huesped + llamado a funciones
Compilador del Lenguaje Huesped
Host language compiler
Programa en Lenguaje Huesped
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
44
22
15/10/2014
SQL Embebido
El SQL directo es raramente utilizado! SQL necesita estar
embebido en un lenguaje de propósito general para permitir:
 IGU
 Flujo de control
 Generar SQL dinámico basado en las entradas del usuario.
Los comandos SQL pueden ser llamados desde un lenguaje
huésped (como C/C++ o Java) o desde lenguajes de etiquetado
(como PHP o Ruby).
Una respuesta a una consulta es una bolsa de registros – con un
numero arbitrario de muchos registros! En la mayoría de lenguajes
no hay una estructura de datos como esta. Este problema se
denomina impedance mismatch
El SQL estándar soporta los cursores para el manejo de esto.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
45
SQL Embebido
Interface: SQL / Lenguaje Anfitrion
Los valores son pasados con variables compartidas.
Los dos puntos (:) preceden variables compartidas cuando
ocurren dentro de una declaración SQL.
EXEC SQL precede cada declaración de SQL en el
lenguaje anfitrión.
La variable SQLSTATE proporciona mensajes de error y el
estado de los informes (ejemplo, 00000 dice que la
operación fue terminada sin problema).
EXEC SQL BEGIN DECLARE SECTION;
char productName[30];
EXEC SQL END DECLARE SECTION;
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
46
23
15/10/2014
SQL Embebido
Uso de Variables Compartidas
Void insercionSimple() {
EXEC SQL BEGIN DECLARE SECTION;
char nombProducto[20], fabrica[30];
char SQLSTATE[6];
EXEC SQL END DECLARE SECTION;
/*
Aquí se obtienen los valores para nombProducto y
fabrica de alguna manera
*/
EXEC SQL INSERT INTO Producto (nombre, empresa)
VALUES (:nombProducto, :fabrica);
}
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
47
SQL Embebido
Instrucción SELECT para escoger una fila
Void traerPrecio() {
EXEC SQL BEGIN DECLARE SECTION;
char nombreProducto[20], fabrica[30];
integer precioT;
char SQLSTATE[6];
EXEC SQL END DECLARE SECTION;
/* leer el valor de nombreProducto */
EXEC SQL SELECT precio INTO :precioT
FROM Producto
WHERE Producto.nombre = :nombreProducto;
/* imprimir valor de precio */
}
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
48
24
15/10/2014
SQL Embebido
Cursores
 El término cursor se refiere a una estructura de control utilizada
para el recorrido (y potencial procesamiento) de los registros del
resultado de una consulta.
 Un cursor se usa para el procesamiento individual de tuplas
devueltas por el SMBD para una consulta. Se necesita porque
muchos lenguajes de programación sufren de impedance
mismatch. Por norma general los lenguajes de programación
son procedurales y no disponen de ningún mecanismo para
manipular conjuntos de datos en una sola instrucción. Por ello,
las filas deben ser procesadas de forma secuencial por la
aplicación. Un cursor puede verse como un iterador sobre la
colección de filas que hay en el set de resultados.
 Existen sentencias SQL que no requieren del uso de cursores.
Ello incluye la sentencia Insert, así como la mayoría de formas
del Update o el Delete. Incluso una sentencia Select puede no
requerir un cursor si se utiliza en la variante de SELECT...INTO,
ya que esta variante sólo devuelve una fila.
Bases de Datos I - Mauricio E. Fernández N
15/10/2014
49
SQL Embebido
Cursores
 Un cursor es creado utilizando la sentencia DECLARE CURSOR.
Es obligatorio asignarle un nombre.
DECLARE cursor_name CURSOR FOR SELECT ... FROM ...
 Antes de ser utilizado, el cursor debe ser abierto con una sentencia
OPEN. Como resultado de esta sentencia, el cursor se posiciona
antes de la primera fila del set de resultados.
OPEN cursor_name
 La posición de un cursor de recorrido puede especificarse de forma
relativa a la posición actual del cursor o de forma absoluta a partir
del principio del set de resultados.
FETCH [ NEXT | PRIOR | FIRST | LAST ] FROM cursor_name
FETCH ABSOLUTE n FROM cursor_name
FETCH RELATIVE n FROM cursor_name
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
50
25
15/10/2014
SQL Embebido
Cursores
EXEC SQL DECLARE nombreCursor CURSOR FOR
SELECT …. FROM …. WHERE …. ;
EXEC SQL OPEN nombreCursor;
while (true) {
EXEC SQL FETCH FROM nombreCursor INTO :variables;
if (NO_MORE_TUPLES) break;
/* Se trabaja con los valores */
}
EXEC SQL CLOSE nombreCursor;
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
51
SQL Embebido
Cursores
Obtenga los nombres de los estudiantes que practican natación, en
orden alfabético:
EXEC SQL DECLARE DeporNataciónCur CURSOR FOR
SELECT nombre
FROM Estudiante JOIN EstudXDeporte
ON Estudiante.codigoE = EstudXDeporte.codEstud AND
EstudXDeporte.deporte = ‘Natación’
ORDER BY nombre;
(EXEC SQL OPEN DeporNataciónCur;
while true) {
EXEC SQL FETCH FROM DeporNataciónCur INTO :nombreCur;
if (NO_MORE_TUPLES) break;
/* Los : en :nombreCur se refiere a una variable declarada en el programa */
}
EXEC SQL CLOSE DeporNataciónCur;
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
52
26
15/10/2014
SQL Embebido
Más sobre Cursores
 Los cursores pueden modificar una relación así como se
lee.
 Podemos determinar el orden en el cual el cursor traerá
las tuplas por la palabra clave ORDER BY en la consulta
SQL.
 Los cursores pueden proteger contra cambios a
relaciones subyacentes.
 El cursor puede tener movimiento en algún sentido:
puede ir adelante, hacia atrás +n, - n, ABS (n), ABS (- n).
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
53
SQL Dinámico
Hemos considerado hasta ahora solamente embeber
estático en lenguajes de programación.
SQL
El SQL estático embebido está muy bien para aplicaciones fijas
cuando deseamos ejecutar una consulta SQL específica desde
un lenguaje de programación, p.e., un programa que es utilizado
por las agencias de viajes para reservar un asiento de una línea
aérea.
¿Qué si la consulta SQL que deseamos embeber no se
conoce por adelantado en tiempo de compilación?
Por ejemplo, el código que implementa una base de datos toma
una consulta del usuario en tiempo de ejecución y la suministra a
la base de datos.
El SQL dinámico permite que la consulta sea especificada en
tiempo de ejecución.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
54
27
15/10/2014
SQL Dinámico
Dos declaraciones especiales del SQL embebido:
 PREPARE convierte una cadena de caracteres en una
consulta SQL.
 EXECUTE ejecuta esa consulta
Ejemplo de USAGE
EXEC SQL BEGIN DECLARE SECTION;
char datoConsulta [MAX_QUERY_LENGTH];
EXEC SQL END DECLARE SECTION;
/* Se lee el texto del usuario en el arreglo datoConsulta*/
EXEC SQL PREPARE q FROM :datoConsulta;
EXEC SQL EXECUTE q;
/* programa que lee una consulta SQL y la ejecuta */
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
55
Arquitectura POSTGRES
El siguiente gráfico muestra de forma esquemática las entidades
involucradas en el funcionamiento normal del gestor de bases de datos:
 PostgreSQL está basado en una arquitectura
cliente-servidor.
 El programa servidor se llama postgres y entre
los muchos programas cliente tenemos, por
ejemplo, pgaccess (un cliente gráfico) y psql
(un cliente en modo texto).
 Un proceso servidor postgres puede atender
exclusivamente a un solo cliente; es decir, hacen
falta tantos procesos servidor postgres como
clientes haya. El proceso postmaster es el
encargado de ejecutar un nuevo servidor para
cada cliente que solicite una conexión.
 Se llama sitio al equipo anfitrión (host) que
almacena un conjunto de bases de datos
PostgreSQL. En un sitio se ejecuta solamente
un proceso postmaster y múltiples procesos
postgres.
 Los clientes pueden ejecutarse en el mismo sitio
o en equipos remotos conectados por TCP/IP.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
56
28
15/10/2014
Arquitectura POSTGRES
El administrador Postgres
Terminada la instalación, en el S.O. se creará el
usuario postgres, y en PostgreSQL se habrá
creado un usuario con el mismo nombre.
Él es el único usuario existente en la base de
datos y será el único que podrá crear nuevas
bases de datos y nuevos usuarios.
Normalmente, al usuario postgres del S.O. no
se le permitirá el acceso desde un shell ni tendrá
contraseña asignada, por lo que debemos
convertirnos en el usuario root, para después
convertirnos en el usuario postgres y realizar
tareas en su nombre.
Se deben decrear los usuarios necesarios para
operar la instalación de PostgreSQL, e ingresar,
lo menos posible, con el usuario postgres.
Es posible restringir el acceso a usuarios o a
direcciones IP modificando las opciones del
archivo de configuración (pg_hba.conf).
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
57
Arquitectura POSTGRES
Para entender lo básico de la arquitectura del s/ma Postgres, debemos entender
como interactúan las partes de Postgres. En la Jerga de bases de datos,
Postgres usa un modelo cliente/servidor conocido como "proceso por usuario".
Una sesión Postgres consiste en los siguientes procesos cooperativos
(programas):
 un proceso supervisor (postmaster),
 la aplicación sobre la que trabaja el usuario (frontend) (p.e. el programa psql),
 y uno o más servidores de bases de datos en segundo plano (el mismo
proceso postgres).
Un único postmaster controla una colección de bases de datos dadas en un host.
Por ello una colección de bases de datos se suele llamar instalación o un sitio.
Las aplicaciones de frontend que quieren acceder a una determinada base de
datos dentro de una instalación hacen llamadas a la librería.
La librería envía peticiones de usuario a través de la red al postmaster (establece
una conexión), el cual en respuesta inicia un nuevo proceso en el servidor
(backend) y conecta el proceso de frontend al nuevo servidor. A partir de este
punto, el proceso de frontend y el servidor en backend se comunican sin la
intervención del postmaster. Aunque, el postmaster siempre se está ejecutando,
esperando peticiones, los procesos de frontend y de backend vienen y se van.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
58
29
15/10/2014
Arquitectura POSTGRES
La librería libpq permite a un único proceso en frontend realizar múltiples
conexiones a procesos en backend. Aunque, la aplicación frontend
todavía es un proceso en un único thread.
Una implicación de esta arquitectura es que el postmaster y el proceso
backend siempre se ejecutan en la misma máquina (el servidor de base
de datos), mientras que la aplicación en frontend puede ejecutarse desde
cualquier sitio. Debe tener esto en mente, porque los archivos que pueden
ser accedidos en la máquina del cliente pueden no ser accesibles (o sólo
pueden ser accedidos usando un nombre de archivo diferente) en la
máquina del servidor de base de datos.
Tenga en cuenta que los servicios postmaster y postgres se ejecutan
con el identificador de usuario del "superusuario" Postgres. Note que el
superusuario Postgres no necesita ser un usuario especial (ej. un usuario
llamado "postgres"). De todas formas, el superusuario Postgres
definitivamente no tiene que ser el superusuario de Unix ("root")! En
cualquier caso, todos los archivos relacionados con la base de datos
deben pertenecer a este superusuario Postgres.
15/10/2014
Bases de Datos I - Mauricio E. Fernández N
59
30
Descargar