Está en la página 1de 22

PHP Y MYSQL.

TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

En las próximas secciones se verá la forma en la que la base de datos diseñada


puede ser implementada en un sistema gestor como MySQL, para ello será preciso
estudiar previamente, y de forma breve, las sentencias básicas del lenguaje SQL.

13.4. EL LENGUAJE SQL

13.4.1. INTRODUCCIÓN
SQL es un lenguaje de definición y manipulación de datos para bases de datos
relacionales. Es un lenguaje de definición porque permite definir la estructura de
las tablas que componen la base de datos, y de manipulación porque permite
efectuar consultas y realizar operaciones como inserción, borrado y actualización
de los datos que contiene.

El lenguaje SQL tiene sus orígenes en el lenguaje SEQUEL (Structured English


QUEry Language) desarrollado por IBM, un lenguaje para la especificación de las
características de las bases de datos que adoptaban el modelo relacional. En 1979
aparece el primer SGBD basado en SQL: ORACLE. Rápidamente comenzaron a
aparecer en el mercado múltiples productos de bases de datos basados en SQL:
SQL/DS, DB2, SYBASE, INTERBASE, INFORMIX y otros. El amplio desarrollo
del lenguaje hizo necesario un proceso de estandarización para conseguir que el
SQL soportado por los distintos sistemas tuviera una sintaxis común.

Las características destacables de este lenguaje son:


— Posee una firme base teórica.
— Gran capacidad expresiva.
— Flexibilidad.
— Sus sentencias permiten manejar conjuntos de registros.
— Tiene una estructura simple.
— Alta productividad en la codificación (con una sola sentencia pueden
efectuarse consultas complejas).
— SQL no es un lenguaje de programación (su código no necesita
compilarse).

SQL puede usarse de dos maneras:

316
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

— Interactivamente, escribiendo directamente las sentencias y obteniendo


automáticamente el resultado. Es decir, como lenguaje autocontenido.
— Como lenguaje embebido en un lenguaje de programación anfitrión (4GL,
Cobol, Fortran, C, Basic,...). De esta forma SQL se complementa con la
capacidad expresiva, lógica y de cálculo del lenguaje anfitrión. Este uso
está reservado para los usuarios programadores.

En este libro se utilizará el SQL embebido dentro de programas PHP y también se


hará un uso interactivo a través de la línea de comandos de MySQL.

13.4.2. SENTENCIAS DE DEFINICIÓN DE DATOS

Creación de la base de datos


Las sentencias SQL de definición de datos permiten crear la base de datos y los
diferentes objetos que la componen, como por ejemplo, tablas, vistas, índices, etc.
La sentencia utilizada para la creación de objetos es CREATE.

La creación de un objeto requiere la asignación de un nombre que lo identifique


una vez creado, cualquier referencia posterior a él hace uso de ese identificador.
Los identificadores en SQL deben estar formados por letras, dígitos o signos de
subrayado, pero siempre comenzando por una letra y, por supuesto, sin coincidir
con ninguna de las palabras reservadas del lenguaje.

El primer objeto a crear es la propia base de datos, para ello se utilizará el siguiente
comando:

CREATE DATABASE nombre_base_de_datos

Donde nombre_base_de_datos es el identificador escogido para referenciar


a la base de datos que se está creando.

Ejemplo 13.2:
Para crear la base de datos de la empresa Cinem@s que se utilizará a lo largo de los
próximos capítulos, la sentencia es la siguiente:

CREATE DATABASE CINEMAS;

317
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Todo objeto creado con la sentencia CREATE puede ser modificado con la
sentencia ALTER o destruido con la sentencia DROP, de manera que, si se quisiera
destruir la bases de datos anterior, la sentencia a utilizar sería:

DROP DATABASE CINEMAS;

El lenguaje SQL no distingue el uso de mayúsculas y minúsculas. En este


NOTA
libro se utilizará como convenio las mayúsculas para escribir todas las
sentencias SQL, de esta manera serán más fácilmente identificables.

Creación de tablas
Una vez creada la base de datos, el paso siguiente es la creación de la estructura de
cada una de sus tablas.

La sintaxis más simple de la sentencia de creación de tablas es la siguiente:

CREATE TABLE nombre_tabla (atrib1 dominio1,


atrib2 dominio2,
...............
...............
...............
atribN dominioN)

donde:

nombre_tabla es el identificador utilizado para referirse a la tabla.


atribX es el nombre de un atributo de la tabla.
dominioX es el dominio en el que puede tomar valores el atributo
correspondiente.

Respecto a los dominios de los atributos, SQL incorpora un conjunto de dominios


básicos, permitiendo definir atributos de tipo cadena de caracteres, de tipo
numérico, de fecha y hora,...

Además de indicar el dominio de cada atributo, a la hora de definir las tablas


