parte 1 de 2 - elmasri - capitulo 8 - sql

20
a- a- n- y CAPíTULO 8 SQL-99: definición del esquema, restricciones, consultas y vistas E l lenguaje SQL se puede considerar como una de las principales razones del éxito comercial de las bases de datos relacionales. Como se convirtió en un estándar para estas últimas, los usuarios perdieron el miedo a migrar sus aplicaciones de base de datos desde otros tipos de sistemas de bases de datos (por ejemplo, sistemas de red o jerárquicos) a los sistemas relacionales, porque aunque estuvieran satisfechos con el producto DBMS relacional que estaban utilizando, no esperaban que la conversión a otro producto DBMS relacional fuera caro y consumiera mucho tiempo, ya que ambos sistemas seguían los mismos estándares en cuanto al lenguaje. En la práctica, por supuesto, hay muchas diferencias entre los distintos paquetes DBMS relacionales comerciales. Sin embargo, si el usuario sólo utiliza las funciones que forman parte del estándar, y si ambos sistemas relacionales soportan fielmente el estándar, la conversión entre los dos sistemas es mucho más sencilla. Otra ventaja de disponer de un estándar es que los usuarios pueden escribir sentencias en una aplicación de base de datos para acceder a los datos almacenados en dos o más DBMSs relacionales sin tener que cambiar el sublenguaje de base de datos (SQL), siempre y cuando esos DBMS soporten el SQL estándar. Este capítulo presenta las principales características del estándar SQL para los DBMSs relacionales comercia- les, mientras que el Capítulo 5 presentó los conceptos fundamentales del modelo de datos relacionalformal. En el Capítulo 6 (Secciones 6.1 a 6.5) explicamos las operaciones del álgebra relacional, que es muy impor- tante para entender los tipos de solicitudes que se pueden especificar en una base de datos relacional. También son muy importantes para el procesamiento y la optimización de consultas en un DBMS relacional, como tam- bién veremos en los Capítulos 15 y 16. No obstante, las operaciones del álgebra relacional están consideradas como muy técnicas por la mayoría de los usuarios de los DBMSs comerciales, porque una consulta en el álge- bra relacional se escribe como una secuencia de operaciones que, cuando se ejecutan, producen el resultado requerido. Por tanto, el usuario debe especificar cómo (es decir, en qué orden) hay que ejecutar las operacio- nes de la consulta. Por otro lado, el lenguaje SQL proporciona una interfaz de lenguaje declarativo del más alto nivel, por lo que el usuario sólo especifica lo que debe ser el resultado, dejando para el DBMS la optimi- zación y las decisiones de cómo ejecutar la consulta. Aunque SQL incluye algunas características del álgebra relacional, está basado en gran medida en el cálculo relacional de tuplas (consulte la Sección 6.6). Sin embar- go, la sintaxis de SQL es mucho más amigable para el usuario que cualquiera de los otros dos lenguajes for- males. http://libreria-universitaria.blogspot.com

Upload: david-kummers

Post on 04-Jan-2016

50 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

a­a-

n-y

CAPíTULO 8 SQL-99: definición del esquema,

restricciones, consultas

y vistas

El lenguaje SQL se puede considerar como una de las principales razones del éxito comercial de las bases de datos relacionales. Como se convirtió en un estándar para estas últimas, los usuarios perdieron el miedo a migrar sus aplicaciones de base de datos desde otros tipos de sistemas de bases de datos (por

ejemplo, sistemas de red o jerárquicos) a los sistemas relacionales, porque aunque estuvieran satisfechos con el producto DBMS relacional que estaban utilizando, no esperaban que la conversión a otro producto DBMS relacional fuera caro y consumiera mucho tiempo, ya que ambos sistemas seguían los mismos estándares en cuanto al lenguaje. En la práctica, por supuesto, hay muchas diferencias entre los distintos paquetes DBMS relacionales comerciales. Sin embargo, si el usuario sólo utiliza las funciones que forman parte del estándar, y si ambos sistemas relacionales soportan fielmente el estándar, la conversión entre los dos sistemas es mucho más sencilla. Otra ventaja de disponer de un estándar es que los usuarios pueden escribir sentencias en una aplicación de base de datos para acceder a los datos almacenados en dos o más DBMSs relacionales sin tener que cambiar el sublenguaje de base de datos (SQL), siempre y cuando esos DBMS soporten el SQL estándar.

Este capítulo presenta las principales características del estándar SQL para los DBMSs relacionales comercia­les, mientras que el Capítulo 5 presentó los conceptos fundamentales del modelo de datos relacionalformal. En el Capítulo 6 (Secciones 6.1 a 6.5) explicamos las operaciones del álgebra relacional, que es muy impor­tante para entender los tipos de solicitudes que se pueden especificar en una base de datos relacional. También son muy importantes para el procesamiento y la optimización de consultas en un DBMS relacional, como tam­bién veremos en los Capítulos 15 y 16. No obstante, las operaciones del álgebra relacional están consideradas como muy técnicas por la mayoría de los usuarios de los DBMSs comerciales, porque una consulta en el álge­bra relacional se escribe como una secuencia de operaciones que, cuando se ejecutan, producen el resultado requerido. Por tanto, el usuario debe especificar cómo (es decir, en qué orden) hay que ejecutar las operacio­nes de la consulta. Por otro lado, el lenguaje SQL proporciona una interfaz de lenguaje declarativo del más alto nivel, por lo que el usuario sólo especifica lo que debe ser el resultado, dejando para el DBMS la optimi­zación y las decisiones de cómo ejecutar la consulta. Aunque SQL incluye algunas características del álgebra relacional, está basado en gran medida en el cálculo relacional de tuplas (consulte la Sección 6.6). Sin embar­go, la sintaxis de SQL es mucho más amigable para el usuario que cualquiera de los otros dos lenguajes for­males.

http://libreria-universitaria.blogspot.com

Page 2: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

204 Capítulo 8 SQL-99: definición del esquema, restricciones, consultas y vistas

El nombre SQL significa Lenguaje de consulta estructurado (Structured Que/)I Langllage). Originalmente, SQL se denominaba SEQUEL (Stl'uctllred English QUE/)I Language) y fue diseñado e implementado por IBM Research a modo de interfaz para un sistema de base de datos relacional conocido como SYSTEM R. SQL es ahora el lenguaje estándar de los DBMSs relacionales comerciales. Un esfuerzo conjunto llevado a cabo por el Instituto nacional americano de normalización (ANSI, American National Standal'ds lnstitute) y la Organizacón internacional para la normalización (ISO, lnternational Standal'ds Ol'ganization) llevó a una versión estándar de SQL (ANSI 1986), denominada SQL-86 o SQL1. A continuación se desarrolló un están­dar revisado y mucho más amplio, SQL2 (también conocido como SQL-92). El siguiente estándar fue SQL-99. Se han propuesto otros estándares, como SQL3, pero no han gozado de suficiente respaldo por parte de la industria. Intentaremos cubrir en lo posible la última versión de SQL.

SQL es un lenguaje de bases de datos global: cuenta con sentencias para definir datos, consultas y actualiza­ciones. Por tanto, se compOlia como DDL y como DML. Además, dispone de características para definir vis­tas en la base de datos, especificar temas de seguridad y autorización, definir restricciones de integridad, y especificar controles de transacciones. También tiene reglas para incrustar sentencias de SQL en un lenguaje de programación de propósito general, como Java, COBOL o C/C++.l

Como la especificación del estándar SQL sigue creciendo, con más funciones en cada nueva versión del están­dar, el último estándar, SQL-99, está dividido en una especificación central (o núcleo) más unos paquetes especilizados opcionales. Se supone que todos los desarrolladores de DBMSs compatibles con SQL-99 imple­mentan dicho núcleo. Los paquetes pueden implementarse como módulos opcionales que pueden adquirirse independientemente para determinadas aplicaciones de bases de datos; por ejemplo, para el minado de datos, datos espaciales, datos meteorólogicos, datos de almacenamiento, procesamiento analítico online (OLAP), datos multimedia, etcétera. Ofreceremos un resumen de algunos de estos paquetes (y dónde se explican en este libro) al final del presente capítulo.

Como SQL es muy importante (y muy extenso) dedicaremos dos capítulos a sus características básicas. En este capítulo, la Sección 8.1 describe los comandos DDL de SQL para crear esquemas y tablas, y ofrece una panorámica de los tipos básicos de datos. La Sección 8.2 explica cómo se especifican las restricciones bási­cas, como la integridas de clave y referencial. La Sección 8.3 explica las sentencias para modificar esquemas, tablas y restricciones. La Sección 8.4 describe las construcciones SQL básicas destinadas a especificar las consultas de recuperación, mientras que la Sección 8.5 explora las funciones más complejas de las consultas SQL, como las funciones de agregación y agrupamiento. La Sección 8.6 describe los comandos SQL para la inserción, eliminación y actualización de datos.

En la Sección 8.7 describimos la sentencia CREATE ASSERTION, que permite especificar las restricciones más generales de la base de datos. También introducimos el concepto de tl'iggers, que se presentan más en profundidad en el Capítulo 24. A continuación, la Sección 8.8 describe los servicios de SQL para definir vis­tas en la base de datos. Las vistas también se denominan tablas virtuales o derivadas porque presentan al usuario lo que parece haber en unas tablas; sin embargo, la información de dichas tablas deriva de otras tablas previamente definidas.

