Beruflich Dokumente
Kultur Dokumente
de Organizacin y Estructura de la Informacin (EUI-UPM) Asignatura de Bases de Datos Pedro Pablo Alarcn Cavero Diciembre 1994
INDICE
1. INTRODUCCION. 2. LENGUAJE DE DEFINICION DE DATOS 3. LENGUAJE DE MANIPULACION DE DATOS 3.1. OPERACIONES DE ACTUALIZACION 3.2. OPERACIONES DE CONSULTA O RECUPERACION 4. LENGUAJE DE CONTROL DE DATOS 5. SQL INMERSO. 6. EJEMPLOS.
1. INTRODUCCIN
Desde que el Dr. Codd introdujera el concepto de Base de Datos Relacional, hacia 1970, hasta que se diseo un SGBDR (System R) pasaron varios aos. El System R (diseado por IBM), no era ms que un prototipo, y el principal objetivo era que el sistema fuese operacionalmente completo, es decir, demostrar que era posible construir un Sistema Relacional, utilizable en un entorno real, para solucionar problemas verdaderos, con un desempeo al menos comparable al de los sistemas existentes. Este sistema incorporaba un sublenguaje de datos que permita realizar cualquier acceso a la Base de Datos, que se llam SEQUEL. Posteriormente otros sistemas adoptaron este sublenguaje, al que pasaron a llamar SQL, como sublenguaje de consulta de datos, realizando modificaciones sobre l, hasta hoy en da, en que su utilizacin dentro del mbito comercial es realmente extensa. SQL es una abreviatura de "Structured Query Language", esto es, Lenguaje de Consulta Estructurado. Con este lenguaje se formulan operaciones relacionales, es decir, operaciones que permiten definir y manipular una base de datos relacional.
En 1986, el Instituto Nacional Norteamericano de Normalizacin (ANSI) public las primeras normas que enunciaban la
Pedro Pablo Alarcn Cavero SQL_Estndar. Pg. 1
sintaxis y la semntica de SQL. En 1989, ANSI defini el SQL2, basado en el anterior pero con una serie de mejoras (definicin de claves primarias, integridad de los datos, etc.). En este tema, abordaremos el estudio del SQL 86, ya que es en ste en el que est basado la versin de Informix_SQL que se utilizar para desarrollar las prcticas de la asignatura. A lo largo de la exposicin se hace referencia en los ejemplos a distintas tablas. Estas tablas se encuentran en el apartado 6 correspondiente a los ejemplos (pgina 18).
1.1. ARQUITECTURA
En la figura siguiente se muestra como ven los usuarios el SGBDR, bajo el punto de vista de la arquitectura de bases de datos ANSI/X3/SPARC.
SQL
NIVEL EXTERNO
VISTA 1
...
VISTA N
NIVEL CONCEPTUAL
TABLA BASE 1
TABLA BASE 2
...
TABLA BASE N
NIVEL INTERNO
FICHERO FSICO 1
FICHERO FSICO 2
...
FICHERO FSICO N
Nivel Externo:
SQL_Estndar. Pg. 2
Nivel Conceptual: compuesto por tablas base. Nivel Interno: compuesto por ficheros fsicos. Las tablas base estn almacenadas en ficheros, donde cada fila corresponde a un registro del fichero. Incorpora la posibilidad de construir ndices sobre cada una de las tablas.
Por tanto, las tablas que los usuarios pueden manejar son de dos tipos: tablas base y vistas. Una tabla base, es una tabla que tiene existencia por s misma, es decir, sus filas (registros) se encuentran almacenados fsicamente en uno o varios ficheros fsicos. Una vista es una tabla virtual, esto es, no tiene existencia por s misma, se definen a partir de una o ms tablas base. De ellas solamente existe su definicin en el diccionario de datos, y cuando se opera con ellas, se opera en realidad con las tablas base sobre las que est definida.
CATALOGO: Los SGBDR tienen una base de datos propia del sistema, que se llama catlogo o diccionario de datos y que contiene el esquema de las bases de datos de usuario, es decir, contiene informacin sobre las tablas base, las vistas, ndices, los derechos de acceso, identificacin de usuarios, etc. El catlogo no es propio del lenguaje SQL, sino de cada sistema en particular, pero puede consultarse utilizando la instruccin SELECT de SQL.
As pues, el SQL es al mismo tiempo un lenguaje de consulta interactivo y un lenguaje de programacin de bases de datos, aunque difieren en ciertos detalles que se vern ms adelante. En funcin de esta caracterstica, existirn dos tipos de usuarios en el sistema, usuarios finales en terminales en lnea y programadores de aplicaciones (el SGBDR deber permitir el acceso concurrente a datos compartidos, por parte de mltiples usuarios (finales y programas de aplicacin) de los dos tipos, realizando los controles necesarios para mantener la integridad y seguridad de los
Pedro Pablo Alarcn Cavero SQL_Estndar. Pg. 3
datos). Por ltimo, indicar que las sentencias SQL deben terminar en punto y coma (;), y que existe total libertad para escribir las palabras que componen una sentencia.
Cada funcin tiene su conjunto propio de instrucciones, que se expresan respectivamente en: - Lenguaje de Definicin de Datos (LDD) - Lenguaje de Manipulacin de Datos (LMD) - Lenguaje de Control de Datos (LCD)
SQL_Estndar. Pg. 4
Creacin de tablas
CREATE TABLE nombre_tabla (<definicin_atributo_1> [UNIQUE] [NOT NULL], (<definicin_atributo_2> [UNIQUE] [NOT NULL], ..................... (<definicin_atributo_n> [UNIQUE] [NOT NULL]); donde: definicin_atributo = nombre_atributo tipo_dato (tamao) UNIQUE: no se permiten valores duplicados en la columna NOT NULL: no se permiten valores nulos en la columna
Modificacin de tablas
Aadir un nuevo atributo ALTER TABLE <nombre_tabla> ADD <definicin_atributo>; En el caso que la tabla contenga una serie de filas, no se podr definir el atributo nuevo ni como UNIQUE ni como NOT NULL (ya que en las filas existentes no tendr valor). Modificar un atributo ya existente ALTER TABLE <nombre_tabla> MODIFY <definicion_atributo> Si la tabla ya contiene filas, se podr poner el atributo como NOT NULL, si dicho atributo no tiene valor nulo en ninguna fila. Si se quiere definir como UNIQUE el atributo no puede tener valores duplicados en las filas existentes.
Eliminacin de tablas
DROP TABLE <nombre_tabla> Esta sentencia elimina tanto el contenido como la definicin (esquema) de la tabla especificada.
Eliminacin de vistas
DROP VIEW <nombre_vista>;
SQL_Estndar. Pg. 5
Esta sentencia permite eliminar la definicin de una vista de usuario del catlogo de la base de datos.
Eliminacin de ndices
DROP INDEX <nombre_indice> [ON <nombre_tabla>] Esta sentencia elimina el fichero ndice especificado. La opcin "ON nombre_tabla", cuando ms de una tabla tenga ndices con el mismo nombre. Es el sistema el encargado de utilizar los ndices, para optimizar el acceso a los datos. El usuario slo puede crear o eliminar ndices, pero no indicar su utilizacin.
FROM <lista_de_tablas> [WHERE <condicion>] [GROUP BY <lista_de_atributos> [HAVING <condicin_de_grupo> ]] [ORDER BY <lista_de_atributos> [ASC/DESC] ]; SELECT: Indica que la operacin a realizar es una consulta, y adems qu informacin se desea obtener. Se puede incluir la opcin UNIQUE o DISTINCT para no obtener filas duplicadas en el resultado. FROM: Especifica las tablas en las que se encuentran los atributos implicados en la consulta.
WHERE: Especifica la condicin de bsqueda que se requiere para obtener la informacin deseada. GROUP BY: Permite agrupar el resultado en base a los atributos especificados. HAVING: Especifica una condicin de grupo.
3.2.2. OPERADORES
Los siguientes operadores se pueden utilizar para expresar condiciones de fila (clusula WHERE) o de grupo (clusula HAVING). - De comparacin (<, <=, >, >=, <>, =) - Lgicos (AND, OR, NOT) - BETWEEN ... AND ... - LIKE - IN - IS NULL - Cuantificadores (ANY, SOME, ALL) - Existencial (EXISTS)
1. Recuperacin simple
Obtener todos los datos de todos los proyectos. SELECT p#, descrip, localidad, cliente FROM proyecto : SELECT * FROM proyecto; *: equivale a todos los atributos de una tabla
Obtener los cdigos de mquina (m#) para todas las mquinas utilizadas. SELECT DISTINCT m# FROM trabajos;
SQL_Estndar. Pg. 8
2. Recuperacin calificada
Obtener los cdigos de los conductores que son de Arganda. SELECT c# FROM conductores WHERE localidad = 'ARGANDA';
Obtener los cdigos de los conductores de Arganda que tengan categora inferior a 20. SELECT c# FROM conductores WHERE localidad = 'ARGANDA' AND categ < 20;
SQL_Estndar. Pg. 9
Obtener nombres de los trabajadores que han utilizado la mquina 'M2'. SELECT nombre FROM conductores WHERE c# IN (SELECT c# FROM trabajos WHERE m# = 'M2'); : SELECT nombre FROM conductores, trabajos WHERE conductores.c# = trabajos.c# AND m# = 'M2'; : SELECT nombre FROM conductores WHERE 'M2' IN (SELECT m# FROM trabajos WHERE conductores.c# = trabajos.c#);
SQL_Estndar. Pg. 10
ALL >= ALL < ALL, ... ANY >= ANY < ANY, ...
Obtener los conductores que no han participado en el proyecto 'P1'. SELECT nombre FROM conductor WHERE c# <> ALL (SELECT c# FROM trabajos WHERE p# = 'P1');
Obtener los trabajadores con categora inferior a la de algn trabajador de Arganda. SELECT nombre FROM conductores WHERE categ < ANY (SELECT categ FROM conductores WHERE localidad = "ARGANDA");
Obtener los cdigos de aquellos conductores que residan en Rivas o tengan categora inferior a 15.
SQL_Estndar. Pg. 11
SELECT c# FROM conductores WHERE localidad = 'RIVAS' UNION SELECT c# FROM conductores WHERE categ < 25; Obtener los cdigos de aquellos trabajadores que tengan categora inferior a 15 y que no hayan trabajado con la mquina M3. SELECT c# FROM conductores WHERE categ < 15 MINUS SELECT c# FROM trabajos WHERE m# = 'M3';
Devuelven un valor nico, numrico, como resumen de la informacin relativa a atributos. No se puede combinar una funcin agregada, con columnas que devuelvan ms de un valor, a menos que la consulta contenga una clusula GROUP BY.
SQL_Estndar. Pg. 12
SELECT COUNT (DISTINCT m#) FROM trabajos WHERE p# = 'P2'; Obtener el precio medio por hora de las mquinas utilizadas en el proyecto 'P1' SELECT AVG(precio_hora) FROM maquinas WHERE m# IN (SELECT m# FROM trabajos WHERE p#='P1'); Obtener el precio total a pagar a los trabajadores del proyecto 'P3' SELECT SUM (tiempo*precio_hora) FROM trabajos, maquinas WHERE p# = 'P3' AND trabajos.m# = maquinas.m#; Obtener el precio hora de mquina ms elevado" SELECT MAX (precio_hora) FROM maquinas; Obtener el nombre del conductor que ha trabajado menos tiempo con la mquina 'M2'. SELECT nombre FROM conductores WHERE c# IN (SELECT c# FROM trabajos WHERE tiempo IN (SELECT MIN(tiempo) FROM trabajos WHERE m# = 'M2'));
GROUP BY <lista_de_atributos>
Agrupa el resultado de una consulta en base a uno o varios atributos, devolviendo una nica fila por grupo. El agrupamiento no se realiza ordenado, el resultado de ste depende de como est la tabla. Los atributos que aparezcan en la clusula GROUP BY, deben aparecer en la clusula SELECT.
Obtener por cada conductor que haya trabajado, el cdigo de ste y la cantidad total de tiempo empleado. SELECT c#, SUM(tiempo) FROM trabajos GROUP BY c#;
Resultado:
SQL_Estndar. Pg. 13
Aqu, si puede aparecer una funcin, puesto que GROUP BY devuelve un nico valor por grupo. Para cada valor de P# distinto en la tabla trabajos, aparecer su suma total. Obtener para cada conductor en el proyecto 'P1', su cdigo y el tiempo mximo trabajado. SELECT c#, MAX (tiempo) FROM trabajos WHERE p# = 'P1' GROUP BY c#; Resultado: c# MAX(tiempo) C2 100
HAVING <condicion_de_grupo> Siempre va acompaada de la clusula GROUP BY. Especifica una condicin de grupo, seleccionndose slo aquellos grupos que cumplan la condicin especificada. Conceptualmente es como el WHERE, salvo que ste acta a nivel de tuplas.
Obtener para los conductores que hayan utilizado la misma mquina ms de una vez entre el 12/09/94 y el 18/09/94, el cdigo de conductor, el cdigo de mquina y el tiempo total empleado. SELECT c#, m#, SUM (tiempo) FROM trabajos WHERE fecha BETWEEN 12/09/94 AND 18/09/94 GROUP BY c#, m# HAVING COUNT(*) > 1; Resultado: c# m# SUM(tiempo) C1 M2 C2 M3 240 110
SQL_Estndar. Pg. 14
El resultado de la consulta se ordena en base a los atributos que se indiquen en la lista. Los Atributos de ordenacin deben ser atributos o expresiones que aparezcan en la clusula SELECT. Cada atributo puede llevar un criterio de ordenacin, ascendente (ASC) o descendente (DESC), por defecto ascendente. Obtener los partes de trabajo correspondientes al proyecto 'P4' ordenados ascendentemente por conductor y mquina. SELECT * FROM trabajos WHERE p# = 'P4' ORDER BY c#, m#; Resultado: C# M# P# FECHA TIEMPO C1 C1 C3 C5 M2 M3 M1 M3 P4 P4 P4 P4 17/09/94 15/09/94 15/09/94 15/09/94 120 180 300 90
Se utilizan en los siguientes casos: 1. Para hacer el nombre de una columna ms significativo cuando se muestra. 2. Abreviar un nombre de una tabla o de una columna que se usa a menudo. 3. Hacer ms clara una instruccin complicada de SQL. 4. Distinguir entre dos ocurrencias del mismo nombre de columna o tabla en cualquier instruccin SELECT. Obtener los conductores que tengan la categora ms alta. SELECT X.nombre CONDUCTOR, X.categ CATEGORIA FROM conductores X, conductores Y WHERE X.categ > = Y.categ;
Concesin de privilegios
La concesin de privilegios se utiliza para permitir a los usuarios el acceso completo o restringido a las tablas de la base de datos. GRANT <accesos> ON <lista_de_tablas> TO <lista_de_cesionarios>|PUBLIC [WITH GRANT OPTION]; donde: <accesos>: - ALL PRIVILEGES - SELECT - UPDATE - INSERT - DELETE PUBLIC: se conceden los privilegios especificados a todos los usuarios del sistema. WITH GRANT OPTION: se concede el privilegio de poder otorgar privilegios a otros usuarios.
Revocacin de privilegios
Se utiliza para anular privilegios ya concedidos a los usuarios. REVOKE <accesos> FROM <nombre_usuario> TO <lista_de_tablas>
Commit work
Los cambios que se puedan estar realizando sobre la base de datos se hacen fijos nicamente al completar la transaccin. (Transaccin: secuencia de operaciones tales que cada operacin de la secuencia es necesaria para completar un resultado unitario. Todas las operaciones deben completarse para que la base de datos quede consistente)
En la base de datos de ejemplo, si eliminamos un proyecto ser necesario eliminar las filas de la tabla TRABAJOS que pertenezcan al proyecto eliminado. Para mantener la integridad de la base de datos o se ejecutan las dos operaciones de borrado o no se debe ejecutar ninguna.
Rollback work
Elimina todos los cambios que se hayan podido producir en la base de datos desde la ejecucin de la ltima instruccin COMMIT. Si se produce un error de programa o un fallo hardware el sistema realiza un ROLLBACK automticamente.
5. SQL INMERSO
Como se indic en la introduccin, las sentencias SQL pueden incluirse en un programa de aplicacin escrito en un lenguaje de programacin. En este contexto, llamaremos lenguaje anfitrin al lenguaje de programacin utilizado, y lenguaje husped al lenguaje SQL.
SQL_Estndar. Pg. 16
Para que puedan incluirse sentencias SQL en un programa, es necesario que el SGBDR disponga de un precompilador de SQL para el lenguaje de programacin a utilizar. La funcin del precompilador es traducir las sentencias SQL que aparezcan en el programa fuente en llamadas a rutinas del SGBDR. Una vez precompilado el programa, el fichero resultante se compila con un compilador del lenguaje de programacin utilizado. Como resultado final, se obtiene un programa ejecutable, que interacta con el SGBDR. Se llama SQL inmerso, al conjunto de instrucciones SQL que permiten su utilizacin en programas escritos en lenguajes de programacin.
Instrucciones
Todas las instrucciones de SQL inmerso van precedidas de las palabras clave EXEC SQL. Dependiendo del lenguaje de programacin acabarn en punto y coma o en otro indicador.
Variables principales
Las variables principales del programa, pueden utilizarse para almacenar el resultado de una consulta que devuelva una sola fila o bien pueden utilizarse en la propia instruccin SQL. EXEC SQL SELECT nombre INTO :nom_cond FROM conductores WHERE p# = :variable_principal; Las variables que se usen en las instrucciones EXEC SQL, deben aparecer en una seccin de declaracin en el programa principal. Esta seccin comenzar con EXEC SQL BEGIN DECLARE y finalizar con EXEC SQL END DECLARE.
Cursores
El resultado de una consulta SQL que devuelva ms de una fila no se puede almacenar en variables principales. Para estos casos se utilizarn los cursores, que son ficheros virtuales de registros, en los que se almacenan el resultado de una consulta (cada fila un registro). Por tanto un cursor debe asociarse con una consulta, y se declaran de la siguiente forma: EXEC SQL DECLARE <nombre_cursor> CURSOR FOR <consulta_SQL>; Para poder utilizar el fichero virtual que representa el cursor es necesario abrirlo primero: EXEC SQL OPEN <nombre_cursor>; En el programa que se utilice ser necesario la lectura de los registros. La forma de leer un registro del cursor es: EXEC SQL FETCH <nombre_cursor> INTO <variables_principales>; Cuando ya no se necesite el cursor, es conveniente cerrarlo: EXEC SQL CLOSE <nombre_cursor>;
6. EJEMPLOS
BASE DE DATOS DE EJEMPLO
Un empresario que se dedica a la construccin, dispone de una base de datos para gestionar la contratacin de maquinarias (camiones, excavadoras,...) en sus proyectos. En una fecha determinada la base de datos contiene la siguiente informacin:
SQL_Estndar. Pg. 17
TABLA PROYECTOS
P# P1 P2 P3 P4
TABLA MAQUINAS
M# M1 M2 M3
TABLA CONDUCTORES
C# C1 C2 C3 C4 C5
NOMBRE JOSE SANCHEZ MANUEL DIAZ JUAN PEREZ LUIS ORTIZ JAVIER MARTIN
CATEG 18 15 20 18 12
TABLA TRABAJOS
C# C2 C3 C5 C4 C1 C2 C3 C2 C1 C5 C1 C2
M# M3 M1 M3 M3 M2 M3 M1 M3 M3 M3 M2 M3
P# P1 P2 P2 P2 P2 P3 P4 P2 P4 P4 P4 P1
FECHA 10/09/94 10/09/94 10/09/94 10/09/94 12/09/94 13/09/94 15/09/94 15/09/09 15/09/94 15/09/94 17/09/94 18/09/94
SQL_Estndar. Pg. 18
DESCRIP CHAR(20) NOT NULL, LOCALIDAD CHAR(15), CLIENTE CHAR(20) NOT NULL);
El atributo P# se define como UNIQUE NOT NULL, puesto que es la clave de la tabla, y por tanto no debe tener valores duplicados (por la definicin de clave) ni valores nulos (integridad de la entidad). Los atributos DESCRIP y CLIENTE se definen como NOT NULL, por considerar que es informacin que no debe faltar al insertar una fila (del mismo modo se podra considerar LOCALIDAD). Al ejecutar esta sentencia se crear la definicin de la tabla PROYECTOS (la tabla estar vaca, sin filas), almacenndose dicha definicin en el diccionario de datos (tablas propias del sistema que contienen el esquema de la base de datos).
Los atributos que forman parte de la clave de esta tabla se han definido como NOT NULL (integridad de la entidad), pero en cualquier caso los atributos simples que son clave en otra tabla se deben definir como NOT NULL para mantener la integridad referencial. En este caso, puesto que la clave est formada por ms de un atributo no podemos definir los atributos que la forman como UNIQUE, ya que lo que no debe repetirse es el valor de la clave, y no el valor de los atributos que la forman. Para establecer la unicidad de la clave, crearemos un ndice. CREATE UNIQUE INDEX clave_trabajo ON TRABAJOS (C#, M#, P#, FECHA); De esta forma aseguramos la unicidad de la clave, al definir un ndice con los atributos que la componen como nico. Podramos crear tambin ndices para cada una de las dems tablas, sobre las claves de stas, ya que estos atributos participarn en las uniones naturales cuando las consultas involucren ms de una tabla. De esta forma, se tardar menos tiempo en ejecutar estas consultas. Tambin se podran crear ndices para aquellos atributos que se consulten frecuentemente (por ejemplo nombre de conductor). Los ndices deben crearse para asegurar la unicidad de una clave compuesta por ms de un atributo, o para optimizar el acceso en las consultas. La creacin de los ndices debe estudiarse detenidamente, ya que al actualizar una tabla (insertar y borrar una fila, o modificar valores de los atributos que forman la clave de un ndice) el sistema debe actualizar tambin los ficheros ndices. Esta actualizacin consume tiempo, y si el nmero de ndices es elevado, puede no ser rentable la optimizacin en consultas por el retraso en tiempo que sufren las actualizaciones.
CREATE VIEW partes_trabajo (proyecto, conductor, maquina, fecha, minutos) AS (SELECT descrip, conductores.nombre, maquinas.nombre, fecha, tiempo FROM proyectos, conductores, maquinas, partes
SQL_Estndar. Pg. 19
Al ejecutar esta sentencia el sistema crear la definicin de la vista partes_trabajo. Esta vista nunca contendr filas (es una tabla virtual), sus filas correspondern al resultado de la consulta sobre la que est definida. Por ejemplo, la consulta: SELECT conductor, maquina, fecha, minutos FROM partes_trabajo WHERE proyecto = 'CONSTRUCCION CHALET'; dar como resultado:
CONDUCTOR JUAN PEREZ JAVIER MARTIN LUIS ORTIZ JOSE SANCHEZ MANUEL DIAZ
MAQUINA
FECHA
EXCAVADORA 10/09/94 VOLQUETE 10/09/94 VOLQUETE 10/09/94 HORMIGONERA 12/09/94 VOLQUETE 15/09/94
Actualizacin de filas
Subir el precio_hora de todas las mquinas en un 10% UPDATE maquinas SET precio_hora = precio_hora * 1.1;
UPDATE conductores SET categ = categ + (SELECT categ/6 FROM conductores WHERE categ = (SELECT MIN(categ) FROM conductores) ) WHERE localidad = 'ARGANDA'; Esta solucin no es vlida en Informix_sql, ya que no permite que se realice una consulta sobre la tabla que se est
Pedro Pablo Alarcn Cavero SQL_Estndar. Pg. 20
modificando en la asignacin del nuevo valor para el atributo. La actualizacin puede realizarse con xito utilizando una tabla temporal como se muestra a continuacin: SELECT (categ/6) tercio FROM conductores WHERE categ IN (SELECT MIN (categ) FROM conductores) INTO TEMP minima; UPDATE conductores SET categ = categ + (SELECT tercio FROM minima) WHERE localidad = 'ARGANDA'; DROP TABLE minima; De esta forma, utilizamos una tabla temporal en la que se almacena la tercera parte de la categora ms baja en el atributo tercio, y posteriormente se actualiza el valor de categora consultando dicha tabla temporal. Por ltimo eliminamos la tabla temporal, aunque no sera del todo necesario, porque el sistema elimina las tablas temporales al abandonar el entorno sql.
Borrado de filas
Eliminar de la base de datos al conductor Javier Martn. DELETE FROM conductores WHERE nombre = 'JAVIER MARTIN'; Con esta sentencia eliminamos al conductor, pero la base de datos puede quedar inconsistente, ya que en la tabla TRABAJOS puede figurar el cdigo de ste (no debe consentirse nunca la aparicin de inconsistencias en la base de datos, ya que dan lugar a resultados incorrectos). Para evitar que esta eliminacin provoque una inconsistencia, habr que eliminar de la base de datos cualquier referencia al conductor eliminado. En nuestro caso, C# est definido como NOT NULL en la tabla TRABAJOS, por tanto habr que eliminar todas las filas de esta tabla en las que aparezca el conductor eliminado para dejar la base de datos consistente. Si admitiera valores nulos en lugar de eliminar la fila entera podramos modificar el valor del cdigo de conductor con NULL.
DELETE FROM trabajos WHERE c# NOT IN (SELECT c# FROM conductores); Tambin podamos haber realizado la siguiente secuencia: DELETE FROM trabajos WHERE c# IN (SELECT c# FROM conductores WHERE nombre = 'JAVIER MARTIN'); DELETE FROM conductores WHERE nombre = 'JAVIER MARTIN');
SQL_Estndar. Pg. 21
Las dos operaciones de eliminacin de datos (eliminacin en trabajos y en conductores), deben ejecutarse como una transaccin nica, de tal forma que se ejecuten las dos operaciones o no se ejecute ninguna.
Obtener el importe total de los trabajos realizados al cliente Felipe Garca, ms el 20% de beneficio de la empresa. SELECT SUM(tiempo*precio_hora/60)*1.20 'IMPORTE_TOTAL' FROM trabajos, maquinas, proyectos WHERE cliente = 'FELIPE GARCIA' AND proyectos.p# = trabajos.p# AND trabajos.m# = maquinas.m#;
SQL_Estndar. Pg. 22
En este ejemplo, se calcula la suma de las cantidades resultantes de multiplicar el tiempo (expresado en minutos) empleado por cada mquina en los diferentes proyectos que se hayan realizado al cliente Felipe Garca, por el coste de la mquina por minuto (coste de una hora dividido entre 60 minutos). El resultado de dicha suma se multiplica por 1.20 para obtener, el coste total ms el 20%. Se ha especificado un literal ('IMPORTE_TOTAL') para que este sea la cabecera de la tabla resultado.
Obtener nombre de los conductores que no tengan la categora ms alta. SELECT nombre FROM conductores WHERE categ NOT IN (SELECT MAX(categ) FROM conductores); Resultado: NOMBRE MANUEL DIAZ JAVIER MARTIN : SELECT x.nombre FROM conductores x, conductores y WHERE x.categ < y.categ; Resultado: X.NOMBRE MANUEL DIAZ MANUEL DIAZ MANUEL DIAZ JAVIER MARTIN JAVIER MARTIN JAVIER MARTIN JAVIER MARTIN
En esta segunda solucin se utilizan mediante el empleo de alias de tabla, dos copias de la misma tabla (conductores), que a efectos de la consulta son tratadas como dos tablas diferentes. Si no queremos que aparezcan filas duplicadas en la tabla resultado: SELECT UNIQUE x.nombre
SQL_Estndar. Pg. 23
Obtener el tiempo total empleado en cada proyecto. SELECT p#, SUM(tiempo) FROM trabajos GROUP BY p#;
Resultado: P# SUM(tiempo)
P1 P2 P3 P4
En esta consulta, al agrupar por el atributo p#, se obtiene por cada valor diferente de p# en la tabla TRABAJOS el valor de la funcin especificada. Es decir, por todas las filas que tienen el mismo valor de p# (grupo) se obtiene la suma correspondiente al valor del atributo TIEMPO.
Conductores que han participado en todos los proyectos de Arganda. SELECT nombre FROM conductores, trabajos, proyectos WHERE proyecto.localidad = 'ARGANDA' AND conductores.c# = trabajos.c# AND trabajos.p# = proyectos.p# GROUP BY nombre HAVING COUNT (DISTINCT p#) = (SELECT COUNT (p#) FROM proyectos WHERE localidad = 'ARGANDA'); Resultado: NOMBRE MANUEL DIAZ
En la clusula WHERE especificamos las condiciones de fila para obtener los datos relativos a los conductores que han participado en proyectos realizados en Arganda. Despus se agrupa por nombre y especificamos que por cada grupo (nombre de conductor) el nmero de proyectos distintos en los que ha participado debe ser igual al nmero de proyectos realizados en Arganda.
Obtener el cdigo del proyecto en el que ms tiempo se ha empleado. SELECT p# FROM trabajos GROUP BY p# HAVING SUM(tiempo) IN (SELECT MAX(SUM(tiempo)) FROM trabajos
SQL_Estndar. Pg. 24
GROUP BY p#);
Esta solucin que es vlida en SQL estndar, no lo es en la versin de Informix_sql que utilizaremos en las prcticas, ya que no permite anidar funciones. Para solucionar este problema, podemos crear una tabla temporal para obtener los valores correspondientes a la primera funcin. Veamos una posible solucin: SELECT SUM(tiempo) suma FROM trabajos GROUP BY p# INTO TEMP sumas; SELECT p# FROM trabajos GROUP BY p# HAVING SUM(tiempo) IN (SELECT MAX(suma) FROM sumas); Resultado: P# P4
La primera consulta crea la tabla temporal SUMAS, en la que se almacena en el atributo SUMA, la suma de los tiempos empleados para cada uno de los proyectos. En la segunda consulta para cada proyecto, se comprueba si la suma del tiempo empleado coincide con el proyecto con mayor tiempo empleado. Una vez realizada la consulta es conveniente eliminar la tabla temporal, ya que si antes de abandonar la sesin se intenta ejecutar de nuevo esta consulta aparecer un error al intentar crear una tabla temporal ya existente. En cualquier caso, al abandonar la sesin desaparecen todas las tablas temporales que se hayan podido crear durante sta.
SQL_Estndar. Pg. 25