pueden señalarse igualmente diferentes características de los mismos, como por
ejemplo si no se permitirán valores nulos para ese atributo, si el valor debe ser
único, valores por defecto,...

318
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

Ejemplo 13.3:
El código SQL que crea la tabla de la base de datos Cinem@s correspondiente a la
entidad Clientes sería:

CREATE TABLE CLIENTES (


NUM_CLIENTE SMALLINT NOT NULL AUTO_INCREMENT,
NOMBRE VARCHAR(40) NOT NULL,
DIRECCION VARCHAR(50),
FECHANAC DATE,
TELEF CHAR(9),
EMAIL CHAR(30),
PUNTOS_ACUM SMALLINT NOT NULL DEFAULT 0,
CLAVE CHAR(6) NOT NULL,
PRIMARY KEY (NUM_CLIENTE));

En el código anterior puede observarse cómo cada atributo tiene asociado un tipo
de dato; por ejemplo, el atributo NOMBRE será una cadena de un máximo de 40
caracteres (VARCHAR(40)), el atributo NUM_CLIENTE tendrá un valor numérico
de tipo entero en un rango pequeño (SMALLINT), o la fecha de nacimiento tendrá
un valor de tipo fecha (DATE). En el capítulo destinado al estudio del sistema
gestor MySQL se presentarán con detalle todos los tipos de datos admitidos.

En la definición de la tabla CLIENTES se observa igualmente cómo alguno de los


atributos tienen a continuación de su tipo las palabras NOT NULL; se trata de
palabras reservadas del lenguaje SQL que indican que el correspondiente atributo
no puede tomar valores nulos, es decir, todos los registros que sean incluidos en la
tabla deberán tener obligatoriamente un valor para ese atributo. Por ejemplo, en la
tabla CLIENTES, tal como está definida, los únicos atributos que obligatoriamente
deben tener un valor son: NUM_CLIENTE, NOMBRE, PUNTOS_ACUM y CLAVE,
de manera que a la hora de dar de alta un nuevo cliente no sería necesario dar su
dirección de correo electrónico o teléfono, por ejemplo.

Sobre el atributo NUM_CLIENTE de la tabla CLIENTES se deben hacer dos


observaciones adicionales. Por un lado, en la última línea de la definición de la
tabla se establece como clave de la tabla (PRIMARY KEY) precisamente ese
atributo; de esta manera el número de cliente identificará a cada cliente. Además de
eso, en la definición del atributo se ha utilizado la palabra AUTO_INCREMENT
para indicar que el valor de ese atributo en cada registro se generará de forma
automática de manera incremental.

Finalmente, la palabra DEFAULT se utiliza para dar valores por defecto a


determinado atributo, de manera que si al crear un registro no se da valor a ese

319
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

atributo este tomará el valor por defecto. Tal como se aprecia en la definición de la
tabla CLIENTES, el único atributo que tiene valor por defecto es PUNTOS_ACUM,
siendo este valor 0; esto provoca que cuando se produzca el alta de un nuevo
cliente, su saldo de puntos acumulados sea 0, a no ser que se dé otro valor.

La sentencia CREATE crea la estructura de la tabla pero no su contenido, es decir,


sus registros. Estos deberán ser añadidos posteriormente mediante la instrucción
INSERT. Esta sentencia INSERT podrá ser usada de forma interactiva o bien
dentro de un programa que se encargue de leer los datos a insertar, por ejemplo de
un fichero existente creado al efecto.

Ejemplo 13.4:
A continuación se incluye el código SQL completo de generación de todas las
tablas de la base de datos CINEMAS:

CREATE TABLE PELICULAS (


IDPELICULA SMALLINT NOT NULL AUTO_INCREMENT,
TITULO CHAR(50) NOT NULL,
ACTORES MEDIUMTEXT,
PRODUCCION MEDIUMTEXT,
DIRECCION MEDIUMTEXT,
GUION VARCHAR(40),
ANNO SMALLINT,
DURACION SMALLINT NOT NULL,
NACIONALIDAD VARCHAR(25),
GENERO ENUM('infantil','comedia','drama',
'acción','terror','erótica'),
EDAD_RESTRICCION ENUM('apta','mayores 7',
'mayores 13','mayores 18'),
SINOPSIS LONGTEXT,
CARTELERA BLOB,
PRIMARY KEY (IDPELICULA));

CREATE TABLE SALAS (


NUM_SALA SMALLINT NOT NULL,
AFORO SMALLINT NOT NULL,
NUM_FILAS SMALLINT NOT NULL,
OBSERVACIONES LONGTEXT,
PRIMARY KEY (NUM_SALA));

CREATE TABLE PROYECCIONES (


IDPROY SMALLINT NOT NULL AUTO_INCREMENT,
IDPELICULA SMALLINT NOT NULL,
NUM_SALA SMALLINT NOT NULL,

320
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

HORA TIME NOT NULL,


FECHA DATE NOT NULL,
TARIFA_REDUCIDA BOOL,
ESTRENO BOOL,
PRIMARY KEY (IDPROY));