La Sección 8.9 enumera algunas de las características de SQL que se presentan en otros capítulos del libro, como el control de las transacciones en el Capítulo 17, los temas de seguridad y autorización en el Capítulo 23, las bases de datos activas (triggers) en el Capítulo 24, las características orientadas a objetos en el Capítulo 22, y las características de procesamiento analítico online (OLAP) en el Capítulo 28. La Sección 8.10 resume el capítulo. El Capítulo 9 explica varias técnicas de programación de bases de datos destinadas a programar con SQL.

El lector que desee una introducción menos global a SQL, puede omitir partes de las Secciones 8.2 y 8.5, así como las Secciones 8.7 y 8.8.

I Originalmente, SQL tenía sentencias para crear y eliminar índices en los ficheros que representaban las relaciones, pero esto ha desapa­recido por un tiempo del estándar SQL.

http://libreria-universitaria.blogspot.com

Page 3: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

s

e

a

s s a

s n

s

o o e r

8.1 Definición de datos y tipos de datos de SQL 205

8.1 Definición de datos y tipos de datos de Sal SQL utiliza los términos tabla, fila y columna para los términos relación, tupla y atributo del modelo rela­cional formal, respectivamente. Utilizaremos todos estos términos indistintamente. El principal comando de SQL para definir datos es la sentencia CREATE, que se utiliza para crear esquemas, tablas (relaciones) y domi­nios (así como otras estructuras, como vistas, aserciones y triggers). Antes de describir las sentencias CREA­TE relevantes, explicamos los conceptos de esquema y catálogo en la Sección 8.1.1 para centrar nuestra expli­cación. La Sección 8.1.2 describe la creación de las tablas y la Sección 8.1.3 describe los tipos de datos más impOliantes disponibles para la especificación de atributos. Como la especificación SQL es muy larga, ofre­cemos una descripción de las características más importantes. Los detalles más avanzados se pueden encon­trar en los distintos documentos de los estándares SQL (consulte las notas bibliográficas).

8.1.1 Conceptos de esquema y catálogo en Sal

Las versiones anteriores de SQL no incluían el concepto de esquema de base de datos relacional; todas las tablas (relaciones) estaban consideradas como parte del mismo esquema. El concepto de esquema SQL se incorporó por primera vez en SQL2 para agrupar las tablas y otras estructuras pertenecientes a la misma apli­cación de base de datos. Un esquema SQL se identifica con un nombre de esquema e incluye un identifi­cador de autorización para indicar el usuario o la cuenta propietaria del esquema, así como unos descripto­res para cada elemento. Los elementos del esquema son las tablas, las restricciones, las vistas, los dominios y otras estructuras (como la concesión de autorización), que describen el esquema. El esquema se crea con la sentencia CREATE SCHEMA, que puede incluir las definiciones de todos sus elementos. Como alternativa, puede asignarse un nombre y un identificador de autorización al esquema, y definir los elementos más tarde. Por ejemplo, la siguiente sentencia crea el esquema EMPRESA, propiedad del usuario cuyo identificador de autorización es 'Jperez'.

CREATE SCHEMA EMPRESA AUTHORIZATION Jperez;

En general, no todos los usuarios están autorizados a crear esquemas y elementos de esquema. El privilegio de crear esquemas, tablas y otras estructuras debe ser otorgado explícitamente por el administradr del sistema o DBA a las cuentas de usuario pertinentes.

Además del concepto de esquema, SQL2 utiliza el concepto de catálogo, que es una colección de esquemas bajo un nombre, en un entorno SQL. Un entorno SQL es básicamente una instalación de un RDBMS com­patible con SQL en un computador.2 Un catálogo siempre contiene un esquema especial denominado INFOR­MATION_SCHEMA, que proporciona información sobre todos los esquemas del catálogo y todos los descrip­tores de elemento de esos esquemas. Las restricciones de integridad, como la integridad referencial, se pue­den definir entre las relaciones sólo si existen en los esquemas del mismo catálogo. Los esquemas del mismo catálogo también pueden compartir ciertos elementos, como las definiciones de dominio.

8.1.2 El comando CREATE TABlE de Sal

El comando CREATE TABLE se utiliza para especificar una nueva relación, asignándole a esta última un nom­bre y sus atributos y restricciones iniciales. Primero se especifican los atributos, a cada uno de los cuales se le asigna un nombre, un tipo de datos para especificar su dominio de valores, y cualesquiera restricciones de atributo, como NOT NULL. Las restricciones de clave, integridad de entidad e integridad referencial, pueden especificarse con la sentencia CREATE TABLE después de haber declarado los atributos, o pueden añadirse más tarde con el comando ALTER TABLE (consulte la Sección 8.3). La Figura 8.1 muestra unos ejemplos de sentencias de SQL para definir los datos del esquema de la base de datos relacional de la Figura 5.7.

2 SQL también incluye el concepto de grupo (cluster) de catálogos dentro de un entorno, pero no está claro si se requieren muchos nive­les de anidamiento en la mayoría de las aplicaciones.

http://libreria-universitaria.blogspot.com

Page 4: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

206 Capítulo 8 SQL-99: definición del esquema, restricciones, consultas y vistas

Figura 8.1. Sentencias de definición de datos CREATE TABLE para definir el esquema EMPRESA de la Figura 5.7.

CREATE TABLE EMPLEADO