CREATE TABLE ENTRADAS (


NUM_ENTRADA SMALLINT NOT NULL AUTO_INCREMENT,
IDPROY SMALLINT NOT NULL ,
FILA SMALLINT NOT NULL ,
NUM_ASIENTO SMALLINT NOT NULL ,
NUM_CLIENTE SMALLINT NOT NULL ,
RECOGIDA BOOL ,
PRIMARY KEY (NUM_ENTRADA));

CREATE TABLE CLIENTES (


NUM_CLIENTE SMALLINT NOT NULL AUTO_INCREMENT,
NOMBRE VARCHAR(40) NOT NULL,
DIRECCION VARCHAR(50),
FECHANAC DATE,
TELEF CHAR(9),
EMAIL CHAR(30),
PUNTOS_ACUM SMALLINT NOT NULL DEFAULT 0,
CLAVE CHAR(6) NOT NULL,
PRIMARY KEY (NUM_CLIENTE));

Para mejorar la legibilidad, las sentencias SQL pueden partirse en


NOTA
tantas líneas como se desee y utilizar todos los espacios en blanco extra
que se quiera.

Modificación de tablas
Una vez creada una tabla, es posible su modificación utilizando la sentencia
ALTER.

Ejemplo 13.5:
A continuación se incluyen algunos ejemplos de usos de la sentencia ALTER para
modificar la tabla CLIENTES:

321
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

⎯ Cambio del nombre de la tabla CLIENTES:

ALTER TABLE CLIENTES RENAME TABLA_CLIENTES;

⎯ Cambio del nombre de un atributo de la tabla CLIENTES:

ALTER TABLE CLIENTES CHANGE FECHANAC FNACIMIENTO DATE;

⎯ Cambio del tipo de dato de un atributo de la tabla CLIENTES:

ALTER TABLE CLIENTES CHANGE CLAVE CLAVE VARCHAR(10);

⎯ Añadir un nuevo atributo a la tabla CLIENTES:

ALTER TABLE CLIENTES ADD E_CIVIL ENUM('soltero','casado',


'otros');

⎯ Eliminación de un atributo de la tabla CLIENTES:

ALTER TABLE CLIENTES DROP E_CIVIL;

Creación de índices
Otro de los aspectos a considerar a la hora de construir las tablas de la base de
datos es la posibilidad de definir índices. Un índice es un archivo estructurado que
facilita el acceso a los datos en las operaciones de búsqueda. Los índices se deben
crear sobre aquellos atributos que suelen ser utilizados con frecuencia en las
búsquedas. Normalmente los sistemas gestores crean automáticamente un índice
sobre los atributos declarados como claves, y el programador puede optar por
añadir nuevos índices, pero siempre con precaución de no abusar de su uso, ya que
si se tienen demasiados índices la gestión de los datos se hace más costosa.

Los índices son creados, como cualquier elemento, con la sentencia CREATE,
aunque con una sintaxis diferente.

Ejemplo 13.6:
A continuación se incluyen dos ejemplos de creación de índices, uno sobre el
atributo FECHA de la tabla PROYECCIONES y otro sobre el atributo TITULO de
la tabla PELICULAS:

322
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

CREATE INDEX FECHA_IDX ON PROYECCIONES(FECHA);


CREATE INDEX TITULO_IDX ON PELICULAS(TITULO);

También es posible utilizar la sentencia ALTER para añadir un índice a una tabla
creada previamente; por ejemplo:

ALTER TABLE CLIENTES ADD INDEX (NOMBRE);

Claves ajenas: relaciones entre tablas


En la definición de tablas se pueden definir claves ajenas (FOREIGN KEY), es
decir, atributos que son claves primarias de otras tablas, de esta manera ambas
tablas quedan relacionadas. La forma de hacerlo es incluir en la definición de la
tabla una instrucción con la siguiente sintaxis:

FOREIGN KEY (atributo) REFERENCES Tabla_enlazada


(atributo)

Ejemplo 13.7:
En la tabla de PROYECCIONES se incluyó un atributo (IDPELICULA) que hacía
referencia a otro atributo, en este caso del mismo nombre, de la tabla PELICULAS.
En principio, si no se definen claves ajenas podría darse la situación de existir una
proyección con un código de película inexistente en la tabla de películas, con la
correspondiente inconsistencia. La forma de evitar este problema es definir
precisamente en la tabla de proyecciones el correspondiente atributo como una
clave ajena que referencia a la tabla de películas. Como la tabla ya ha sido creada,
esta modificación se puede realizar mediante la sentencia ALTER:

ALTER TABLE PROYECCIONES ADD FOREIGN KEY (IDPELICULA)


REFERENCES PELICULAS (IDPELICULA);

Otra posibilidad es definir las claves ajenas de cada tabla de la misma manera en la
que se definen las claves primarias en la propia definición de la tabla.

Ejemplo 13.8:
La tabla de ENTRADAS podría haber sido definida incluyendo dos claves ajenas,
una referenciando a las proyecciones y otra a los clientes:

CREATE TABLE ENTRADAS (


NUM_ENTRADA SMALLINT NOT NULL AUTO_INCREMENT,

323
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

IDPROY SMALLINT NOT NULL ,


FILA SMALLINT NOT NULL ,
NUM_ASIENTO SMALLINT NOT NULL ,
NUM_CLIENTE SMALLINT NOT NULL ,
RECOGIDA BOOL ,
PRIMARY KEY (NUM_ENTRADA),
FOREIGN KEY (IDPROY) REFERENCES PROYECCIONES (IDPROY),
FOREIGN KEY (NUM_CLIENTE) REFERENCES CLIENTES
(NUM_CLIENTE) );

Cuando se produce una operación de modificación o borrado de los datos de una


tabla que se encuentra relacionada con otra, puede ser necesario que se produzca
una actualización en cascada de la tabla relacionada.

Ejemplo 13.9:
Si una película es dada de baja en la tabla PELICULAS, entonces se deberían
eliminar de la tabla de PROYECCIONES todos aquellos registros que hacían
referencia a esa película. La forma en la que se indica esta necesidad de borrado en
cascada es:

ALTER TABLE PROYECCIONES ADD FOREIGN KEY (IDPELICULA)


REFERENCES PELICULAS (IDPELICULA)
ON DELETE CASCADE ON UPDATE CASCADE;

En otros casos puede ser interesante que no se borren los registros relacionados y
que simplemente a los campos que han quedado con un valor no existente les sean
asignados el valor NULL, o incluso, que se queden con el valor inicial a pesar de su
inconsistencia. Para hacer esto, en la sentencia anterior debería cambiarse la
palabra CASCADE por SET NULL, en el primer caso, o NO ACTION, en el
segundo.

La forma en la que se trabaja con claves ajenas en MySQL es un tanto


NOTA
especial, por lo que se analizará con más detalle cuando se estudie la
integridad referencial en el capítulo dedicado al sistema gestor MySQL.

13.4.3. LA SENTENCIA INSERT


Una vez creadas la base de datos y sus tablas, el siguiente paso es añadir los datos,
ya que toda tabla generada con CREATE estará vacía.

324
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

La sentencia INSERT permite añadir una o varias filas (registros) a una tabla. En
la práctica, para insertar datos en una base de datos se utilizan programas de
entrada orientados a formularios o rutinas que importan los datos desde ficheros o
documentos, realizando procesos iterativos de lectura de datos. Uno de los
objetivos finales que persigue este libro es poder realizar esas operaciones de
inserción desde una página web, para ello será preciso utilizar las sentencias SQL
en programas PHP que a su vez estarán integrados en documentos HTML.

La sintaxis básica de la sentencia INSERT es la siguiente:

INSERT INTO nombre_tabla VALUES (lista_de_valores)

Con esta sintaxis, deben ser introducidos tantos valores como atributos de la tabla;
además, los valores deben darse en el mismo orden en el que se encuentren
definidos los respectivos atributos. Por supuesto, los valores introducidos deben
coincidir con el tipo del correspondiente atributo.

SQL admite un valor especial, el valor NULL, que indica que el correspondiente
atributo está vacío en el registro insertado. Únicamente pueden utilizarse estos
valores nulos sobre atributos que no tengan en su declaración la cláusula NOT
NULL.

Debe aclararse también que las filas de una tabla no están ordenadas, por lo que no
es posible insertar una fila "al comienzo" o "al final" o "entre dos filas" de la tabla.

Ejemplo 13.10:
A continuación se muestran dos ejemplos de inserción de registros en la tabla
SALAS y en la tabla CLIENTES:

INSERT INTO SALAS


VALUES (1, 300, 15, 'Zona para minusválidos');

Esta sentencia insertaría una nueva sala, cuyo número correspondería al 1, con
capacidad para 300 personas, distribuidas en 15 filas y se incluiría en el campo de
observaciones el hecho de tener una zona reservada para minusválidos.

INSERT INTO CLIENTES


VALUES (147, 'Luis Medina Ríos',
'Los Laureles, 129 – 39005 Santander',
'1965-2-21', '942323135',
'medinal@mimail.com', 0, 'lmr65b');

325
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Esta sentencia inserta un nuevo cliente con número de identificación 147, de


nombre "Luis Medina Ríos", con la dirección indicada, nacido el 21 de febrero de
1965, siendo su teléfono 942323135, su dirección de correo electrónico
medinal@mimail.com, con un saldo de puntos inicial de 0 y con clave de
operaciones 'lmr65b'.