( Nombre

Apellido1

Apellido2

Dni

FechaNac

Dirección

Sexo

Sueldo

SuperDni

Dno

VARCHAR(15) NOT NULL,

CHAR, VARCHAR(15) NOT NULL,

CHAR(9) NOT NULL,

DATE, VARCHAR(30),

CHAR, DECIMAL(10,2),

CHAR(9), INT NOT NULL,

PRIMARY KEY (Dni), FOREIGN KEY(SuperDni) REFERENCES EMPLEADO(Dni),

FOREIGN KEY(Dno) REFERENCES DEPARTAMENTO(NúmeroDpto»;

CREATE TABLE DEPARTAMENTO ( NombreDpto VARCHAR(15) NOT NULL,

NúmeroDpto INT

DniDirector CHAR(9)

FechalngresoDírector DATE,

PRIMARY KEY(NúmeroDpto),

UNIQUE(NombreDpto ),

NOT NULL,

NOT NULL,

FOREIGN KEY(DniDirector) REFERENCES EMPLEADO(Dni) );

CREATE TABLE LOCALlZACIONES_DPTO ( NúmeroDpto INT NOT NULL,

UbicaciónDpto VARCHAR(15) NOT NULL,

PRIMARY KEY(NúmeroDpto, UbicaciónDpto), FOREIGN KEY(NúmeroDpto) REFERENCES DEPARTAMENTO(NúmeroDpto) );

CREATE TABLE PROYECTO ( NombreProyecto VARCHAR(15) NOT NULL,

NumProyecto INT NOT NULL,

Ubicación Proyecto VARCHAR(15),

NumDptoProyecto INT NOT NULL,

PRIMARY KEY(NumProyecto),

UNIQUE(NombreProyecto ), FOREIGN KEY(NumDptoProyecto) REFERENCES DEPARTAMENTO(NúmeroDpto) );

CREATE TABLE TRABAJA_EN

( DniEmpleado CHAR(9)

NumProy INT

Horas DECIMAL(3,1)

PRIMARY KEY(DniEmpleado, NumProy),

NOT NULL,

NOT NULL,

NOT NULL,

FOREIGN KEY(DniEmpleado)REFERENCES EMPLEADO(Dní),

FOREIGN KEY(NumProy) REFERENCES PROYECTO(NumProyecto) );

CREATE TABLE SUBORDINADO

( DniEmpleado CHAR(9) NOT NULL,

http://libreria-universitaria.blogspot.com

Page 5: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

8.1 Definición de datos y tipos de datos de SQL 207

Figura 8.1. (Continuación).

NombSubordinado VARCHAR(15) NOT NULL, Sexo CHAR, FechaNac DATE, Relación VARCHAR(8),

PRIMARY KEY(DniEmpleado, NombSubordinado), FOREIGN KEY(DniEmpleado) REFERENCES EMPLEADO(Dni));

Normalmente, el esquema SQL en el que se declaran las relaciones se especifica implícitamente en el entor­no en el que se ejecuta la sentencia CREATE TABLE. De forma alternativa, podemos adjuntar explícitamente el nombre del esquema al nombre de la relación, separándolos con un punto. Por ejemplo, al escribir

CREATE TABLE EMPRESA. EMPLEADO ...

en lugar de

CREATE TABLE EMPLEADO ...

como en la Figura 8.1, podemos conseguir explícitamente (y no implícitamente) que la tabla EMPLEADO forme parte del esquema EMPRESA.

Las relaciones declaradas mediante sentencias CREATE TABLE se denominan tablas base (o relaciones base); esto significa que el DBMS crea y almacena como un fichero la relación y sus tuplas. Las relaciones base se distinguen de las relaciones virtuales, que se crean con CREATE VIEW (consulte la Sección 8.8), en que pue­den o no corresponder a un fichero fisico real. En SQL, los atributos de una tabla base están considerados como ordenados en la secuencia en que se especificaron en la setencia CREATE TABLE. No obstante, no se considera que las filas (tuplas) estén ordenadas dentro de una relación.

En la Figura 8.1 hay algunas claves externas (foreign keys) que pueden provocar errores porque o bien se espe­cifican a través de referencias circulares, o porque se refieren a una tabla que todavía no se ha creado. Por ejemplo, laforeign key SuperDni de la tabla EMPLEADO es una referencia cruzada porque se refiere a la pro­pia tabla. Laforeign key Dno de la tabla EMPLEADO se refiere a la tabla DEPARTAMENTO, que todavía no se ha creado. Para tratar con este tipo de problema, estas restricciones pueden omitirse de la sentencia CREATE TABLE inicial, y añadirse más tarde con la sentencia ALTER TABLE (consulte la Sección 8.3.2).

8.1.3 Tipos de datos y dominios en SQl

Los tipos de datos básicos disponibles para los atributos son numérico, cadena de caracteres, cadena de bits, booleano, fecha y hora.

• El tipo de datos numéricos incluye los números enteros de varios tamaños (lNTEGER o INT, Y SMA­LLlNT) así como los números en coma flotante (reales) de distintas precisiones (FLOAT o REAL, Y DOUBLE PRECISION). Los números se pueden declarar utilizando DECIMAL(i,j) [o DEC(i,j) o NUME­RIC(i,j)], donde i, la precisión, es el número total de dígitos decimales y j, la escala, es el número de dígitos después del punto decimal. El valor predeterminado para la escala es cero, mientras que la pre­cisión predeterminada se define en la implementación .

• El tipo de datos cadena de caracteres puede ser de longitud fija [CHAR(U) o CHARACTER(n), donde n es la cantidad de caracteres] o de longitud variable [VARCHAR(n) oCHAR VARYING(n) o CHARAC­TER VARYING(n), donde 11 es la cantidad máxima de caracteres]. Al especificar un valor de cadena lite­ral, se coloca entre comillas simples (apóstrofes) y distingue entre minúsculas y mayúsculas.3 En el

3 No es el caso con las palabras clave de SQL, como CREATE oCHAR. SQL no hace distinción entre mayúsculas y minúsculas con ellas, de modo que trata todas las letras por igual, sean mayúsculas o minúsculas.

http://libreria-universitaria.blogspot.com

Page 6: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

208 Capítulo 8 SQL-99: definición del esquema, restricciones, consultas y vistas

caso de las cadenas de longitud fija, las cadenas más cortas se rellenan con caractereres en blanco por la derecha. Por ejemplo, si el valor 'Pérez' corresponde a un atributo de tipo CHAR(10), se rellena con cinco caracteres en blanco para convertirse en 'Pérez " si es necesario. Los blancos de relleno nor­malmente se ignoran cuando se comparan cadenas. En las comparaciones, las cadenas se consideran ordenadas alfabéticamente (o lexicográficamente); si una cadena cad] aparece antes que otra cadena cad2 en orden alfabético, entonces se considera que cad] es menor que cad2.4 También existe un ope­rador de concatenación representado por 11 (doble barra vertical) que pelmite concatenar dos cadenas en SQL. Por ejemplo, 'abc' 11 'XYZ' da como resultado una sola cadena, 'abcXYZ'. En SQL-99 hay otro tipo de datos denominado CHARACTER LARGE OBJECT o CLOB, destinado a especificar colum­nas que tienen valores de texto más largos, como los documentos.

11 El tipo de datos cadena de bits es de longitud fija n [BIT(I1)] o de longitud variable [BIT VARYING(ll)], donde 11 es la cantidad máxima de bits. El valor predeterminado para 11, que es la longitud de una cade­na de caracteres o de una cadena de bits, es l. Las cadenas de bits literales se escriben entre comillas simples pero precedidas por una B para distinguirlas de las cadenas de caracteres; por ejemplo, B'lOlOl '.5 En SQL-99 existe otro tipo de datos denominado BINARY LARGE OBJECT o BLOB desti­nado a especificar las columnas que tienen valores binarios más grandes, como las imágenes.

11 Un tipo de datos booleano tiene los valores tradicionales TRUE o FALSE. En SQL, debido a la presen­cia de los valores NULL, se utiliza una lógica de tres valores, que permite un tercer valor: UNKNOWN. En la Sección 8.5.1 explicaremos la necesidad de UNKNOWN y de la lógica de tres valores.

11 En SQL2 se añadieron dos nuevos tipos de datos, fecha y hora. El tipo de datos DATE tiene diez posi­ciones y sus componentes son AÑO, MES Y DíA según la formaAAAA-MM-DD. El tipo de datos TIME tiene al menos ocho posiciones, con los componentes HORAS, MINUTOS Y SEGUNDOS en la forma HH:MM:SS. La implementación de SQL sólo debe permitir las fechas y las horas válidas. La compa­ración < (menor que) se puede utilizar con fechas y horas (una fecha anterior se considera que es más pequeña que una fecha posterior, y lo mismo pasa con las horas). Los valores literales se representan mediante cadenas entre comillas simples precedidas por la palabra clave DATE o TIME; por ejemplo, DATE '2002-09-27' o TIME '09:12:47'. Además, un tipo de datos TIME(i), especifica i + 1 posiciones adicionales para TIME (una posición para un carácter separador adicional, e i posiciones para especifi­car las fracciones decimales de un segundo). Un tipo de datos TIME WITH TIME ZONE incluye seis posiciones adicionales para especificar el desplazamiento respecto a la zona horaria universal estándar, y que puede variar desde +13:00 a -12:59 en unidades de HORAS:MINUTOS. Si no se incluye WITH TIME ZONE, el valor predeterminado es la zona horaria local para la sesión de SQL.

11 Un tipo de datos marca de tiempo (TIMESTAMP) incluye los campos DATE y TIME, más un mínimo de seis posiciones para las fracciones decimales de segundos y un calificador WITH TIME ZONE opcio­nal. Los valores literales se representan como cadenas entre comillas simples precedidas por la pala­bra clave TIMESTAMP, con un espacio en blanco entre la fecha y la hora; por ejemplo, TIMESTAMP '2002-09-2709:12:47648302'.

11 Otro tipo de datos relacionado con DATE, TIME Y TIMESTAMP es INTERVAL, que permite especificar un intervalo (un valor relativo que puede utilizarse para incrementar o reducir el valor absoluto de una fecha, una hora o una marca de tiempo). Los intervalos están cualificados para ser intervalos AÑO/MES o intervalos DíA/HORA.

11 El formato de DATE, TIME Y TIMESTAMP se puede considerar como un tipo especial de cadena. Por tanto, se pueden utilizar normalmente en comparaciones de cadena si se convierten en las cadenas equivalentes.

4 En el caso de caracteres no alfabéticos hay un orden definido.

s Las cadenas de bits cuya longitud es un múltiplo de 4 se pueden especificar en notación hexadecimal, donde la cadena literal va prece­dida por una X y cada carácter hexadecimal representa 4 bits.

http://libreria-universitaria.blogspot.com

Page 7: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

s

s

s

o

r s

8.2 Especificación de restricciones en SQL

Es posible especificar directamente el tipo de datos de cada atributo, como en la Figura 8.1; alternativamen­te, se puede declarar un dominio, y el nombre del dominio se puede utilizar con la especificación del atribu­to. Esto hace más fácil cambiar el tipo de datos de un dominio que es utilizado por numerosos atributos de un esquema, y mejorar la legibilidad de este último. Por ejemplo, podemos crear un dominio TIPO_DNI con la siguiente sentencia:

CREATE OOMAIN TIPO_DNI AS CHAR(9);

En la Figura 8.1 podemos utilizar TIPO_DNI en lugar de CHAR(9) para los atributos Dni y SuperDni de Empleado, DniDirector de Departamento, DniEmpleado de TRABAJA_EN y DniEmpleado de SUBORDINA­DO. Un dominio también puede tener una especificación predeterminada opcional a través de una cláusula DEFAULT, como explicamos más adelante para los atributos. Los dominios no están disponibles en muchas implementaciones de SQL.

8.2 Especificación de restricciones en Sal Esta sección describe las restricciones básicas que se pueden especificar en SQL como parte de la creación de una tabla. Entre ellas podemos citar las restricciones de clave y de integridad referencial, así como las restric­ciones en los dominios de atributo y NULLs y en las tuplas individuales dentro de una relación. En la Sección 8.7 explicaremos la especificación de las restricciones más generales, denominadas aserciones.

8.2.1 Especificación de restricciones de atributo y valores predeter­minados de atributo

Como SQL permite NULL como valor de atributo, es posible especificar una restricción NOT NULL si no se permite NULL para un atributo en particular. Esto siempre se especifica implícitamente para los atributos que forman parte de la clave principal de cada relación, pero puede especificarse para cualquier otro atributo para cuyo valor se exige que no sea NULL (véase la Figura 8.1).

También es posible definir un valorpredeterll1inado para un atributo añadiendo la cláusula OEFAULT <valor> a su definición. El valor predeterminado se incluye en cualquier tupla nueva si no se proporciona un valor explícito para ese atributo. La Figura 8.2 ilustra un ejemplo de cómo especificar un director predeteminado para un departamento nuevo y un departamento predeterminado para un empleado nuevo. Si no se especifica una cláusula predeterminada, el valor predeterminado es NULL para los atributos que no tienen la restricción NOT NULL.

Otro tipo de restricción puede ser restringir los valores de atributo o dominio con la cláusula CHECK a con­tinuación de la definición de un atributo o dominio.6 Por ejemplo, suponga que los números de departamen­to están restringidos a número enteros entre 1 y 20; entonces, podemos cambiar la declaración de atributo de NumeroDpto en la tabla DEPARTAMENTO (véase la Figura 8.1) a lo siguiente:

NumeroDpto INT NOT NULL CHECK (NumeroDpto > O ANO NumeroDpto < 21);

La cláusula CHECK también se puede utilizar en combinación con la sentencia CREATE DOMAIN. Por ejem­plo, podemos escribir la siguiente sentencia:

CREATE OOMAIN NUM_D AS INTEGER CHECK

(NUM_D > O ANO NUM_D < 21);

6La cláusula CHECK también se puede utilizar con otros fines, como veremos.

I 209

1

http://libreria-universitaria.blogspot.com

Page 8: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

210 Capítulo 8 SQL-99: definición del esquema, restricciones, consultas y vistas

Figura 8.2. Ejemplo de cómo especificar en SQL los valores de atributo predeterminados y las acciones de activación de la integridad referencial.

CREATE TABLE EMPLEADO

( ... Dno INT NOT NULL DEFAULT 1,

CONSTRAINT EMPPK

PRIMARY KEY(Dni),

CONSTRAINT SUPERFKEMP FOREIGN KEY(SuperDni) REFERENCES EMPLEADO(Dni)

ON DELETE SET NULL ON UPDATE CASCADE

CONSTRAINT EMPDEPTFK FOREIGN KEY(Dno) REFERENCES DEPARTAMENTO(NumeroDpto)

ON DELETE SET DEFAUL T ON UPDATE CASCADE );

CREATE TABLE DEPARTAMENTO

( ... , DniDirector CHAR(9)

CONSTRAINT DEPTPK PRIMARY KEY(NumeroDpto),

CONSTRAINT DEPTSK

U NIQUE(NombreDpto),

CONSTRAINT DEPTMGRFK

NOT NULL DEFAULT '888665555',

FOREIGN KEY(DniDirector) REFERENCES EMPLEADO(Dni)

ON DELETE SET DEFAULT ON UPDATE CASCADE );

CREATE TABLE LOCALIZACIONES_OPTO

( ... , PRIMARY KEY(NumeroDpto, Ubicación Opto), FOREIGN KEY(NumeroDpto) REFERENCES DEPARTAMENTO(NúmeroDpto)

ON DELETE CASCADE ON UPDATE CASCADE );

Podemos utilizar entonces el dominio NUM_D creado como tipo de atributo para todos los atributos que se refieran a los números de departamento de la Figura 8.1, como NumeroDpto de Departamento, NumDptoProyecto de PROYECTO, Dno de EMPLEADO, etcétera.

8.2.2 Especificación de las restricciones de clave y de integridad referencial

Como las restricciones de clave e integridad referencial son muy importantes, hay cláusulas especiales para la sentencia CREATE TABLE. En la Figura 8.1 se muestran algunos ejemplos para ilustrar la especificación de claves y la integridad referenciaI.7 La cláusula PRIMARY KEY especifica uno o más atributos que constituyen la clave principal de una relación. Si una clave principal sólo tiene un atributo, la cláusula puede seguir al atri­buto directamente. Por ejemplo, la clave principal de DEPARTAMENTO se puede especificar como sigue (en lugar de como se muestra en la Figura 8.1):

NumeroDpto INT PRIMARY KEY;

7 Las restricciones de clave y de integridad referencial no se incluían en las versiones anteriores de SQL. En algunas de esas implemen­taciones, las claves se especificaban implícitamente en el nivel interno mediante el comando CREATE INDEX.

http://libreria-universitaria.blogspot.com

Page 9: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

8.2 Especificación de restricciones en SQL 211

La cláusula UNIQUE especifica claves (secundarias) alternativas, como se ilustraba en la declaración de las tablas DEPARTAMENTO y PROYECTO de la Figura 8.1.

La integridad referencial se especifica mediante la cláusula FOREIGN KEY (véase la Figura 8.1). Como se explicó en la Sección 5.2.4, una restricción de integridad referencial se puede violar cuando se insertan o eli­minan tuplas o cuando se modifica el valor de un atributo de laforeign key o de la clave principal. La acción predeterminada que SQL toma en caso de una violación de la integridad es rechazar la operación de actuali­zación que provocaría tal violación. Sin embargo, el diseñador del esquema puede especificar una acción alternativa si se viola la integridad referencial añadiendo una cláusula de acción de activación referencial a cualquier restricción deforeign key. Las opciones son SET NULL, CASCADE y SET DEFAULT. Una opción debe cualificarse con ON DELETE u ON UPDATE. Ilustramos esto con los ejemplos de la Figura 8.2. Aquí, el diseñador de la base de datos eligió SET NULL ON DELETE Y CASCADE ON UPDATE para laforeign key SuperDni de EMPLEADO. Esto significa que si se elimina la tupla de un empleado supervisor, el valor de SuperDni se establece automáticamente a NULL en todas las tuplas de empleado que hacían referencia a la tupla de empleado borrada. Por el contrario, si se actualiza el valor Dni de un empleado supervisor (por ejem­plo, porque se introdujo incorrectamente), entonces el valor nuevo se actualiza en cascada para el SuperDni de todas las tuplas de empleado que hacen referencia a la tupla de empleado actualizada.8

En general, la acción tomada por el DBMS para SET NULL o SET DEFAULT es la misma tanto para ON DELE­TE como para ON UPDATE: el valor de los atributos de referencia afectados se cambia a NULL para SET NULL y al valor predeterminado especificado para SET DEFAUL T. La acción para CASCAD E ON DELETE es elimi­nar todas las tuplas referenciadas, mientras que la acción para CASCAD E ON UPDATE es cambiar el valor de laforeign key por el valor de la clave principal (nueva) actualizada en todas las tuplas referenciadas. Es res­ponsabilidad del diseñador de la base de datos elegir la acción apropiada y especificarla en el esquema de la base de datos. Como regla general, la opción CASCADE es adecuada para las relaciones "de relación" (con­sulte la Sección 7.1), como TRABAJA_EN; para las relaciones que representan atributos multivalor, como LOCALlZACIONES_DPTO; y para las relaciones que representan tipos de entidad débiles, como SUBORDI­NADO.

8.2.3 Asignación de nombres a las restricciones

La Figura 8.2 también ilustra cómo puede asignarse un nombre de restricción a una restricción, con la pala­bra clave CONSTRAINT. Los nombres de todas las restricciones dentro de un esquema particular deben ser únicos. El nombre de una restricción se utiliza para identificar una restricción particular en caso de que la res­tricción tenga que eliminarse más tarde y sustituirse por otra restricción, como se explica en la Sección 8.3. La asignación de nombres a las restricciones es opcional.

8.2.4 Especificación de restricciones en las tuplas utilizando CHECK

Además de las restricciones de clave y de integridad referencial, que se especifican mediante palabras claves especiales, se pueden indicar otras restricciones de tabla mediante cláusulas CHECK adicionales al final de una sentencia CREATE TABLE. Estas restricciones se pueden denominar basadas en tuplas porque se apli­can individualmente a cada tupla y se comprueban siempre que se inserta o modifica una tupla. Por ejemplo, suponga que la tabla DEPARTAMENTO de la Figura 8.1 tiene un atributo adicional FechaCreaciónDpto, que almacena la fecha en que se creó el departamento. Después, podríamos añadir la siguiente cláusula CHECK al final de la sentencia CREATE TABLE para la tabla DEPARTAMENTO para garantizar que la fecha de inicio de un director es posterior a la fecha de creación del departamento.

8 Laforeigl1 key SuperDni de la tabla EMPLEADO es una referencia circular y, por tanto, es posible que tenga que añadirse más tarde como una restricción con nombre utilizando la sentencia ALTER TABLE, como explicamos al final de la Sección 8.1.2.

http://libreria-universitaria.blogspot.com

Page 10: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

212 Capítulo 8 SQL-99: definición del esquema, restricciones, consultas y vistas

CHECK (FechaCreaciónDpto <= FechalngresoDirector);

La cláusula CHECK también se puede utilizar para especificar restricciones más generales utilizando la sen­tencia CREATE ASSERTION de SQL. Lo explicamos en la Sección 8.7 porque requiere toda la potencia de las consultas, que se explican en las Secciones 8.4 y 8.5.

8.3 Sentencias de SQl para cambiar el esquema En esta sección ofrecemos una panorámica de los comandos de evolución del esquema de SQL, que se pue­den utilizar para alterar un esquema añadiendo o eliminando tablas, atributos, restricciones y otros elementos del esquema.

8.3.1 Comando DROP

El comando DROP se puede utilizar para eliminar los elementos con nombre del esquema, como tablas, domi­nios o restricciones. También puede eliminar un esquema. Por ejemplo, si ya no se necesita un esquema ente­ro, se puede utilizar el comando DROP SCHEMA. Hay dos opciones de comportamiento para estas elimina­ciones: CASCADE y RESTRICT. Por ejemplo, para eliminar el esquema de la base de datos EMPRESA y todas sus tablas, dominios y otros elementos, se utiliza la opción CASCADE de este modo:

DROP SCHEMA EMPRESA CASCADE;

Si se opta por RESTRICT en lugar de CASCAD E, el esquema sólo se elimina si no contiene elementos; en caso contrario, el comando DROP no se ejecutará.

Si ya no se necesita una relación base dentro de un esquema, la relación y su definición se pueden eliminar con el comando DROP TABLE. Por ejemplo, si ya no queremos hacer un seguimiento de los subordinados de los empleados en la base de datos EMPRESA de la Figura 8.1, podemos librarnos de la relación SUBORDI­NADO ejecutando el siguiente comando:

DROP TABLE Sl,JBORDINADO CASCADE;

Si se elige la opción RESTRICT en lugar de CASCADE, la tabla sólo se elimina si no se hace referencia a ella en ninguna restricción (por ejemplo, desde las definiciones de foreign key de otra relación) o vista (consulte la Sección 8.8). Con la opción CASCADE, todas estas restricciones y vistas que hacen referencia a la tabla se eliminan automáticamente del esquema, junto con la propia tabla.

E! comando DROP TABLE no sólo elimina todos los registros de la tabla, sino también la definición de la tabla del catálogo. Si se desea eliminar los registros, pero manteniendo la definición de la tabla para un uso futuro, entonces hay que utilizar el comando DELETE (consulte la Sección 8.6.2) en lugar de DROP TABLE.

E! comando DROP también se puede utilizar para eliminar otros tipos de elementos con nombre del esquema, como las restricciones o los dominios.

8.3.2 Comando ALTER

La definición de una tabla base o de otros elementos con nombre del esquema se puede cambiar con el coman­do ALTER. Para las tablas base, las posibles acciones de alteración incluyen la adición o eliminación de una columna (atributo), el cambio de la definición de una columna, y la adición o eliminación de restricciones. Por ejemplo, para añadir a las relaciones base EMPLEADO del esquema EMPRESA un atributo que sirva para hacer un seguimiento de los trabajos de los empleados, podemos usar este comando:

ALTER TABLE EMPRESA.EMPLEADO ADD COLUMN Trabajo VARCHAR(12);

http://libreria-universitaria.blogspot.com

Page 11: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

8.4 Consultas básicas en SQL 213

Todavía debemos introducir un valor para el atributo nuevo, Trabajo, por cada tupla EMPLEADO. Lo pode­mos hacer especificando una cláusula predeterminada o utilizando el comando UPDATE (consulte la Sección 8.6). Si no especificamos una cláusula predeterminada, el atributo nuevo tendrá NULL en todas las tuplas de la relación inmediatamente después de haberse ejecutado el comando; por tanto, la restricción NOT NULL no está permitida en este caso.

Para eliminar una columna, debemos elegir CASCAD E o RESTRICT como comportamiento de eliminación. En el caso de CASCADE, todas las restricciones y vistas que hacen referencia a la columna se eliminarán auto­máticamente del esquema, junto con la columna. Si optamos por RESTRICT, el comando es satisfactorio sólo si no hay vistas o restricciones (u otros elementos) que hagan referencia a la columna. Por ejemplo, el siguien­te comando elimina el atributo Dirección de la tabla base EMPLEADO:

ALTER TABLE EMPRESA.EMPLEADO DROP COLUMN Dirección CASCADE;

También es posible alterar la definición de una columna eliminando una cláusula predeterminada existente o definiendo una nueva cláusula predeterminada. Los siguientes ejemplos sirven como explicación:

ALTER TABLE EMPRESA.DEPARTAMENTO ALTER COLUMN DniDirector DROP DEFAULT;

ALTER TABLE EMPRESA.DEPARTAMENTO ALTER COLUMN DniDirector SET DEFAULT '333445555';

También se pueden cambiar las restricciones especificadas en una tabla añadiendo o eliminando una res­tricción. Para ser eliminada, la restricción debe contar con un nombre asignado durante su definición. Por ejemplo, para eliminar la restricción SUPERFKEMP de la relación EMPLEADO (véase la Figura 8.2) escri­bimos:

ALTER TABLE EMPRESA.EMPLEADO DROP CONSTRAINT SUPERFKEMP CASCADE;

Una vez hecho esto, podemos redefinir una restricción de sustitución añadiendo, si es necesario, una restric­ción nueva a la relación. Esto se consigue utilizando la palabra clave ADD en la sentencia ALTER TABLE seguida por la restricción nueva, que puede o no tener nombre, y que puede ser de cualquiera de los tipos de restricción de tabla explicados.

Las subsecciones anteriores han ofrecido una panorámica de los comandos de evolución del esquema de SQL. Hay otros muchos detalles y opciones, por lo que instamos al lector a consultar los documentos citados en la sección "Bibliografía seleccionada", al final de este capítulo. Las dos secciones siguientes explican las capa­cidades de consulta de SQL.

8.4 Consultas básicas en Sal SQL tiene una sentencia básica para recuperar información de una base de datos: SELECT. Esta sentencia no tiene relación con la operación SELECCiÓN del álgebra relacional, que explicamos en el Capítulo 6. En SQL hay muchas opciones y versiones de la sentencia SELECT, por lo que introduciremos sus características gra­dualmente. Utilizaremos las consultas de ejemplo especificadas en el esquema de la Figura 5.5 y nos referi­remos al estado de la base de datos de la Figura 5.6 para mostrar los resultados de algunas consultas.

Antes de continuar, debemos hacer una distinción importante entre SQL y el modelo relacional formal expli­cado en el Capítulo 5. SQL permite que una tabla (relación) tenga dos o más tuplas idénticas en todos sus valo­res de atributo. Por tanto, en general, una tabla SQL no es un conjunto de tuplas, porque un conjunto no per­mite dos miembros idénticos; en su lugar, es un multiconjunto (a veces conocido como bolsa) de tuplas. Algunas relaciones SQL están restringidas a ser conjuntos porque se ha declarado una restricción de clave o porque se ha utilizado la opción DISTINCT con la sentencia SELECT (se explica más adelante en esta sec­ción). Debemos ser conscientes de esta distinción durante la explicación de los ejemplos.

http://libreria-universitaria.blogspot.com

Page 12: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

214 Capitulo 8 SQL-99: definición del esquema, restricciones, consultas y vistas

8.4.1 Estructura SElECT-FROM-WHERE de las consultas básicas de Sal

Las consultas en SQL pueden ser muy complejas. Empezaremos con las sencillas e iremos progresando, paso a paso, hasta las más complejas. La forma básica de la sentencia SELECT, denominada en ocasiones mapea­do o bloque select-from-where, está formada por las cláusulas SELECT, FROM y WHERE y tiene la siguien­te forma: 9

donde:

SELECT FROM WHERE

<lista de atributos> <lista de tablas> <condición>;

11 <lista de atributos> es una lista de los atributos cuyos valores serán recuperados por la consulta.

11 <lista de tablas> es una lista de las relaciones necesarias para procesar la consulta.

11 <condición> es una expresión condicional (booleana) que identifica las tuplas que la consulta recupe­rará.

En SQL, los operadores básicos para comparar lógicamente los valores de los atributos entre sí y con cons­tantes literales son =, <, <=, >, >= y <>, que se corresponden con los operadores =, <, ?, >, ? y ? del álgebra relacional, respectivamente, y con los operadores =, <, <=, >, >= y != del lenguaje de programación C/C++. La diferencia principal es el operador no igual. SQL tiene muchos operadores de comparación adicionales que iremos presentando a medida que los necesitemos.

Vamos a ilustrar la sentencia SELECT básica con algunas consultas de ejemplo. Las consultas están etiqueta­das con los mismos números que en el Capítulo 6.

Consulta O. Recuperar la fecha de nacimiento y la dirección del empleado (o empleados) cuyo nom­bre sea José Pérez Pérez,

CO: SELECT

FROM

WHERE

FechaNac, Dirección EMPLEADO Nombre='José' ANO Apellid01 ='Pérez' ANO Apellid02='Pérez';

Esta consulta sólo implica a la relación EMPLEADO que se especifica con la cláusula FROM. La consulta selecciona las tuplas de EMPLEADO que satisfacen la condición de la cláusula WHERE; después,pl'Oyecta el resultado en los atributos FechaNac y Dirección enumerados en la cláusula SELECT. CO es parecida a la siguiente expresión escrita en álgebra relacional, excepto que /10 se eliminan los duplicados, si los hay:

1T FechaNac,Dirección( (J' Nombre='José' AND Apellido1='Pérez' AND Apellido2='Pérez' (EMPLEADO»

Por tanto, una consulta SQL sencilla con una sola relación en la cláusula FROM es similar a una pareja de operaciones SELECCiÓN-PROYECTO del álgebra relacional. La cláusula SELECT de SQL especifica los atributos de pmyecció/1 y la cláusula WHERE especifica la condición de selección, La única diferencia es que en la consulta SQL podemos obtener tuplas duplicadas en el resultado porque no se implementa la restricción de que una relación es un conjunto. La Figura 8,3(a) muestra el resultado de la consulta CO sobre la base de datos de la Figura 5,6,

La consulta CO también es parecida a la siguiente expresión de cálculo relacional de tuplas, excepto que los duplicados, si los hay, tampoco serían eliminados en la consulta SQL:

CO: { l.FechaNac, l.Dirección I EMPLEADO(t) ANO l.Nombre='José' ANO l.Apellid01 ='Pérez' ANO l.Apellid02='Pérez' }

9 Las cláusulas SELECT y FROM son necesarias en todas las consultas SQL. WHERE es opcional (consulte la Sección 8.4.3),

http://libreria-universitaria.blogspot.com

Page 13: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

8.4 Consultas básicas en SOL 215

Figura 8.3. Resultado de las consultas SQL aplicadas sobre el estado de la base de datos EMPRESA de la Figura 5.6. (a) CO. (b) C1. (c) C2. (d) C8. (e) C9. (f) C10. (g) C1C.

(a) FechaNac

01-09-1965

(e) NumProyecto

10

30

(d) E.Nombre

José

Alberto

Alicia

Juana

Fernando

Aurora

Luis

(e) E.Nombre

123456789

333445555

999887777

987654321

666884444

453453453

987987987

888665555

(g)

Dirección

Eloy 1, 98

NumDgtoProyeclo

4

4

Ageflido1

Sainz

Sainz

(b) Nombre

José

Alberto

Fernando

Aurora

Dirección

Cerquillas, 67

Cerquillas, 67

E.Agellído1 S.Nombre S.Agelligo1 (f)

Pérez Alberto Campos

Campos Eduardo Ochoa

Jiménez Juana Sainz

Sainz Eduardo Ochoa

Ojeda Alberto Campos

Oliva Alberto Campos

Pajares Juana Sainz

Nombre Agellido1 Agellido2 Dn! FechaNac Dirección

José Pérez Pérez 123456789 01-09-1965 Eloy 1, 98

Alberto Campos Sastre 333445555 08-12-1955 Avda. Ríos, 9

Fernando Ojeda Ordóñez 666884444 15-09-1962 Portillo, s/n

Aurora Oliva Avezuela 453453453 31-07-1972 Antón, 6

8gellido1

Pérez

Campos

Ojeda

Oliva

FechaNac

20-06-1941

20-06-1941

Dni

123456789

333445555

999887777

987654321

666884444

453453453

987987987

888665555

123456789

333445555

999887777

987654321

666884444

453453453

987987987

888665555

123456789

333445555

999887777

987654321

666884444

453453453

987987987

888665555

Sexo Sueldo

H 30000

H 40000

H 38000

M 25000

Dirección

Eloy 1,98

Avda. Ríos, 9

Portillo, s/n

Antón, 6

NombreDgto

Investigación

Investigación

Investigación

Investigación

Investigación

Investigación

Investigación

Investigación

Administración

Administración

Administración

Administración

Administración

Administración

Administración

Administración

Sede central

Sede central

Sede central

Sede central

Sede central

Sede central

Sede central

Sede central

SuperDn! Dno

333445555 5

888665555 5

333445555 5

333445555 5

http://libreria-universitaria.blogspot.com

Page 14: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

216 Capítulo 8 SQL-99: definición del esquema, restricciones, consultas y vistas

Por tanto, podemos pensar en una variable de tupla implícita en la consulta SQL pasando por cada tupla de la tabla EMPLEADO y evaluando la condición de la cláusula WHERE. Sólo se seleccionan las tuplas que satis­facen la condición (es decir, las tuplas para las que la condición se evalúa como TRUE después de sustituir sus correspondientes valores de atributo).

Consulta 1. Recuperar el nombre y la dirección de todos los empleados que trabajan en el departa­mento 'Investigación'.

C1: SELECT FROM

WHERE

Nombre, Apellido1, Dirección

EMPLEADO, DEPARTAMENTO NombreDpto='lnvestigación' ANO NumeroDpto=Dno;

La consulta el es parecida a una secuencia SELECCIÓN-PROYECCIÓN-CONCATENACIÓN de operaciones del álgebra relacional. Dichas consultas se denominan a veces consultas selección-proyección-concatena­ción. En la cláusula WHERE de el, la condición NombreDpto='lnvestigación' es una condición de selección y se corresponde con una operación SELECCiÓN del álgebra relacional. La condición NumeroDpto=Dno es una condición de concatenación, que corresponde a una condición CONCATENACiÓN del álgebra relacio­nal. El resultado de la consulta e 1 se muestra en la Figura 8.3(b). En general, en una consulta SQL sencilla puede especificarse cualquier cantidad de condiciones de selección y concatenación. El siguiente ejemplo es una consulta selección-proyección-concatenación con dos condiciones de concatenación.

Consulta 2. Por cada proyecto ubicado en 'Gijón', mostrar su número, el número del departamento que lo gestiona y el primer apellido, dirección y fecha de nacimiento del director del mismo.

C2: SELECT

FROM

WHERE

NumProyecto, NumDptoProyecto, Apellido1, Dirección, FechaNac

PROYECTO, DEPARTAMENTO, EMPLEADO

NumDptoProyecto=NumeroDpto ANO DniDirector=Dni ANO

UbicaciónProyecto='Gíjón';

La condición de concatenación NumDptoProyecto = NumeroDpto relaciona un proyecto con el departamento que lo controla, mientras que la condición de concatenación DniDirector=Dni relaciona el depmiamento de control con el empleado que lo administra. El resultado de la consulta e2 se muestra en la Figura 8.3(c).

8.4.2 Nombres de atributo ambiguos, alias y variables de tupla

En SQL el mismo nombre se puede utilizar para dos (o más) atributos, siempre y cuando los atributos se encuentren en relaciones diferentes. Si es el caso, y una consulta se refiere a dos o más atributos que tienen el mismo nombre, debemos calificar el nombre del atributo con el nombre de la relación a fin de evitar la ambigüedad. Esto se consigue colocando como prefijo el nombre de la relación al nombre del atributo, y sepa­rando los dos nombres con un punto. A modo de ilustración, suponga que en las Figuras 5.5 y 5.6, los atribu­tos Dno y Apellido1 de la relación EMPLEADO se llamaran NumeroDpto y Nombre, y que el atributo NombreDpto de DEPARTAMENTO también se llamara Nombre; entonces, para evitar la ambigüedad, la con­sulta el tendría que reformarse como aparece en la consulta elA. Hemos añadido un prefijo a los atributos Nombre y NumeroDpto para especificar a cuáles nos estamos refiriendo en realidad, ya que estos nombres de atributo se utilizan en dos relaciones:

C1A: SELECT FROM WHERE

Nombre, EMPLEADO. Nombre, Dirección

EMPLEADO, DEPARTAMENTO DEPARTAMENTO.Nombre='lnvestígación' ANO DEPARTAMENTO.NumeroDpto=EMPLEADO.NumeroDpto;

La ambigüedad también aparece en el caso de las consultas que se refieren dos veces a la misma relación, como en el siguiente ejemplo:

http://libreria-universitaria.blogspot.com

Page 15: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

8.4 Consultas básicas en SQL 217

Consulta 8. Por cada empleado, recuperar el nombre y el primer apellido del empleado, y el nombre y el primer apellido de su supervisor inmediato.

C8: SELECT

FROM

WHERE

E.Nombre, E.Apellid01, S.Nombre, S.Apellid01 EMPLEADO AS E, EMPLEADO AS S E.SuperDni=S.Dni;

En este caso, nos permite declarar nombres de relación alternativos, E y S, denominados alias o variables de tupla, para la relación EMPLEADO. Un alias puede seguir a la palabra clave AS, como se muestra en C8, o puede seguir directamente al nombre de la relación (por ejemplo, escribiendo EMPLEADO E, EMPLEADO S en la cláusula FROM de CS). También es posible renombrar los atributos de la relación dentro de la consulta SQL, asignándoles unos alias. Por ejemplo, si escribimos:

EMPLEADO AS E(Np, A1, A2, Dni, Fn, Dir, Sex, Sal, Sdni, Dno)

en la cláusula FROM, Np será el alias de Nombre, A 1 de Apellid01, A2 de Apellid02, etcétera.

En CS, podemos pensar que E y S son dos copias diferentes de la relación EMPLEADO; la primera, E, repre­senta a los empleados en el papel de supervisados; la segunda, S, representa a los empleados en el papel de supervisores. Ahora podemos concatenar las dos copias. Por supuesto, en la realidad sólo hay una relación EMPLEADO, y la condición de concatenación significa unir la relación consigo misma haciendo coincidir las tuplas que satisfagan la condición de concatenación E.SuperDni=S.Dni. Esto es un ejemplo de consulta recur­siva de un solo nivel, como explicamos en la Sección 6.4.2. En versiones anteriores de SQL, como en el álge­bra relacional, no era posible especificar una consulta recursiva general, con un número desconocido de nive­les, en una sola sentencia SQL. En SQL-99 se ha incorporado una estructura para especificar consultas recur­sivas, como se describe en el Capítulo 22.

El resultado de la consulta C8 se muestra en la Figura S.3( d). Siempre que se otorguen uno o más alias a una relación, podemos utilizar esos nombres para representar diferentes referencias a esa relación. Esto permite múltiples referencias a la misma relación dentro de una consulta. Si queremos, podemos utilizar este meca­nismo alias-denominación en cualquier consulta SQL para especificar en la cláusula WHERE variables de tupla para cada tabla, necesite o no la misma relación ser referenciada más de una vez. De hecho, esta prácti­ca es recomendable porque da lugar a consultas más fáciles de comprender. Por ejemplo, podríamos especi­ficar la consulta CIA como en CIB:

C1B: SELECT

FROM

WHERE

E.Nombre, E.NombreC, E.Dirección EMPLEADO E, DEPARTAMENTO O

D.Nombre='lnvestigación' ANO D.NumeroDpto=E.NumeroDpto;

Si especificamos variables de tupla para cada tabla de la cláusula WHERE, una consulta sección-proyección­concatenación en SQL se parece mucho a la correspondiente expresión de cálculo relacional de tuplas (excep­to por la eliminación de los duplicados). Por ejemplo, compare CIB con la siguiente expresión de cálculo rela­cional de tuplas sobre las tablas originales:

C1: {e.Nombre, e.Apellid01, e.Dirección I EMPLEADO(e) ANO (3d)

(DEPARTAMENTO(d) ANO d.NombreDpto='lnvestigación' ANO d.NumeroDpto=e.Dno)}

La principal diferencia (aparte de la sintaxis) es que en la consulta SQL el cuantificador existencial no se espe­cifica explícitamente.

8.4.3 Cláusula WHERE no especificada y uso del asterisco

Vamos a ver dos características más de SQL. La ausencia de una cláusula WHERE indica que no hay una con­dición en la selección de tuplas; por tanto, todas las tuplas de la relación especificada en la cláusula FROM

http://libreria-universitaria.blogspot.com

Page 16: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

218 Capítulo 8 SQL-99: definición del esquema, restricciones, consultas y vistas

se califican y seleccionan para la consulta resultante. Si en la cláusula FROM se especifica más de una rela­ción y no hay una cláusula WHERE, entonces se selecciona el PRODUCTO CRUZADO (todas las posibles combinaciones de tuplas) de esas relaciones. Por ejemplo, la Consulta 9 selecciona todos los DNls de EM­PLEADO (véase la Figura 8.3[e]), y la Consulta 10 selecciona todas las combinaciones de un Dni de EMPLEA­DO Y el NombreDpto de un DEPARTAMENTO (véase la Figura 8.3[fl)·

Consultas 9 y 10. Seleccione todos los Dni de EMPLEADO (C9) y todas las combinaciones de Dni de EMPLEADO y NombreDpto de DEPARTAMENTO (CIO) en la base de datos.

C9: SELECT FROM

C10: SELECT FROM

Dni EMPLEADO;

Dní, NombreDpto EMPLEADO, DEPARTAMENTO;

Es extremadamente importante especificar todas las selecciones y condiciones de concatenación en la cláusu­la WHERE; si se omite cualquiera de esas condiciones, pueden obtenerse relaciones incorrectas y muy gran­des. La C10 es parecida a una operación PRODUCTO CRUZADO seguida por una operación PROYECCiÓN en el álgebra relacional. Si especificamos todos los atributos de EMPLEADO y DEPARTAMENTO en C 1 0, obtenemos el PRODUCTO CRUZADO (excepto por la eliminación de duplicados, si los hay).

Para recuperar todos los valores de atributo de las tuplas seleccionadas, no tenemos que listar explícitamente los nombres de los atributos en SQL; podemos escribir un asterisco (*), que tiene el significado de todos los atributos. Por ejemplo, la consulta CIC recupera todos los valores de atributo de cualquier EMPLEADO que trabaje en el DEPARTAMENTO número 5 (véase la Figura 8.3[g]), la consulta CID recupera todos los atri­butos de un EMPLEADO y los atributos del DEPARTAMENTO en el que trabaja por cada empleado del depar­tamento 'Investigación', y C10A especifica el PRODUCTO CRUZADO de las relaciones EMPLEADO y

DEPARTAMENTO.

C1C: SELECT * FROM EMPLEADO WHERE Dno=5;

C10: SELECT * FROM EMPLEADO, DEPARTAMENTO WHERE NombreDpto='lnvestigación' ANO Dno=NumeroDpto;

C10A: SELECT * FROM EMPLEADO, DEPARTAMENTO;

8.4.4 Tablas como conjuntos en Sal

Como mencionamos anteriormente, SQL trata normalmente a una tabla no como un conjunto, sino como un multiconjunto; las tuplas duplicadas pueden aparecer más de una vez en una tabla, y en el resultado de una consulta. SQL no elimina automáticamente las tuplas duplicadas en los resultados de las consultas, por las

siguientes razones:

• La eliminación de duplicados es una operación muy costosa. Una forma de implementarla consiste en ordenar primero las tuplas y después eliminar los duplicados.

• El usuario puede querer ver las tuplas duplicadas en el resultado de una consulta.

• Cuando se aplica una función de agregación (consulte la Sección 8.5.7) a las tuplas, en la mayoría de los casos no queremos eliminar los duplicados.

http://libreria-universitaria.blogspot.com

Page 17: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

8.4 Consultas básicas en SQL 219

Figura 8.4. Resultados de distintas consultas SQL aplicadas sobre el estado de la base de datos EMPRESA de la Figura 5.6. (a) C11. (b) C11A. (e) C16. (d) C18.

(a) Sueldo (b)

Sueldo (e)

Nombre Apellido 1

30000 30000

40000 40000

25000 25000 (d) Nombre Apellido1 43000 43000 Eduardo Ochoa 38000 38000

25000 55000 25000

55000

Una tabla SQL con una clave está restringida a ser un conjunto, ya que el valor de la clave debe ser distinto en cada tupla. 10 Si queremos eliminar las tuplas duplicadas del resultado de una consulta SQL, utilizamos la palabra clave DISTINCT en la cláusula SELECT, lo que significa que sólo las tuplas distintas deben permane­cer en el resultado. En general, una consulta con SELECT DISTINCT elimina los duplicados, mientras que una consulta con SELECT ALL no lo hace. Especificar SELECT sin ALL ni DISTINCT (como en nuestros anterio­res ejemplos) es equivalente a SELECT ALL. Por ejemplo, CIl recupera el sueldo de los empleados; si varios empleados tienen el mismo sueldo, ese valor aparecerá varias veces en el resultado de la consulta (véase la Figura 8.4[a]). Si sólo estamos interesados en los valores de sueldo diferentes, será deseable que cada valor aparezca una sola vez, independientemente del número de empleados que ganen ese sueldo. Con la palabra clave DISTINCT como en CIIA, conseguimos lo mencionado (véase la Figura 8.4[b]).

Consulta 11. Recuperar el sueldo de todos los empleados (C 11) y todos los valores de sueldo que son distintos (C 11 A).

C11: SELECT FROM

C11A: SELECT FROM

ALL Sueldo EMPLEADO;

DISTINCT Sueldo EMPLEADO;

SQL ha incorporado directamente algunas de las operaciones del álgebra relacional: unión de conjuntos (UNION), diferencia de conjuntos (EXCEPT)ll e intersección de conjuntos (INTERSECT). Las relaciones resultantes de estas operaciones son conjuntos de tuplas; es decir, las tuplas duplicadas son eliminadas del resultado. Como estas operaciones con conjuntos sólo se aplican a las relaciones compatibles con la unión, debemos asegurarnos de que las dos relaciones sobre las que apliquemos la operación tengan los mismos atri­butos y que éstos aparezcan en el mismo orden en las dos relaciones. El siguiente ejemplo ilustra el uso de UNION.

Consulta 4. Crear una lista con el número de todos los proyectos en los que esté implicado un em­pleado cuyo primer apellido sea 'Pérez', sea un trabajador o sea director del depmiamento que contro­la el proyecto.

10 En general, no es necesario que una tabla SQL tenga una clave, aunque en la mayoría de los casos contarán con una.

11 En algunos sistemas, se utiliza la palabra clave MlNUS para la diferencia de conjuntos, en lugar de EXCEPT.

http://libreria-universitaria.blogspot.com

Page 18: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

220 Capítulo 8 SQL-99: definición del esquema, restricciones, consultas y vistas

C4: (SELECT OISTINCT NumProyecto FROM PROYECTO,DEPARTAMENTO,EMPLEADO

WHERE

UNION

NumDptoProyecto=NumeroDpto ANO DniDirector=Dni ANO Apellido1 ='Pérez' )

(SELECT OISTINCT NumProyecto FROM PROYECTO, TRABAJA_EN, EMPLEADO

WHERE NumProyecto=NumProy ANO DniEmpleado=Dni ANO Apellido1='Pérez' );

La primera consulta SELECT recupera los proyectos que implican a 'Pérez' como director del depatiamento encargado de controlar el proyecto, y la segunda recupera los proyectos en los que trabaja 'Pérez'. Si varios empleados tienen como primer apellido 'Pérez', se recuperará el nombre de los proyectos en los que cualquie­ra de ellos esté implicado. La aplicación de la operación UNION a las dos consultas SELECT proporciona el resultado deseado.

SQL también dispone de las operaciones multiconjunto correspondientes, que van seguidas por la palabra clave ALL (UNION ALL, EXCEPT ALL, INTERSECT ALL). Sus resultados son multiconjuntos (los duplicados no se eliminan). El comportamiento de estas operaciones se ilustra en los ejemplos de la Figura 8.5. Básicamente, cuando se aplican estas operaciones a cada tupla (sea duplicada o no), ésta se considera una tupla diferente.

8.4.5 Comparación de subcadenas y operadores aritméticos

En esta sección explicamos algunas características más de SQL. En primer lugar hablaremos de las condicio­nes de comparación de partes de una cadena de caracteres, mediante el operador de comparación LlKE. Esto se puede utilizar para la comparación de patrones. Las cadenas parciales se especifican mediante dos carac­teres reservados: % sustituye una cantidad arbitraria de caracteres (de cero o más caracteres), y el guión de subrayado U reemplaza un solo carácter. Por ejemplo, considere la siguiente consulta.

Consulta 12. Recuperar todos los empleados cuya dirección se encuentra en Madrid.

C12: SELECT

FROM WHERE

Nombre, Apellid01 EMPLEADO Dirección LlKE '%Madrid%';

Figura 8.5. Resultado de las operaciones de multiconjunto de SQL. (a) Dos tablas, R(A) y S(A). (b) R(A) UNION ALL S(A). (e) R(A) EXCEPT ALL S(A). (d) R(A) INTERSECT ALL S(A).

(a) R S (b) T (e) T

A A A

~ a1 a1 a1

a2 a2 a1 a3

a2 a4 a2

a3 a5 a2

a2 (d) T

a3

~ a4

a5 a3

http://libreria-universitaria.blogspot.com

Page 19: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

8.4 Consultas básicas en SQL 221

Para recuperar todos los empleados que hayan nacido en la década de 1950 podemos utilizar la Consulta 12A. Aquí, el '5' debe ser el noveno carácter de la cadena (de acuerdo con nuestro formato de fecha), por lo que utilizamos el valor ' ________ 5 _', en el que cada guión de subrayado sirve como marcador de un carácter.

Consulta 12A. Encontrar todos los empleados que hayan nacido durante la década de 1950.

C12A: SELECT Nombre, Apellido1

FROM EMPLEADO WHERE FechaNac LlKE ' ________ 5 _';

Si hay necesidad de utilizar el carácter % o el guión bajo como carácter literal en la cadena, hay que prece­derlo por un carácter de escape, que se especifica después de la cadena mediante la palabra clave ESCAPE. Por ejemplo, 'AB\ _CD\ %EF' ESCAPE '\ ' representa la cadena literal 'AB_CD%EF' porque se ha especifica­do el carácter \ como carácter de escape. Como carácter de escape se puede utilizar cualquier carácter que no se utilice en la cadena. Además, necesitamos una regla para especificar los apóstrofes o comillas simples (' ') en caso de tener que incluirlas en una cadena porque se utilicen para empezar o terminar cadenas. Si necesi­tamos un apóstrofe n, hay que representarlo como dos apóstrofes consecutivos (H), para que no sea interpre­tado como final de la cadena.

Otra característica permite utilizar la aritmética en las consultas. Los operadores aritméticos estándar para la suma (+), la diferencia (-), la multiplicación (*) y la división (/) se pueden aplicar a valores o atributos numéricos con dominios numéricos. Por ejemplo, suponga que queremos ver el efecto de subir un 10% el sueldo de todos los empleados que trabajan en el proyecto 'ProductoX'; podemos ejecutar la Consulta 13 para ver sus nuevos salarios. Este ejemplo también muestra cómo podemos renombrar un atributo en el resultado de la consulta utilizando AS en la cláusula SELECT.

Consulta 13. Mostrar los salarios aumentados un 10% de todos los empleados que trabajan en el pro­yecto 'ProductoX'.

C13: SELECT Nombre, Apellid01, 1. hSueldo AS SueldoAumentado FROM EMPLEADO, TRABAJA_EN, PROYECTO

WHERE Dni=DniEmpleado ANO NumProy=NumProyecto ANO

NombreProyecto='ProductoX';

En las cadenas es posible utilizar el operador de concatenación 11 para añadir dos valores de cadena. En el caso de fechas, horas, marcas de tiempo e intervalos, los operadores suponen incrementar (+) o decrementar (-) una fecha, una hora o una marca de tiempo según un intervalo. Además, un valor de intervalo es el resultado de la diferencia entre dos valores de fecha, hora o marca de tiempo. Otro operador de comparación que se puede utilizar es BETWEEN, que se ilustra en la Consulta 14.

Consulta 14. Recuperar todos los empleados del departamento 5 cuyo salario esté entre 30.000 y 40.000.

C14: SELECT * FROM EMPLEADO

WHERE (Sueldo BETWEEN 30000 ANO 40000) ANO Dno = 5;

La condición (Sueldo BETWEEN 30000 ANO 40000) de la C14 es equivalente a la condición ((Sueldo >= 30000) ANO (Sueldo <= 40000)).

8.4.6 Ordenación del resultado de una consulta

SQL permite ordenar las tuplas del resultado de una consulta por los valores de uno o más atributos, utilizan­do la cláusula ORDER BY. Es lo que se ilustra en la Consulta 15.

http://libreria-universitaria.blogspot.com

Page 20: Parte 1 de 2 - Elmasri - Capitulo 8 - SQL

222 Capítulo 8 SQL-99: definición del esquema, restricciones, consultas y vistas

Consulta 15. Recuperar una lista de empleados y de los proyectos en los que trabajan, ordenada por el depar­tamento. Dentro de cada departamento, ordenar alfabéticamente los empleados por su primer apellido y su nombre.

C15: SELECT FROM

NombreDpto, Apellid01, Nombre, NombreProyecto DEPARTAMENTO,EMPLEADO,TRABAJA_EN,PROYECTO

WHERE NumeroDpto=Dno AND Dni=DniEmpleado AND NumProy=NumProyecto ORDER BY NombreDpto, Apellid01, Nombre;

El orden predeterminado es el ascendente. Con la palabra clave DESC podemos ver el resultado ordenado des­cendentemente. La palabra clave ASC permite especificar explícitamente el orden ascendente. Por ejemplo, si deseamos el orden descendente para NombreDpto y el orden ascendente para Apellido 1 , Nombre, la cláusula ORDER BY de Cl5 se puede escribir de este modo:

ORDER BY NombreDpto DESC, Apellido1 ASC, Nombre ASC

8.5 Consultas SQl más complejas En la sección anterior describimos algunos tipos básicos de consultas SQL. Debido a la generalidad y la potencia expresiva del lenguaje, hay muchas otras características que penniten consultas más complejas. En esta sección explicaremos algunas de estas características.

8.5.1 Comparaciones con valores NULL y lógica de tres valores

SQL tiene varias reglas para tratar con los valores NULL. Si recuerda de la Sección 5.1.2, NULL se utiliza para representar la ausencia de un valor, aunque normalmente tiene una de tres interpretaciones diferentes: valor desconocido (existe, pero no se conoce), valor no disponible (existe, pero no se especifica a propósito), o atri­buto no aplicable (no definido para esta tupla). Considere los siguientes ejemplos para ilustrar cada uno de los significados de NULL.

1. Valor desconocido. Una persona en particular tiene una fecha de nacimiento, pero no la conocemos, por lo que la representamos con NULL en la base de datos.

2. Valor no disponible o no especificado. Una persona tiene un teléfono en casa, pero no quiere que apa­rezca listado, por lo que se impide su visualización y se representa como NULL en la base de datos.

3. Atributo no aplicable. Un atributo ÚltimoGrado sería NULL para una persona que no tiene una licen-ciatura, algo que no es aplicable para esa persona.

A veces no es posible determinar el significado que se pretende; por ejemplo, NULL para el teléfono de casa de una persona puede tener cualquiera de los tres significados. Por tanto, SQL no distingue entre los diferen­tes significados de NULL.

En general, cada NULL es considerado diferente a cualquier otro NULL de la base de datos. Cuando en una comparación se ve implicado un NULL, se considera que el resultado es UNKNOWN, o desconocido (podría ser TRUE o podría ser FALSE). Por tanto, SQL utiliza una lógica de tres valores con los valores TRUE, FALSE y UNKNOWN, en lugar de la lógica estándar de dos valores con TRUE o FALSE. Por consiguiente, es necesa­rio definir los resultados de las expresiones lógicas de tres valores cuando se utilizan los conectores lógicos AND, OR Y NOT. La Tabla 8.1 muestra los valores resultantes.

En las Tablas 8.1(a) y 8.1(b), las filas y las columnas representan los valores de los resultados de las expre­siones booleanas (condiciones de comparación) de tres valores, que normalmente aparecen en la cláusula WHERE de una consulta SQL. Cada resultado de una expresión tendría un valor de TRUE, FALSE o UNKNOWN. La Tabla 8.I(a) muestra el resultado de combinar los dos mediante el conector lógico AND, y la

http://libreria-universitaria.blogspot.com