En SQL las cadenas de caracteres deben darse entre comillas simples.


Las fechas y horas también son dadas entre comillas y en principio se
NOTA pueden utilizar diferentes formatos. Al analizar el sistema MySQL se
indicarán estos formatos.

En la última inserción realizada en la tabla CLIENTES se puede observar cómo, a


pesar de que el atributo NUM_CLIENTE había sido definido como autoincremental
y el atributo PUNTOS_ACUM tenía un valor por defecto de 0, al insertar el registro
se asignaron también valores para esos dos atributos.

Surge, a la vista de esta situación, la necesidad de disponer de una sintaxis


adicional de la sentencia INSERT que permita insertar valores solo para
determinados atributos. En este caso, a la hora de insertar el registro se deberán
indicar los nombres de los atributos, sin ser necesario que el orden de los valores a
incluir y el de los atributos en la tabla coincidan. La sintaxis de esta variante es:

INSERT INTO nombre_tabla (lista_atributos)


VALUES (lista_valores)

Ejemplo 13.11:
Se podría insertar un nuevo cliente en la tabla con la sentencia:

INSERT INTO CLIENTES (NOMBRE, FECHANAC, EMAIL, CLAVE)


VALUES ('Andrea Fuentes Dávila', '1970-3-31',
'afd@tumail.com', 'and349');

Como puede observarse, en este caso no se dan valores para todos los atributos de
la tabla. En concreto, el atributo NUM_CLIENTE al no tener valor y haber sido
declarado como autoincremental, tomará automáticamente como valor el número
siguiente al valor más alto que se encuentre almacenado en la columna
NUM_CLIENTE de la tabla hasta ese momento. El atributo PUNTOS_ACUM, al no
habérsele dado ningún valor y tener definido uno por defecto, tomará
automáticamente este último (0 en este caso). Al resto de atributos a los que no se

326
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

les ha dado valor (DIRECCION y TELEFONO) se les asignará automáticamente el


valor especial NULL, siempre y cuando el correspondiente atributo admita ese
valor.

Ejemplo 13.12:
Se incluye a continuación una sentencia que permitiría dar de alta una nueva sala:

INSERT INTO SALAS (AFORO, NUM_FILAS, NUM_SALA)


VALUES (400, 20, 3);

Como se aprecia, no se dan valores a todos los atributos (faltaría el atributo


OBSERVACIONES) y además el orden en el que se dan los valores no coincide con
el orden de los atributos en la tabla.

Otra de las posibilidades de inserción de datos es la utilización de la conocida


como "sentencia de inserción multifila". Esta sentencia permite añadir múltiples
filas a una tabla en una sola sentencia. En este caso los valores para las nuevas filas
no son especificados explícitamente, sino que se utiliza una consulta (sentencia
SELECT) para obtener esos valores. Su sintaxis es:

INSERT INTO nombre_tabla (lista_atributos)


Consulta_SELECT

La sentencia INSERT multifila proporciona un modo eficiente y compacto de


copiar datos.

Ejemplo 13.13:
Si se dispone de una tabla adicional PELICULAS_TERROR para guardar en ella
todas las películas del género de terror con una estructura totalmente similar a la de
la tabla PELICULAS, estas podrían insertarse con una sentencia como la que
sigue:

INSERT INTO PELICULAS_TERROR


SELECT * FROM PELICULAS WHERE GENERO = 'terror';

En este caso, el uso del signo "*" es una forma de indicar todos los atributos de la
tabla.

327
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

13.4.4. LA SENTENCIA DELETE


Por supuesto, todo registro almacenado en una tabla puede ser eliminado en
cualquier momento. La sentencia que permite eliminar una o varias filas de una
tabla es DELETE, cuya sintaxis es:

DELETE FROM nombre_tabla WHERE condición

Esta sentencia elimina de la tabla indicada todas las filas que cumplan la condición
señalada. Si se suprime la cláusula WHERE, se borrarán todas las filas de la tabla,
pero no la tabla; recuérdese que la instrucción que destruye completamente la tabla
(datos y estructura) es DROP TABLE.

Las filas no pueden borrarse parcialmente, es decir, no pueden suprimirse valores


concretos de una fila.

Ejemplo 13.14:
Las sentencias de eliminación de registros serían:

⎯ Eliminación del cliente número 1456:

DELETE FROM CLIENTES WHERE NUM_CLIENTE = 1456;

⎯ Eliminación de las entradas de las primeras 5 filas para la proyección número 231:

DELETE FROM ENTRADAS WHERE FILA <= 5 AND IDPROY = 231;

Las sentencias DELETE con condiciones simples permiten seleccionar las filas a
suprimir basándose únicamente en los propios contenidos de las filas. Sin embargo,
también es posible efectuar la selección de las filas a suprimir en base a los datos
contenidos en otras tablas.

Ejemplo 13.15:
Si se desea eliminar todas las proyecciones de la película Refugio en el paraíso, se
podría utilizar la sentencia:

DELETE FROM PROYECCIONES WHERE


IDPELICULA = (SELECT IDPELICULA FROM PELICULAS WHERE
TITULO = 'Refugio en el paraíso');

328
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

13.4.5. LA SENTENCIA UPDATE


La sentencia UPDATE permite modificar los valores de los atributos de uno o
varios registros almacenados en la tabla. La sintaxis de la sentencia es:

UPDATE nombre_tabla SET lista_asignaciones WHERE condición

La parte final de la sentencia, la cláusula WHERE es opcional; en caso de no


indicarse, la actualización afectaría a todos los registros de la tabla.

En una misma sentencia se pueden actualizar los valores de varios atributos, indicando las
asignaciones separadas por comas.

Ejemplo 13.16:
Sentencias de actualización de registros serían:

⎯ Reducción del aforo de todas las salas en un 10%:

UPDATE SALAS SET AFORO = AFORO * 0.9;

⎯ Otorgar 100 puntos extra a todos los clientes que tengan un saldo de puntos
acumulados menor que 500:

UPDATE CLIENTES SET PUNTOS_ACUM = PUNTOS_ACUM + 100


WHERE PUNTOS_ACUM < 500;

⎯ Modificar el aforo y el número de filas de la sala número 7:

UPDATE SALAS SET AFORO = 500, FILAS = 25


WHERE NUM_SALA = 7;

Al igual que ocurría con la sentencia DELETE, también es posible efectuar la


selección de las filas a actualizar en base a los datos contenidos en otras tablas.

Ejemplo 13.17:
Se desea establecer tarifa reducida para todas las proyecciones de películas rodadas
antes de 1990, la sintaxis de la sentencia sería:

UPDATE PROYECCIONES SET TARIFA_REDUCIDA = 1


WHERE IDPELICULA =

329
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

(SELECT IDPELICULA FROM PELICULAS WHERE ANNO <


1990);

El tipo booleano o lógico no es uno de los tipos estándar de SQL; en el


caso de MySQL, se dispone del tipo BOOL que realmente es un sinónimo
del tipo TINYINT(1) que permite almacenar un número entero de 1 bit (0
NOTA ó 1). El valor 1 puede identificarse con el valor lógico "verdadero" y el
valor 0 con "falso".

13.4.6. LA SENTENCIA SELECT


Las consultas son la base del SQL, mediante ellas se extrae información de las
diferentes tablas de la base de datos, mostrándola en una estructura tabular.

Toda consulta en SQL se realiza con la sentencia SELECT. Esta es sin duda la
sentencia más poderosa y completa con la que cuenta el lenguaje SQL. Su sintaxis
completa es:

SELECT [Cuantificador_de_conjunto] items


FROM Nombre_de_tabla
[WHERE Condición_de_búsqueda]
[GROUP BY Columna_de_agrupación]
[HAVING Condición_de_búsqueda]
[ORDER BY Especificación_de_ordenación]

Todos los fragmentos que en esta sintaxis aparecen encerrados entre corchetes son
opcionales.

La sentencia SELECT consta de varias partes diferentes:

— Cláusula SELECT: en ella se indican los datos a recuperar en la consulta.


Los items indicados deben ir separados por comas y pueden ser:
o Un nombre de columna (atributo) de una tabla.
o Un asterisco (*), que es equivalente a especificar los nombres de
todas las columnas de la tabla.
o Una constante, indicando que el mismo valor constante va a
aparecer en todas las filas de los resultados de la consulta.
o Una expresión SQL, cuyo valor será calculado a partir de los
valores de los atributos.

— El cuantificador de conjunto es opcional, puede ser:

330
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

o ALL (opción por defecto): indica que en el resultado de la consulta


deben mostrarse todas las filas, incluyendo las repetidas.
o DISTINCT: indica que en el resultado de la consulta no deben
mostrarse las filas repetidas.

— Cláusula FROM: en ella se indican, separadas por comas, las tablas que
contienen los datos que se desean recuperar en la consulta.

— Cláusula WHERE: permite indicar una condición de búsqueda.

— Cláusula GROUP BY: permite obtener consultas resumen en las que todas
las filas similares son agrupadas y se genera una fila resumen para cada
grupo.

— Cláusula HAVING: permite indicar condiciones o filtros a verificar por los


diferentes grupos producidos por la cláusula GROUP BY.

— Cláusula ORDER BY: señala el modo de ordenación de los resultados de


la consulta. Si se omite, los resultados no aparecen ordenados.

Proyecciones de una tabla


Las únicas cláusulas obligatorias son SELECT y FROM. Con esta sintaxis mínima
se pueden generar las consultas más sencillas en SQL, las proyecciones de una
tabla, es decir, aquellas que solicitan columnas de datos de una única tabla en la
base de datos.

La sintaxis mínima es:

SELECT lista_columnas FROM nombre_de_tabla

Ejemplo 13.18:
Si se quisiera recuperar todos los registros de la tabla PELICULAS, se debería
utilizar la sentencia:

SELECT * FROM PELICULAS;

En cambio, si lo único que interesa es obtener un listado con los títulos y


nacionalidades de las películas, la sentencia a utilizar sería:

SELECT TITULO, NACIONALIDAD FROM PELICULAS;

331
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Una consulta SQL puede incluir columnas calculadas cuyos valores se obtienen a
partir de los valores de los datos almacenados.

Ejemplo 13.19:
Se desea listar las salas disminuyendo el aforo en un 10%, la sentencia para ello sería:

SELECT NUM_SALA, AFORO * 0.9 FROM SALAS;

En estas consultas con campos calculados pueden utilizarse diferentes funciones de


SQL además de las propias de cada gestor de bases de datos. Por ejemplo, existen
funciones para tratamiento de fechas y horas, para tratamiento de cadenas de
caracteres,...

Eliminación de duplicados
Si una consulta incluye la clave primaria de una tabla en su lista de selección,
entonces cada fila de resultados será única; en cambio, si no se incluye la clave en
la lista de selección pueden aparecer filas duplicadas en el resultado. Se pueden
eliminar las filas duplicadas en la consulta insertando la palabra clave DISTINCT
en la sentencia SELECT justo antes de la lista de selección.

Ejemplo 13.20:
Al seleccionar todos los directores de las películas de la tabla PELICULAS pueden
aparecer algunos de ellos duplicados (los que han dirigido varias películas), por
tanto habría dos opciones para esta consulta:

⎯ Listar todos los directores de películas aunque se produzca duplicidad de


información:

SELECT DIRECTOR FROM PELICULAS;

⎯ Listar todos los directores de películas, sin duplicidad:

SELECT DISTINCT DIRECTOR FROM PELICULAS;

Consultas con condiciones de selección


Para especificar condiciones de selección en las consultas se utiliza la cláusula
WHERE. En este caso el resultado de la consulta estará formado por todas las filas
que cumplan la condición de búsqueda especificada.

332
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

Ejemplo 13.21:
Algunas consultas con condiciones de selección serían:

⎯ Obtener los títulos de todas las películas de una duración inferior a 120
minutos:

SELECT TITULO FROM PELICULAS WHERE DURACION < 120;

⎯ Obtener un listado con las direcciones de correo electrónico de todos los


clientes que tengan 1.000 puntos acumulados:

SELECT EMAIL FROM CLIENTES WHERE PUNTOS_ACUM = 1000;

⎯ Seleccionar las entradas para la proyección de número de identificación 341 y


que correspondan a filas comprendidas entre la 10 y la 14:

SELECT * FROM ENTRADAS WHERE IDPROY = 341


AND FILA BETWEEN 10 AND 14;

⎯ Obtener los títulos de todas las películas de nacionalidad española, francesa o


italiana:

SELECT TITULO FROM PELICULAS WHERE


NACIONALIDAD IN ('española','francesa','italiana');

⎯ Generar un listado con los títulos y directores de todas las películas en las que
participe Antonio Banderas:

SELECT TITULO,DIRECCION FROM PELICULAS WHERE


ACTORES LIKE '%Banderas%';

Como se puede apreciar en estos ejemplos, el lenguaje SQL tiene una sintaxis muy
similar al lenguaje natural, y ofrece una gran capacidad expresiva para generar
consultas.

Ordenación de los resultados de una consulta


Para ordenar los resultados de una consulta se utiliza la cláusula ORDER BY
seguida de una lista de especificaciones de ordenación separadas por comas. La
primera especificación de ordenación es la principal y las otras serán utilizadas en
caso de igualdad de valor en la primera. Cada especificación de ordenación está
dada por el nombre de un atributo seguido de una de las palabras siguientes:

333
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

ASC Indica orden ascendente.


DESC Indica orden descendente.

En caso de no indicar el tipo de orden, por defecto se entiende que es ascendente.

Ejemplo 13.22:
Se desea generar un listado de clientes en orden decreciente según el atributo de
puntos acumulados y en orden creciente según el nombre, la sentencia sería:

SELECT * FROM CLIENTES ORDER BY PUNTOS_ACUM DESC,NOMBRE


ASC;

Consultas multitabla
SQL permite también recuperar datos procedentes de diferentes tablas mediante
una única sentencia SELECT, esto es lo que se conoce como "composición".

Ejemplo 13.23:
A continuación se presentan algunos sencillos ejemplos de consultas multitabla:

⎯ Se desea saber todas las fechas en las que se proyecta la película El Señor de
los Anillos:

SELECT FECHA FROM PELICULAS,PROYECCIONES WHERE


TITULO = 'El Señor de los Anillos' AND
PELICULAS.IDPELICULA = PROYECCIONES.IDPELICULA;

En este caso, la consulta utiliza dos tablas y es preciso en la condición de


selección indicar la igualdad entre los dos atributos comunes a las dos tablas.

⎯ Se desea un listado con los nombres de todos los clientes que hayan adquirido
alguna entrada para ver la película El Señor de los Anillos:

SELECT NOMBRE FROM


PELICULAS,PROYECCIONES,ENTRADAS,CLIENTES
WHERE
TITULO = 'El Señor de los Anillos' AND
PELICULAS.IDPELICULA = PROYECCIONES.IDPELICULA
AND
PROYECCIONES.IDPROY = ENTRADAS.IDPROY AND
ENTRADAS.NUM_CLIENTE = CLIENTES.NUM_CLIENTE;

334
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

Al intervenir en las consultas anteriores columnas o atributos con el


mismo nombre, aunque en tablas diferentes, es necesario utilizar los
nombres cualificados, es decir, precedidos de los nombres de las tablas
NOTA a las que pertenecen.

Aún cuando no exista conflicto de nombres, también es posible utilizar


los nombres cualificados y evitar ambigüedades.

Consultas resumen
SQL permite resumir los datos mediante un conjunto de funciones denominadas
funciones de columna. Algunas de ellas son:

SUM() Calcula la suma total de los valores de una columna.


AVG() Calcula el valor promedio de una columna.
MIN() Encuentra el valor más pequeño de una columna.
MAX() Encuentra el valor más grande de una columna.
COUNT() Cuenta el número de valores de una columna.

Ejemplo 13.24:
A continuación se muestran ejemplos de consultas resumen:

⎯ Cálculo de la duración media de todas las películas del género comedia:


SELECT AVG(DURACION) FROM PELICULAS
WHERE GENERO = 'comedia';

⎯ Obtención de la capacidad de aforo de la sala más grande:

SELECT MAX(AFORO) FROM SALAS;

⎯ Cálculo de la suma de los puntos acumulados por los clientes número 321, 543,
287 y 721:

SELECT SUM(PUNTOS_ACUM) FROM CLIENTES


WHERE NUM_CLIENTE IN (321,543,287,721);

⎯ Obtener el número total de películas de nacionalidad española:

SELECT COUNT(*) FROM PELICULAS


WHERE NACIONALIDAD = 'española';

335
PHP Y MYSQL. TECNOLOGÍAS PARA EL DESARROLLO DE APLICACIONES WEB

Consultas agrupadas
Las consultas agrupadas o resumen producen una única fila de resultados a modo
de "totales"; sin embargo, en ocasiones es interesante obtener resúmenes parciales
o agrupados por categorías. Esto se consigue con la cláusula GROUP BY.

Ejemplo 13.25:
Dos ejemplos de consultas agrupadas serían las siguientes:

⎯ Obtener para cada género de películas, la duración máxima:

SELECT MAX(DURACION) FROM PELICULAS GROUP BY GENERO;

⎯ Contar el número de entradas compradas por cada cliente:

SELECT NOMBRE, COUNT(NUM_ENTRADA) FROM CLIENTES,ENTRADAS


WHERE CLIENTES.NUM_CLIENTE = ENTRADAS.NUM_CLIENTE
GROUP BY NOMBRE;

Condiciones de búsqueda de grupos


De la misma manera que en las consultas agrupadas la cláusula WHERE puede ser
utilizada para rechazar filas individuales, la cláusula HAVING puede emplearse
para rechazar grupos de filas.

El formato de la cláusula HAVING es similar a la cláusula WHERE y permite indicar


una condición de búsqueda para grupos. A diferencia de lo que ocurría en la
cláusula WHERE, sí es posible utilizar funciones de columna en la condición de la
cláusula HAVING.

Ejemplo 13.26:
Se desea obtener el nombre de todos los clientes que hayan adquirido 20 o más
entradas; la forma de conseguirlo sería utilizando la sentencia:

SELECT NOMBRE, COUNT(NUM_ENTRADA) FROM CLIENTES,ENTRADAS


WHERE CLIENTES.NUM_CLIENTE = ENTRADAS.NUM_CLIENTE
GROUP BY NOMBRE
HAVING COUNT(NUM_ENTRADA) >= 20;

336
BASES DE DATOS RELACIONALES Y EL LENGUAJE SQL

En principio la cláusula HAVING está pensada para su utilización conjunta con la


cláusula GROUP BY; sin embargo, también es posible utilizar HAVING sin GROUP
BY, en este caso SQL considera el conjunto entero de resultados como un único
grupo y le aplica la condición de selección de HAVING.

337

También podría gustarte