Está en la página 1de 152

ANTOLOGÍA TALLER

DE BASES DE DATOS
UNIDAD I. LENGUAJE
DE DEFINICIÓN DE
DATOS
1.1. INSTALACIÓN DE UN SISTEMA GESTOR DE BASE DE
DATOS (SGBD)

Antes de instalar cualquier SGBD es necesario conocer los requerimientos de hardware y


software, el posible software a desinstalar previamente, verificar el registro de Windows y el
entorno del sistema, así como otras características de configuración especializadas como
pueden ser la reconfiguración de los servicios TCP/IP y la modificación de los tipos archivos
HTML para los diversos navegadores.
Se presenta a continuación una serie de requerimientos mínimos de hardware y software
para instalar oracle 11g Express y MySQL estándar versión 5.1. en Windows Seven y Ubuntu
10.

Requerimientos mínimos de instalación de Oracle 11g Express y MySQL estándar


versión 5.1

Requerimiento Oracle MySQL

RAM 512 MB 512 MB

Memoria virtual1 1024 MB 1024 MB

Espacio disco duro 1.5 GB 1 GB

Tamaño máximo de la base de datos 4 GB Sin limite

Sistema Operativo: Windows Server, Windows Seven,


Linux, Unix

Arquitectura del Sistema 32/64-bit

Protocolo de red TCP/IP

Protocolo de red TCP/IP con SSL

La regla general para determinar el tamaño de la memoria virtual depende del tamaño de
memoria RAM instalada. Si su sistema tiene menos de 4 GB de RAM por lo general el
espacio de intercambio debe ser de al menos dos veces este tamaño. Si usted tiene más de
8 GB de memoria RAM instalada puede considerar usar el mismo tamaño como espacio de
intercambio. Cuanta más memoria RAM tenga instalada, es menos probable usar el espacio
de intercambio, a menos que tenga un proceso inadecuado.

INVESTIGAR
Buscar y seleccionar en distintas fuentes de información los requisitos y características de
distintos SGBD (Oracle, MYSQL, INFORMIX, SQLServer, DB2, PostgreSQL y MongoDB)
Realizar un cuadro comparativo donde se agregue la información encontrada acerca de los
distintos SGBD agregando la opinión personal acerca de las ventajas y desventajas de cada
uno de ellos
Usando como fuente de información el libro Fundamentos de Base de Datos del autor
Silberschatz, Korth y Sudarshan capítulo I, resuelva el siguiente cuestionario
¿Cuáles son las inconvenientes de un sistema gestor de base de datos?
 Indique los pasos importantes para configurar una base de datos para una empresa
dada.
 Explique la diferencia entre independencia de datos física y lógica.
 Explique cinco responsabilidades del Sistema Gestor de la Base de Datos.
 Para cada responsabilidad explique qué pasaría de no asumir la responsabilidad.
 ¿Cuáles son las cinco funciones principales del administrador de la base de datos?
 Indique 5 aplicaciones que usted perciba que se usa una base de datos para
almacenar datos persistentes
El producto requerido es una entrada con la fecha de realización en su bloc de notas
________________________________________________________________________

Instalación del SGBD

Microsoft SQL Server© 2008 Express


SQL Server 2008 Express es una edición gratuita de SQL Server y es una plataforma de
datos ideal para aprender y ejecutar pequeñas aplicaciones de servidor y de escritorio, y para
su redistribución a través de ISV.
Características clave que ofrece SQL Server 2008 R2 SP2 Express:
 Admite los procedimientos, desencadenadores, funciones y vistas almacenados
 Almacene todo tipo de datos empresariales con soporte nativo para datos
relacionales, XML, FILESTREAM y datos espaciales
 Rendimiento mejorado, facilidad de uso y visualización además de la integración con
el sistema de Microsoft 2007 Office en SQL Server Reporting Services
 Simplifique las tareas de desarrollo mediante el aprovechamiento de las capacidades
existentes de T-SQL, ADON.NET Entity Framework y LINQ.
 Estrecha integración con Visual Studio y Visual Web Developer
Requisitos del sistema
Sistemas operativos admitidos: Windows 7, Windows Server 2003, Windows Server 2008,
Windows Server 2008 R2, Windows Vista, Windows XP
 Memoria del sistema: Mínimo 512 MB para SQL Server Express with Tools y SQL
Server Express con Advanced Services y 4 GB para Reporting Services que se instala
con SQL Server Express con Advanced Services
 Disco duro:2.2 GB de espacio en disco
 Procesadores:
o X86: Procesador compatible con Pentium III o más rápido (velocidad del
procesador: 1,0 GHz o más)
o X64: Mínimo: AMD Opteron, AMD Athlon 64, Intel Xeon compatible con Intel
EM64T, Intel Pentium IV compatible con EM64T (velocidad del procesador: 1,0
GHz o más)
o IA64: Procesador Itanium o más rápido (velocidad del procesador: 1,0 GHz o
más)
Limitaciones: SQL Server Express acepta un procesador físico, 1 GB de memoria y 10 GB
de capacidad de almacenamiento
Archivos de instalación
El siguiente hipervínculo corresponde a archivos disponibles para esta descarga.
http://www.microsoft.com/es-mx/download/details.aspx?id=30438
En nuestro caso instalaremos la versión de 64 bits. Ejecutamos el archivo, con lo cual nos
mostrara la siguiente imagen
Selección de las características del SGBD. Seleccione todas

Configuración de instancia. Especifique el nombre y el identificador de SQL Server. El


identificador de instancia se convierte en parte de la ruta de acceso de instalación. Por el
momento usaremos los valores por defecto
Configuración del motor de base de datos. Especifique el modo de autenticación, carpeta
de datos y administradores de la base de datos.
Seleccionamos el modo de autenticación Windows. Lo cual significa que si nos logeamos en
Windows, también lo haremos en SQL Server
FILESTREAM. Hoy en día muchos de los datos se crean en la forma no estructurada como
documentos de texto, videos, imágenes, hojas de cálculo, etc. Su gestión aumenta la
complejidad de su manejo y llega a causar serios problemas de consistencia. FILESTREAM
integra el motor de base de datos del servidor SQL con un sistema de archivos NTFS por
objeto binario de almacenamiento BLOB como archivos en el sistema de archivos.
Instrucciones Transact-SQL pueden insertar, actualizar, consultar, buscar y copia de
seguridad de los datos FILESTREAM.

Configuración de Reporting Services. Especifique el modo de Reporting Services


Informe de errores. Solicitud de cooperación para mejoras de SQL Server

Instalación completada. Si llegaste a este punto tendrás un mensaje similar


 

Oracle Express Edition 11g Release 2


Oracle Database XE es una gran base de datos para:
 Desarrolladores que trabajan en PHP, Java, .NET, XML, y Open Source applications
 DBAs que necesitan desarrollar libremente
 Vendedores de Software y hardware que necesitan distribuir sin cargos
 Instituciones educativas y estudiantes que cursan materias relacionados con base
de datos
Oracle es líder en bases de datos. Con Oracle XE, es posible desarrollar y desplegar
aplicaciones potentes, actualizar sin costo y generar complejas migraciones.
Oracle Express Edition se instala en una máquina con cualquier número de procesadores,
solo puede contener una base de datos y direccionar un máximo de 4GB de datos y un
máximo de 1GB RAM.
Oracle Database XE, usa una interface basada en browser (Navegador) para:
 Administrar la base de datos
 Crear tablas, vistas, y otros objetos de base de datos
 Importar, exportar, y ver tablas de datos
 Ejecutar consultas y scripts SQL
 Generar reportes
Oracle Database XE incluye Oracle Application Express release 2.1, un ambiente de
desarrollo gráfico para crear aplicaciones Web con base de datos. Oracle Database XE es
una versión reducida de Oracle con las mismas características y potencialidad de Oracle
Database. Es necesario destacar que no soporta todos los tipos de datos de Oracle
Database XE.
Oracle Database XE incluye las siguientes utilidades:
 Línea de comandos SQL (SQL*Plus), para ejecutar sentencias SQL y comandos
PL/SQL y ejecutar scripts
 SQL*Loader, para insertar datos en la base de datos
 Utilidades para importar, exportar y volcar la base de datos
Download Oracle Database 11g Express Edition. Proceso que descargara el archivo
OracleXE112_Win32.zip descomprímalo en el archivo de su preferencia.
Requerimientos del sistema para Oracle Database XE Server y Oracle Database XE Client.

Requerimiento Valor

Arquitectura del Intel x86 (desde Windows 2000 hasta seven) o Linux x86
sistema (Debian, Mandriva, Novell, Red Hat y Ubuntu )

Protocolo de red TCP/IP

Servidor : 1.6 gigabytes mínimo


Espacio en disco
Cliente: 75 megabytes

RAM 256 megabytes mínimo, 512 megabytes recomendado

 
Estos puertos son usados por defecto por Oracle Database XE
 1521: Oracle database listener
 2030: Oracle Services para Microsoft Transaction Server
 8080: Puerto para Oracle XML DB y la inteface gráfica de usuario Oracle Database XE
Instalación de Oracle Database XE en Windows

Doble clic sobre el icono   o el archivo setup.exe en ambos casos con privilegios de
administrador. Pulse sobre el botón de siguiente para iniciar la instalación.
Acepte los términos de acuerdo de licencia

Verifique los requerimientos de espacio y si los cumple pulse aceptar. Considere un Giga
más para almacenamiento.

Introduzca el password para el usuario SYSTEM. Después de terminar la instalación deberá


iniciar la base de datos con este usuario.
A continuación Oracle Database XE nos informa sobre los puertos que utilizara. Pulse
Instalar.

El tiempo de instalación de Oracle Database XE depende de su equipo (procesador y


memoria). Al terminar el proceso de instalación pulse el botón Terminar.

Al pulsar el botón Terminar nos direccionara a la página de acceso de la base de datos


(http://127.0.0.1:8080/apex). Recuerde iniciar por primera vez con el usuario SYSTEM y su
password.
Pulse el icono Sessions e introduzca la siguiente información

Para futuros accesos usted puede pulsar botón de inicio, todos los programas, base de datos
10g Express Edition o el icono en su escritorio denominado Base de Datos

Ahora vamos a crear un usuario


Conteste el siguiente formulario

Instalación de Oracle Database XE en Ubuntu 10


Lo primero que tenemos que hacer es descargar el paquete .deb correspondiente. Para ello
accedemos a la página oficial de oracle. Note que para poder descargar hay que registrase
gratuitamente
Seleccionado el paquete oracle-xe-universal_10.2.0.1-1.0_i386.deb es necesario abrir con el
instalador de paquetes GDebi.

Terminada la descarga instale el paquete.


Una vez que termina de instalarse el paquete. Tenemos que configurar la base de datos.
Para ello ejecutamos el comando:
sudo /etc/init.d/oracle-xe configure
Con eso arranca un script de configuración en modo texto que nos hará una serie de
preguntas:
 Puerto de la aplicación web que nos permite administrar gráficamente la base de
datos,
 Puerto de la base de datos,
 Password el usuario SYSTEM de Oracle,
 Si queremos arrancar la base de datos cada vez que iniciemos la máquina.
Oracle Database 10g Express Edition Configuration
-------------------------------------------------
This will configure on-boot properties of Oracle Database 10g Express
Edition. The following questions will determine whether the database should
be starting upon system boot, the ports it will use, and the passwords that
will be used for database accounts. Press <Enter> to accept the defaults.
Ctrl-C will abort.
Specify the HTTP port that will be used for Oracle Application Express [8080]:8080
Specify a port that will be used for the database listener [1521]:1521
Specify a password to be used for database accounts. Note that the same
password will be used for SYS and SYSTEM. Oracle recommends the use of
different passwords for each database account. This can be done after
initial configuration:
Confirm the password:
Do you want Oracle Database 10g Express Edition to be started on boot (y/n) [y]:y
Starting Oracle Net Listener...Done
Configuring Database...Done
Starting Oracle Database 10g Express Edition Instance...Done
Installation Completed Successfully.
To access the Database Home Page go to "http://127.0.0.1:8080/apex"
Yo respondí usando los valores por defecto, cambia los valores de los puertos si entran en
conflicto con otros usados en tu máquina y no te olvides de la contraseña que pongas para
SYS y SYSTEM, la usaremos posteriormente.
En ambos sistemas operativos después de introducir el usuario y el password
correspondiente. Es necesario definir un usuario con los privilegios necesarios para
administrar la base de datos.
Para administrar gráficamente tu base de datos usaremos la siguiente URL.
http://127.0.0.1:8080/apex
MySQL Enterprise Edition
MySQL Enterprise Edition incluye el conjunto más completo de características avanzadas y
herramientas de gestión para alcanzar los más altos niveles de escalabilidad, seguridad,
fiabilidad y tiempo de actividad. Reduce el riesgo, costo y complejidad en el desarrollo,
implementación y administración de aplicaciones críticas de negocio MySQL.
MySQL Enterprise Edition incluye:
MySQL Enterprise Backup: Realiza copias de seguridad de bases de datos MySQL en línea,
de los subconjuntos de tablas InnoDB, y la recuperación mediante puntos de restauración.
MySQL Enterprise de alta disponibilidad que proporciona, con soluciones certificadas que
incluyen replicación de MySQL, Oracle VM Templates para MySQL.
MySQL Enterprise Escalabilidad: permite alcanzar el rendimiento sostenido y la escalabilidad
de cada vez mayor de usuarios, consulta, y las cargas de datos
MySQL Enterprise Security: Proporciona listas para utilizar los módulos de autenticación
externos para integrar fácilmente las infraestructuras existentes de seguridad, incluyendo
Pluggable Authentication Modules y el directorio activo de Windows
MySQL Enterprise Monitor supervisa continuamente su base de datos y de forma proactiva le
asesora sobre cómo implementar las mejores prácticas de MySQL, incluyendo consejos y
alertas de seguridad
MySQL Query Analyzer Mejora el rendimiento de las aplicaciones mediante el control de
rendimiento de las consultas y precisa localización de código SQL que está causando una
desaceleración
MySQL Workbench Ofertas de modelado de datos, desarrollo de SQL y herramientas de
administración integral para la administración del servidor de configuración del usuario, y
mucho más.
La versión 5.2. está preinstalada en Ubuntu para su configuración seleccionaremos del menu
principal Aplicaciones, MySQL Administrador. Introduzca el password de root.

Obtendrá como respuesta la interface de conexión. Teclee el password de root y presione el


botón conect.

Similar a Oracle procederemos a crear un usuario administrador para evitar usar root.
Seleccione User Administration y presione el botón New User
Introduzca los datos solicitados. Es necesario dar privilegios al usuario (Scheme Privileges),
sin mayores explicaciones otorgue todos y pulse el botón Apply Changes.
1.3. Configuración del SGBD
Durante el proceso de instalación configuraremos el arranque de MySQL, password de root,
puerto TCP/IP
Tipo de configuración
Indicaremos el tipo de servidor de MySQL Server que queramos dar al equipo en el que se
instala marcaremos una de las tres opciones:
1. Developer Machine: Marcaremos esta opción si en el equipo donde hemos instalado
MySQL Server se utiliza también para otras aplicaciones. MySQL Server utilizará la
memoria mínima necesaria.
2. Server Machine: Equipo compartido con algunas aplicaciones (no demasiadas). Con
esta opción MySQL Server utilizará un nivel medio de memoria.
3. Dedicated MySQL Server Machine: Seleccione esta opción sólo si queremos utilizar
el equipo como un servidor dedicado exclusivamente a MySQL. Con esta opción
MySQL Server utilizará el máximo de memoria disponible. Se obtendrá un
rendimiento elevado pero el equipo sólo servirá para MySQL.
En nuestro caso marcaremos "Developer Machine" (utilizará un bajo de memoria para su
funcionamiento, ya que nuestra máquina trabajará con otras aplicaciones), y pulsaremos clic
sobre el botón para continuar.

Password de root
Indicar si queremos que el asistente de configuración de MySQL Server cree un servicio de
Windows o un archivo de proceso por lotes (.bat). Aquí podremos utilizar el método que más
nos convenga para iniciar MySQL Server, cada uno tiene sus ventajas e inconvenientes. El
más "profesional" es "Install As Windows Service", pues podremos indicar el modo de inicio:
manual, automático, etc. también podremos deshabilitarlo o reiniciarlo desde otras
aplicaciones en caso necesario.
Si marcamos esta opción deberemos indicar el nombre que se le dará al servicio en "Service
Name", en nuestro caso, puesto que el nombre que aparece por defecto "MySQL56"
El archivo de configuración se llama my.ini (Windows) o my.cnf (linux) la localización exacta
depende de su instalación. Recomiendo respaldarlo. Dado que se puede modificar
manualmente
Alguna de las opciones de interés es
max_connections
Cantidad máxima de sesiones simultáneas que el servidor MySQL permite. Una de estas
conexiones será reservada para un usuario con Privilegios de root para permitir que el
administrador inicia sesión, incluso si
alcanzado el límite de conexiones
Si usted espera que una gran cantidad de usuarios al mismo tiempo, entonces usted debe
pensar en servidores de alto desempeño. Como regla general un servidor eFront típico
podría manejar entre 200 y 300 usuarios concurrentes (Un usuario concurrente solicita una
página durante los últimos 5 minutos). Con un servidor web de gama alta con 32 GB de
RAM, discos SCSI y un procesador de gama alta es posible duplicar este n úmero. Separar el
servidor web del servidor de base de datos y tener 32 GB y discos SCSI en ambos de ellos
puede triplicar este número y acercarse a 2.000 usuarios concurrentes.
El uso de la replicación debe ser sencilla y necesitaría con cambios mínimos del código a
implementar (se debe modificar el manejo de las escrituras y lecturas en eFront. Estas son
funciones centralizadas que pueden sintonizarse en el mismo lugar).
max_connections = 2... ∞
query cache size
Caché de consultas se utiliza para almacenar en caché los resultados de SELECT y después
devolverlos sin la ejecución de la misma consulta una vez más. Tener la consulta en Caché
habilitado puede resultar en mejoras significativas de velocidad, si se tienen muchas
consultas idénticas donde raramente vez cambian.
query_cache_size= = 0... ∞
Para consultar el estado de la memoria use la sentencia
SHOW STATUS LIKE '%cache%’;
El resultado depende de query_cache_size y la memoria física de su equipo

Consulte la variable de estado 'Qcache_lowmem_prunes para comprobar si el valor actual,


es lo suficientemente alta como para sus necesidades.
Si las consultas son diferentes cada vez, la caché de consultas puede resultar en una
desaceleración en lugar de una mejora del rendimiento.
1.2. Creación del esquema de la base de datos

El esquema de una base de datos (en inglés, Database Schema) describe la estructura de
una Base de datos, en un lenguaje formal soportado por un Sistema administrador de Base
de datos (DBMS). En una Base de datos Relacional, el Esquema define sus tablas, sus
campos en cada tabla y las relaciones entre cada campo y cada tabla.

El esquema es generalmente almacenado en un Diccionario de Datos. Aunque generalmente


el esquema es definido en un lenguaje de Base de datos, el término se usa a menudo para
referirse a una representación gráfica de la estructura de base de datos (Diseño de lógico de
la base de datos).

Generalmente en la práctica el término esquema de la base de datos se refiere al diseño


físico de la base de datos.

Oracle generalmente asocia un 'username' como esquemas en este caso SYSTEM y HR


(Recursos humanos).

Por otro lado MySQL presenta dos esquemas information_schema y MySQL ambos guardan
información sobre privilegios y procedimientos del gestor y no deben ser eliminados.

Sintaxis básica para crear una base de datos en Oracle (No aplica en Oracle express)
CREATE DATABASE nombre_baseDatos

Sintaxis básica para crear una base de datos en MySQL


CREATE DATABASE IF NOT EXISTS nombre_baseDatos;

Para conocer las bases de datos creadas use


SHOW DATABASES;

Actualización, modificación y eliminación del esquema de base de datos

Oracle

Una tabla es un sistema de elementos de datos (atributo - valores) que se organizan que
usando un modelo vertical - columnas (que son identificados por su nombre)- y horizontal
filas. Una tabla tiene un número específico de columnas, pero puede tener cualquier número
de filas. Cada fila es identificada por los valores que aparecen en un subconjunto particular
de la columna que se ha identificado por una llave primaria.

Una tabla de una base de datos es similar en apariencia a una hoja de cálculo, en cuanto a
que los datos se almacenan en filas y columnas. Como consecuencia, normalmente es
bastante fácil importar una hoja de cálculo en una tabla de una base de datos. La principal
diferencia entre almacenar los datos en una hoja de cálculo y hacerlo en una base de datos
es la forma de organizarse los datos.

Por lo tanto, la creación de las tablas en el proceso de programación en Oracle juegan un


papel muy importante. En el momento de crear las tablas se definen características a dos
niveles: Tabla y Columna, como se muestra a continuación:

A nivel de tabla: Refieren a una o a varias columnas, donde cada columna se define
individualmente.

Nombre: Nombre de la tabla puede ser de 1 a 30 caracteres. La tabla tiene


como propietario al usuario que las crea. Por ejemplo: EQUIPO.
Hay que tener en cuenta también ciertas restricciones con los
nombres de las tablas: longitud máxima de 30 caracteres, no
puede haber nombres de tabla duplicados, deben comenzar con
un carácter alfabético, permitir caracteres alfanuméricos y el
guión bajo '_', y Oracle no distingue entre mayúsculas y
minúsculas.

La tabla tiene como propietario al usuario que las crea En nuestro


caso somos el usuario ALUMNO. Otro usuario que desee usar
Propietario:
nuestras tablas debe tener autorización para ello y hacer
referencia a la tabla como ALUMNO.EQUIPO (propietario.tabla)

Cantidad de
Una tabla puede tener un máximo de 254 columnas.
Columnas:

A nivel de Columna el nombre de la columna puede tener un máximo de 30 caracteres.

En Oracle podemos implementar diversos tipos de tablas. A continuación se presenta una


recopilación no exhaustiva de ellas.

Tipo Tabla Descripción


Son el mecanismo de almacenamiento de los datos en una base
de datos Oracle. Contienen un conjunto fijo de columnas. Las
Regular columnas de una tabla describen los atributos de la entidad que
(heap) se representa con la tabla. Cada columna tiene un nombre y
características específicas: tipo de dato y longitud, restricciones,
etc.

Un cluster proporciona un método opcional de almacenar datos


de tabla. Un cluster está compuesto de un grupo de tablas que
Clustered
comparten los mismos bloques de datos. Las tablas son
agrupadas mediante columnas comunes.

Aquí una tabla es almacenada en la estructura de un índice.


Esto impone orden físico a las filas por si mismas. A diferencia
Index de un heap, donde los datos son almacenados en donde caben,
en una tabla IOT (Tabla Organizada por Índices) los datos son
almacenados en el orden de la clave primaria.

Es un esquema de organización de los datos con el cual


podemos dividirla en múltiples objetos de almacenamientos
llamados particiones de datos o rangos, dependiendo los
Particionada
valores puede ser dividido en uno o más columnas de la tabla.
s
Cada particiones de datos es almacenado separadamente.
Estos objetos almacenados pueden estar en diferentes
tablespaces, en el mismo o en una combinación de ambos.

Son tablas cuyos datos permanecerán en el sistema sólo


Temporales
durante el tiempo que dure la transacción o sesión involucrada.
No obstante, al igual que para las tablas permanentes, la
definición de las tablas temporales se almacena en las tablas
del sistema.

La sintaxis del comando que permite crear un tabla es la siguiente:

Del examen de la sintaxis de la sentencia Create Table se pueden concluir que necesitamos
conocer los distintos tipos de columna y las distintas restricciones que se pueden imponer al
contenido de las columnas.

Existen varios tipos de datos en SQL. De esta manera, cada columna puede albergar una
información de naturaleza distinta. Los tipos de datos más comunes y sus características en
Oracle Express (10 Y 11g) se resumen en la siguiente tabla. Las versiones de Oracle
comercial soportan una gama mucho más amplia de tipos de datos.

Tipo de Dato Descripción


Contiene datos binarios con un tamaño máximo de 4
gigabytes. Los datos binarios nos van a permitir guardar
en la base de datos archivos, imágenes, sonidos, etc ...
BLOB Casi siempre es preferible guardar la ruta del archivo en
la base de datos en lugar del propio archivo en modo
binario, pero existen ciertas circunstancias en las que no
nos queda otra solución.

BINARY_DOUBLE Precisión doble

BINARY_FLOAT Precisión simple

Un tipo de datos CLOB de Oracle contiene datos de


caracteres basados en el juego de caracteres
predeterminados del servidor. Su tamaño máximo es de
CLOB
4 gigabytes. Se asigna a cadena.

Use la siguiente expresión para una consulta de un


campo CLOB

SELECT DBMS_LOB.substr(campo,
DBMS_LOB.getlength(campo), 1)
FROM tablaprueba;
Almacena datos de tipo carácter alfanumérico de longitud
CHAR
fija, con un tamaño máximo de 2000. caracteres

Almacena fechas desde el 1-Ene-4712 AC hasta el 31-


DATE
Dic-4712 DC.

Datos numéricos de n dígitos, de los cuales dec son


NUMBER(dig [, dec])
decimales. El tamaño máximo es de 38 dígitos.

Almacena un valor alfanumérico de longitud variable en


NVARCHAR2 caracteres Unicode con las mismas restricciones de
varchar.

Fecha y hora (incluidos los segundos), con un tamaño


TIMESTAMP
que abarca desde 7 a 11 bytes.

Guarda datos de tipo carácter alfanumérico de longitud


VARCHAR2(tamaño)
variable, con un tamaño máximo de 4,000 caracteres.

Ejemplo: Considere la siguiente tabla de datos correspondientes a los campeones de


Formula 1 (1950 - 2012) y sus escuderías. Y su traducción a sentencias Oracle.

Año Campeón Escudería


201
- -
2

2011 Sebastian Vettel Red Bull Racing

201
Sebastian Vettel Red Bull Racing
0

200
Jenson Button Brawn GP
9

200
Lewis Hamilton McLaren
8

200
Kimi Raikkonen Ferrari
7

200
Fernando Alonso Renault
6
200
Fernando Alonso Renault
5

200
Michael Schumacher Ferrari
4

200
Michael Schumacher Ferrari
3

200
Michael Schumacher Ferrari
2

200
Michael Schumacher Ferrari
1

200
Michael Schumacher Ferrari
0

CREATE TABLE f1 (
year INTEGER PRIMARY KEY,
campeon CHAR(30),
escuderia CHAR(20)
);

Ejemplo: Estados, capitales, densidad de población y superficie de la Republica Mexicana

CREATE TABLE estados (


idEstado INTEGER PRIMARY KEY,
nombreEstado CHAR(25) NOT NULL,
capital CHAR(25) NOT NULL,
densidad INTEGER NOT NULL,
poblacion INTEGER NOT NULL
);

Tablas Temporales

Oracle permite la creación de tablas temporales para mantener datos propios y exclusivos a
una sesión Oracle determinada. Estos datos permanecerán en el sistema sólo durante el
tiempo que dure la transacción o sesión involucrada. No obstante, al igual que para las tablas
permanentes, la definición de las tablas temporales se almacena en las tablas del sistema.

La siguiente sintaxis permite crear una tabla temporal personal para cada sesión. Eso
significa que los datos no se comparten entre sesiones y se eliminan al final de la misma.
CREATE GLOBAL TEMPORARY TABLE [ schema. ]table (
nombreColumna tipoDato [DEFAULT expresión] [NOT NULL],
[,nombre_columna tipo_dato [DEFAULT expresión]
[restricción_columna] ...
|restricción_tabla];
ON COMMIT { DELETE | PRESERVE } ROWS ]
[ physical_properties ]

Con la opción ON COMMIT DELETE ROWS se borran los datos cada vez que se hace
COMMIT en la sesión.
Con la opción ON PRESERVE DELETE ROWS los datos no se borran hasta el final de la
sesión.

Sus ventajas son varias, la información contenida en ella esta solo disponible para la sesión
actual, cualquier inserción, borrado, actualización solo se refleja en la sesión activa.

Muchas funcionalidades de cualquier tabla normal se mantienen en ella, como triggers a nivel
tabla, vistas, índices, exportar e importar (claro solo la definición de la tabla).

No es posible declarar llaves foráneas en una tabla temporal.

(DROP) Eliminación

Cuando una tabla ya no es útil y no vamos a volver a necesitarla debe ser borrada. Esta
operación se puede realizar con el comando DROPTABLE.

DROP TABLE nombre_tabla [CASCADE CONSTRAINTS][PURGE]

Se borra la tabla de la base de datos, borrando toda la información contenida en la tabla, es


decir, todas las filas. También se borrará toda la información que sobre la tabla existiera en el
diccionario.
Si alguna columna de la tabla a borrar sirve como clave ajena de alguna tabla detalle, impide
la eliminación de la tabla, ya que existe una restricción que requiere de la existencia de la
tabla maestra. Esto se puede arreglar colocando la sentencia CASCADE CONSTRAINTS.

Esto produce que las restricciones de la tabla detalle se borren antes de borrar la tabla
maestra. PURGE evita que los objetos borrados se vayan a la papelera

La siguiente sentencia produce la eliminación de la tabla BORRAME.


(ALTER) Modificación

Oracle permite modificar las restricciones definidas para una tabla. Esto puede llevar a
“inconsistencia” de los datos ya introducidos en la base de datos. Por ello, Oracle tiene
definidos mecanismos para modificación de los datos ya existentes.

Esta operación se puede realizar con el comando ALTER TABLE.

ALTER TABLE [esquema.]tabla


clausula_constraint [,…]
[ENABLE clausula_activa | DISABLE clausula_disable]
[{ENABLE|DISABLE} TABLE LOCK]
[{ENABLE|DISABLE} ALL TRIGGERS];

Hay que tener en cuenta varios puntos:

 No es posible disminuir el tamaño de una columna, si esta contiene


datos.

 En las modificaciones, los tipos anterior y nuevo deben ser compatibles,


o la tabla debe estar vacía.

 La opción ADD ... NOT NULL sólo será posible si la tabla está vacía.

 La opción MODIFY ... NOT NULL sólo podrá realizarse cuando la tabla
no contenga ninguna fila con valor nulo en la columna en cuestión.

Considere el ejemplo Propietario - Automóvil, bajo el criterio de hacienda del Gobierno del
Estado de Veracruz, México. Modificaremos el ejemplo para añadir el atributo color.
ALTER TABLE automovil
ADD(color CHAR(15) NOT NULL);

ARCHIVO CREATE TABLE AUTOMOVIL

Es factible modificar una tabla añadiendo o eliminando restricciones, en este caso para el
ejemplo anterior el comando a utilizar será

ALTER TABLE tabla {ADD | DROP} CONSTRAINT restricción;

ALTER TABLE automovil DROP CONSTRAINT FK_Propietario;

ALTER TABLE automovil ADD


CONSTRAINT FK_Propietario FOREIGN KEY (idPropietario)
REFERENCES propietario (idPropietario)
ON DELETE CASCADE;

El cual permitira el borrado en cascada.

MySQL

MySQL soporta varios motores de almacenamiento que tratan con distintos tipos de tabla.
Los motores de almacenamiento de MySQL incluyen algunos que tratan con tablas
transaccionales y otros que no lo hacen:
 MyISAM trata tablas no transaccionales. Proporciona almacenamiento y recuperación de
datos rápida, así como posibilidad de búsquedas fulltext.MyISAM se soporta en todas
las configuraciones MySQL, y es el motor de almacenamiento por defecto a no ser que tenga
una configuración distinta a la que viene por defecto con MySQL.
El motor de almacenamiento MEMORY proporciona tablas en memoria. El motor de
almacenamiento MERGE permite una colección de tablas MyISAM idénticas ser tratadas
como una simple tabla. Como MyISAM, los motores de almacenamiento MEMORY y MERGE
tratan tablas no transaccionales y ambos se incluyen en MySQL por defecto.
Nota: El motor de almacenamiento MEMORY anteriormente se conocía como HEAP.
 Los motores de almacenamiento InnoDB y BDB proporcionan tablas transaccionales. BDB
se incluye en la distribución binaria MySQL-Max en aquellos sistemas operativos que la
soportan. InnoDB también se incluye por defecto en todas las distribuciones binarias de
MySQL 5.0 . En distribuciones fuente, puede activar o desactivar estos motores de
almacenamiento configurando MySQL a su gusto.
 El motor de almacenamiento EXAMPLE es un motor de almacenamiento 'tonto' que no
hace nada. Puede crear tablas con este motor, pero no puede almacenar datos ni
recuperarlos. El objetivo es que sirva como ejemplo en el código MySQL para ilustrar cómo
escribir un motor de almacenamiento. Como tal, su interés primario es para desarrolladores.
 NDB Cluster es el motor de almacenamiento usado por MySQL Cluster para
implementar tablas que se particionan en varias máquinas. Está disponible en distribuciones
binarias MySQL-Max 5.0. Este motor de almacenamiento está disponible para linux, Solaris, y
Mac OS X. Los autores mencionan que se añadirá soporte para este motor de
almacenamiento en otras plataformas, incluyendo Windows en próximas versiones.
 El motor de almacenamiento ARCHIVE se usa para guardar grandes cantidades de datos sin
índices con una huella muy pequeña.
 El motor de almacenamiento CSV guarda datos en archivos de texto usando formato de
valores separados por comas.
 El motor de almacenamiento FEDERATED se añadió en MySQL 5.0.3. Este motor guarda
datos en una base de datos remota. En esta versión sólo funciona con MySQL a través de la
API MySQL C Client. En futuras versiones, será capaz de conectar con otras fuentes de datos
usando otros drivers o métodos de conexión clientes.

La versión 5 de MySQL crea por defecto tablas innoDB que permiten el manejo de integridad
referencial, transacciones. Al igual que las tablas regulares de oracle. Para saber si el gestor
de base de datos de MySQL que tenemos las soporta es necesario ejecutar la siguiente
sentencia.

SHOW VARIABLES liKE '%innodb%';

Si nuestro gestor soporta por defecto las tablas innodb las sentencias para crear las tablas
previamente mostradas serán exactamente igual a las de oracle. En caso contrario se
muestra la sintaxis correspondiente

CREATE TABLE f1 (
year INTEGER PRIMARY KEY,
campeon CHAR(30),
escuderia CHAR(20)
) ENGINE = InnoDB;

Ejemplo: Estados, capitales, densidad de población y superficie de la Republica Mexicana

CREATE TABLE estados (


idEstado INTEGER PRIMARY KEY,
nombreEstado CHAR(25) NOT NULL,
capital CHAR(25) NOT NULL,
densidad INTEGER NOT NULL,
poblacion INTEGER NOT NULL
) ENGINE = InnoDB;

Comando Describe

MySQL proporciona este comando que resulta útil para conocer la estructura de una tabla,
las columnas que la forman y su tipo y restricciones. La sintaxis es la siguiente DESCRIBE
nombreTabla.

DESCRIBE estados;

Comando SHOW TABLES y SHOW CREATE TABLE

El comando SHOW TABLES muestra las tablas dentro de una base de datos y SHOW
CREATE TABLES muestra la estructura de creación de la tabla.

Tablas temporales

Las tablas temporales solo existen mientras la sesión está viva . Si se corre este
código en un script de PHP ( Cualquier otro lenguaje), la tabla temporal se destruirá
automáticamente al termino de la ejecución de la página. Si no específica MEMORY, la tabla
se guardará por defecto en el disco.

CREATE TEMPORARY TABLE temporal (


ife INTEGER(13) PRIMARY KEY,
nombre CHAR(30) NOT NULL UNIQUE
);

 Este tipo de tabla solo puede ser usada por el usuario que la crea.
 Si creamos una tabla que tiene el mismo nombre que una existente en la base de datos, la
que existe quedará oculta y trabajaremos sobre la temporal.

Tablas Memory ( Head )


 Se almacenan en memoria
 Una tabla head no puede tener más de 1600 campos
 Las tablas MEMORY usan una longitud de registro fija.
 MEMORY no soporta columnas BLOB o TEXT.
 MEMORY en MySQL 5.0 incluye soporte para columnas AUTO_INCREMENT e índices en
columnas que contengan valores NULL.
 Las tablas MEMORY se comparten entre todos los clientes (como cualquier otra tabla no-
TEMPORARY).

CREATE TEMPORARY TABLE temporal (


ife INTEGER(13) PRIMARY KEY,
nombre CHAR(30) NOT NULL UNIQUE
) ENGINE = MEMORY;

Modificación

Esta operación se puede realizar con el comando ALTER TABLE. Para usar ALTER TABLE,
necesita permisos ALTER, INSERT y CREATE para la tabla. La sintaxis para MySQL es:

ALTER [IGNORE] TABLE tbl_name


alter_specification [, alter_specification] ...;

alter_specification:
ADD [COLUMN] column_definition [FIRST | AFTER col_name ]
| ADD [COLUMN] (column_definition,...)
| ADD INDEX [index_name] [index_type] (index_col_name,...)
| ADD [CONSTRAINT [symbol]]
PRIMARY KEY [index_type] (index_col_name,...)
| ADD [CONSTRAINT [symbol]]
UNIQUE [index_name] [index_type] (index_col_name,...)
| ADD [FULLTEXT|SPATIAL] [index_name] (index_col_name,...)
| ADD [CONSTRAINT [symbol]]
FOREIGN KEY [index_name] (index_col_name,...)
[reference_definition]
| ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
| CHANGE [COLUMN] old_col_name column_definition
[FIRST|AFTER col_name]
| MODIFY [COLUMN] column_definition [FIRST | AFTER col_name]
| DROP [COLUMN] col_name
| DROP PRIMARY KEY
| DROP INDEX index_name
| DROP FOREIGN KEY fk_symbol
| DISABLE KEYS
| ENABLE KEYS
| RENAME [TO] new_tbl_name
| ORDER BY col_name
| CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
| [DEFAULT] CHARACTER SET charset_name [COLLATE collation_name]
| DISCARD TABLESPACE
| IMPORT TABLESPACE
| table_options

Considere el ejemplo Propietario - Automóvil, bajo el criterio de hacienda del Gobierno del
Estado de Veracruz, México. Modificaremos el ejemplo para añadir el atributo color según la
sintaxis MySQL

ALTER TABLE automovil


ADD(color CHAR(15) NOT NULL);
CREATE TABLE propietario (
idPropietario INTEGER NOT NULL AUTO_INCREMENT,
nombre CHAR(35) NOT NULL,
direccion CHAR(50) NOT NULL,
colonia CHAR(40) NOT NULL,
localidad CHAR(25) NOT NULL,
rfc CHAR(14),
telefono CHAR(14),
CONSTRAINT PK_propietario PRIMARY KEY (idPropietario)
) ENGINE = InnoDB;

CREATE TABLE automovil (


idAutomovil INTEGER NOT NULL AUTO_INCREMENT,
idPropietario INTEGER,
placa CHAR(12) NOT NULL,
marca CHAR(18) NOT NULL,
cveVehicular INTEGER(3) NOT NULL,
linea CHAR(18) NOT NULL,
numeroSerie CHAR(25) NOT NULL,
subLinea CHAR(18) NOT NULL,
origen CHAR(20) NOT NULL,
clase CHAR(14) NOT NULL,
modelo CHAR(18) NOT NULL,
fechaAlta CHAR(18) NOT NULL,
CONSTRAINT PK_Automovil PRIMARY KEY (idAutomovil),
CONSTRAINT FK_Propietario FOREIGN KEY (idPropietario)
REFERENCES propietario (idPropietario)
)ENGINE = InnoDB;

Ejemplo: Eliminar una llave foránea


ALTER TABLE automovil DROP FOREIGN KEY FK_Propietario;

Ejemplo: Agregar una llave foranea con borrado en cascada

ALTER TABLE automovil ADD


CONSTRAINT FK_Propietario
FOREIGN KEY (idPropietario)
REFERENCES propietario (idPropietario)
ON DELETE CASCADE;

Puede ejecutar múltiples cláusulas ADD, ALTER, DROP, y CHANGE en un único comando
ALTER TABLE. Esta es una extensión MySQL al estándar SQL, que permite sólo una de
cada cláusula por comando ALTER TABLE.

Integridad referencial

Una vez definida la estructura de datos del modelo relacional, pasamos a estudiar las reglas
de integridad, es decir que los datos almacenados en dicha estructura deben cumplir ciertas
características para garantizar que son correctos. Al definir cada atributo sobre un dominio se
impone una restricción sobre el conjunto de valores permitidos para cada atributo.

A este tipo de restricciones se les denomina restricciones de dominios. Hay además dos
reglas de integridad muy importantes que se deben cumplir en todas las bases de datos
relacionales y en todos sus estados o instancias (las reglas se deben cumplir todo el tiempo).
Estas reglas son la regla de integridad de entidades y la regla de integridad referencial.
Antes de definirlas, es preciso conocer el concepto de nulo.
Restricciones de dominios

Imponen una limitación al conjunto de valores permitidos para los atributos en las relaciones.
Permitiendo restringir los valores que puede tomar un atributo respecto a su dominio, por
ejemplo EDAD >= 18.

Nulos

Cuando en una tupla un atributo es desconocido, se dice que es nulo. Un nulo no representa
el valor cero ni la cadena vacía, éstos son valores que tienen significado. El nulo implica
ausencia de información, bien porque al insertar la tupla se desconocía el valor del atributo, o
bien porque para dicha tupla el atributo no tiene sentido.

Ya que los nulos no son valores, deben tratarse de modo diferente, lo que causa problemas
de implementación en los SGBD relacionales.

NULL|NOT NULL. Determina si se permiten valores NULL en la columna.

 ORACLE: El optimizador necesita saber que una columna no es NOT NULL, y sin este
conocimiento, se limita a elegir un plan de ejecución inferior al óptimo.
 SQL SERVER: NULL no es estrictamente una restricción, pero se puede especificar de la
misma forma que NOT NULL. La restricción se puede usar para las columnas calculadas sólo
si se especifica también PERSISTED.
 MySQL 5.02 Si la columna puede tener NULL como valor, la columna se define con una
cláusula DEFAULT NULL explícita. En caso contrario no define DEFAULT explícito.

Restricción UNIQUE

En un índice UNIQUE todos los valores en el índice deben ser distintos. Ocurre un error si
intenta añadir un nuevo registro con una clave que coincida con un registro existente. La
excepción es que una columna en el índice puede contener valores NULL múltiples

Cláusula check

Un constraint check específica una condición en cada renglón de la tabla.

 Un constraint check no puede ser definida en una vista.


 Un constraint check puede usar solamente columnas en las misma tabla.
 Un constraint check no puede ser incluida en una subconsulta.

Ejemplo: Se presentan 4 reglas de integridad de dominio.

 En el primer caso la no nulidad del campo nombreProveedor


 La no nulidad de forma ímplícíta del campo idProveedor al ser declarado llave primaria
(pkProveedor)
 La tercera regla obliga que el idProveedor este en el rango de 1,000 a 9,999 (check_id)
 El constraint dom_nombreProveedor obliga a que el nombre del proveedor se escriba en
mayúscula

CREATE TABLE proveedores (


idProveedor INTEGER(4),
nombreProveedor CHAR(50) NOT NULL,
CONSTRAINT pkProveedores PRIMARY KEY (idProveedor),
CONSTRAINT check_id CHECK (idProveedor BETWEEN 1000 AND 9999),
CONSTRAINT dom_nombreProveedor CHECK (nombreProveedor =
UPPER(nombreProveedor))
) ENGINE = InnoDB;

CREATE TABLE proveedores (


idProveedor NUMBER(4),
nombreProveedor CHAR(50) NOT NULL,
CONSTRAINT pkProveedores PRIMARY KEY (idProveedor),
CONSTRAINT check_id CHECK (idProveedor BETWEEN 1000 AND 9999)
CONSTRAINT dom_nombreProveedor CHECK (nombreProveedor =
UPPER(nombreProveedor))
);

-- MySQL
CREATE TABLE proveedores (
idProveedor INTEGER(4),
nombreProveedor CHAR(50),
CONSTRAINT pkProveedores PRIMARY KEY (idProveedor),
CONSTRAINT dom_idProveedor
CHECK (idProveedor BETWEEN 100 AND 9999),
CONSTRAINT dom_nombreProveedor
CHECK (nombreProveedor = UPPER(nombreProveedor))
) ENGINE = InnoDB;
-- Oracle
CREATE TABLE proveedores (
idProveedor NUMBER(4),
nombreProveedor CHAR(50),
CONSTRAINT pkProveedores PRIMARY KEY (idProveedor),
CONSTRAINT dom_idProveedor
CHECK (idProveedor BETWEEN 100 AND 9999),
CONSTRAINT dom_nombreProveedor
CHECK (nombreProveedor = UPPER(nombreProveedor))
);

-- MySQL y Oracle

ALTER TABLE proveedores


ADD CONSTRAINT dom_nombreProveedor
CHECK (nombreProveedor IN ('HP','IBM', 'Microsoft', 'SONY'));

Ejemplo: ALTER TABLE

Mediante esté constraint se restrige el nombre de los proveedores validos

ALTER TABLE proveedores


ADD CONSTRAINT dom_nombreProveedor
CHECK (nombreProveedor
IN ('DELL', 'HP','IBM', 'MICROSOFT', 'SONY'));

Regla de integridad de entidades

Una PRIMARY KEY es una llave única donde todas las columnas de la clave deben
definirse como NOT NULL. Si no se declaran explícitamentecomo NOT NULL, el gestor las
declara implícitamente. Una tabla puede tener sólo una PRIMARY KEY

 La primera regla de integridad se aplica a las claves primarias de las relaciones base: ninguno
de los atributos que componen la clave primaria puede ser nulo.
 Por definición, una clave primaria es un identificador irreducible que se utiliza para identificar
de modo único las tuplas. Irreducible significa que ningún subconjunto de la clave primaria
sirve para identificar otra tupla. Los campos que conforman una llave primaria son por defecto
no nulas.

Nótese que esta regla sólo se aplica a las relaciones base y a las claves primarias, no a las
claves alternativas.

Regla de integridad referencial

La segunda regla de integridad se aplica a las claves ajenas o foraneas: si en una relación
hay alguna clave ajena, sus valores deben coincidir con valores de la clave primaria a la que
hace referencia, o bien, deben ser completamente nulos.

La regla de integridad referencial se enmarca en términos de estados de la base de datos:


indica lo que es un estado ilegal, pero no dice cómo puede evitarse. La cuestión es ¿qué
hacer si estando en un estado legal, llega una petición para realizar una operación que
conduce a un estado ilegal? Existen dos opciones: rechazar la operación, o bien aceptar la
operación y realizar operaciones adicionales compensatorias que conduzcan a un estado
legal.

Por lo tanto, para cada clave ajena de la base de datos habrá que contestar a tres preguntas:

 Regla de los nulos: Los campos involucrados en llaves primarias son por definición no
nulos.
 Regla de borrado: ¿Qué ocurre si se intenta borrar la tupla referenciada por la clave ajena?
o Restringir: no se permite borrar la tupla referenciada.
o Propagar: se borra la tupla referenciada y se propaga el borrado a las tuplas que la referencian
mediante la clave ajena - borrado en cascada-.
o Anular: se borra la tupla referenciada y las tuplas que la referenciaban ponen a nulo la clave ajena
(sólo si acepta nulos) - SET NULL-.
 Regla de modificación: ¿Qué ocurre si se intenta modificar el valor de la clave primaria de
la tupla referenciada por la clave ajena?
o Restringir: no se permite modificar el valor de la clave primaria de la tupla referenciada.
o Propagar: se modifica el valor de la clave primaria de la tupla referenciada y se propaga la
modificación a las tuplas que la referencian mediante la clave ajena. Oracle no permite la
modificación en cascada.
o Anular: se modifica la tupla referenciada y las tuplas que la referenciaban ponen a nulo la clave
ajena (sólo si acepta nulos).

En Oracle y MySQL la clausula ON DELETE dice como comportarse si se borra el registro


“padre”:

1. Si no se especifica nada, por defecto saltará un error


2. CASCADE. Borrará los registros hijos.

Ejemplo: Considere la relación departamentos y empleados. Es posible modificar el


CONSTRAINT para que acepte el borrado en cascada.
DROP TABLE IF EXISTS empleado, departamento

CREATE TABLE departamento (


idDepartamento INTEGER(3),
nombre CHAR(15) NOT NULL,
ciudad CHAR(10) NOT NULL,
CONSTRAINT DOM_Ciudad
CHECK (ciudad IN ('Veracruz', 'Xalapa', 'Orizaba', 'Regional')),
CONSTRAINT PK_Departamento PRIMARY KEY (idDepartamento)
) ENGINE = InnoDB;

CREATE TABLE empleado(


idEmpleado INTEGER,
rfc CHAR(14),
nombreEmpleado CHAR(40) NOT NULL,
oficio CHAR(11) NOT NULL,
cargo CHAR( 9) NOT NULL,
jefe INTEGER,
ingreso DATE NOT NULL,
salario DECIMAL(10,2),
comision DECIMAL(10,2),
idDepartamento INTEGER(3) NOT NULL,
CONSTRAINT PK_Empleado PRIMARY KEY (idEmpleado),
CONSTRAINT AK_Empleado UNIQUE (rfc),
CONSTRAINT FK_EmpJefe FOREIGN KEY (jefe) REFERENCES empleado
(idEmpleado),
CONSTRAINT FK_Empleado FOREIGN KEY (idDepartamento)
REFERENCES departamento (idDepartamento),
CONSTRAINT D_Salario CHECK ( salario > 0 ),
CONSTRAINT D_NombreEmpleado CHECK (nombreEmpleado =
UPPER(nombreEmpleado))
) ENGINE = InnoDB;

ejemplo:
DROP TABLE IF EXISTS empleado, departamento;

CREATE TABLE departamento (


idDepartamento INTEGER(3),
nombre CHAR(15) NOT NULL,
ciudad CHAR(10) NOT NULL,
CONSTRAINT DOM_Ciudad CHECK (ciudad IN ('Veracruz', 'Xalapa', 'Orizaba',
'Regional')),
CONSTRAINT PK_Departamento PRIMARY KEY (idDepartamento)
) ENGINE = InnoDB;

CREATE TABLE empleado(


idEmpleado INTEGER,
rfc CHAR(14),
nombreEmpleado CHAR(40) NOT NULL,
oficio CHAR(11) NOT NULL,
cargo CHAR( 9) NOT NULL,
jefe INTEGER,
ingreso DATE NOT NULL,
salario DECIMAL(10,2),
comision DECIMAL(10,2),
idDepartamento INTEGER(3) NOT NULL,
CONSTRAINT PK_Empleado PRIMARY KEY (idEmpleado),
CONSTRAINT AK_Empleado UNIQUE (rfc),
CONSTRAINT FK_EmpJefe FOREIGN KEY (jefe) REFERENCES empleado(idEmpleado),
CONSTRAINT FK_Depto FOREIGN KEY (idDepartamento) REFERENCES
departamento (idDepartamento),
CONSTRAINT D_Salario CHECK ( salario > 0 ),
CONSTRAINT D_NombreEmpleado CHECK (nombreEmpleado =
UPPER(nombreEmpleado))
) ENGINE = InnoDB;

CREATE GLOBAL TEMPORARY TABLE detalle (


rfc CHAR(14) PRIMARY KEY,
nombreEmpleado CHAR(40) NOT NULL,
salarioNeto NUMBER(10,2)
) ON COMMIT PRESERVE ROWS;

INSERT INTO detalle


SELECT rfc, nombreEmpleado, salario + salario*comision
FROM empleado
WHERE comision > 0;
El código para implementar el borrado es cascada si borramos un departamento borrar los
empleados que laboran en él es:

ALTER TABLE empleado


DROP CONSTRAINT FK_Empleado;
ALTER TABLE empleado ADD CONSTRAINT FK_Empleado
FOREIGN KEY (idDepartamento)
REFERENCES departamento (idDepartamento)
ON DELETE CASCADE;

Versión Oracle

DROP TABLE empleado CASCADE CONSTRAINTS;


DROP TABLE departamento CASCADE CONSTRAINTS;

CREATE TABLE departamento (


idDepartamento NUMBER(3),
nombre CHAR(15) NOT NULL,
ciudad CHAR(10) NOT NULL,
CONSTRAINT DOM_Ciudad
CHECK (ciudad IN ('Veracruz', 'Xalapa', 'Orizaba', 'Regional')),
CONSTRAINT PK_Departamento PRIMARY KEY (idDepartamento)
);

CREATE TABLE empleado(


idEmpleado NUMBER(3),
rfc CHAR(14),
nombreEmpleado CHAR(40) NOT NULL,
oficio CHAR(11) NOT NULL,
cargo CHAR(9) NOT NULL,
jefe NUMBER(3),
ingreso DATE NOT NULL,
salario NUMBER(10,2),
comision NUMBER(10,2),
idDepartamento NUMBER(3) NOT NULL,
CONSTRAINT PK_Empleado PRIMARY KEY (idEmpleado),
CONSTRAINT AK_Empleado UNIQUE (rfc),
CONSTRAINT FK_Empleado_Jefe FOREIGN KEY (jefe) REFERENCES Empleado,
CONSTRAINT FK_Empleado FOREIGN KEY (idDepartamento) REFERENCES
Departamento,
CONSTRAINT D_Empleado_Salario CHECK ( salario > 0 ),
CONSTRAINT D_Empleado_NombreEmpleado CHECK (nombreEmpleado =
UPPER(nombreEmpleado))
);

3. SET NULL. Pondrá los campos del registro hijo a null. Note que la clave ajena debe
permitir el valor nulo.

Sintaxis

CONSTRAINT FK_columna
FOREIGN KEY (columna1, columna2, ... columna_n)
REFERENCES TablaReferenciada (columna1, columna2, ... columna_n)
ON DELETE SET NULL

Ejemplo: Proveedor - Producto

CREATE TABLE IF NOT EXISTS proveedor (


idProveedor INTEGER,
nombreProveedor CHAR(50) NOT NULL,
contacto CHAR(50),
CONSTRAINT PK_Proveedor PRIMARY KEY (idProveedor)
) ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS productos (


idProducto INTEGER,
idProveedor INTEGER,
nombreProducto CHAR(50),
precioProducto DECIMAL(8,2),
CONSTRAINT PK_Productos PRIMARY KEY (idProducto),
CONSTRAINT FK_Proveedor
FOREIGN KEY (idProveedor)
REFERENCES proveedor(idProveedor)
ON DELETE SET NULL
) ENGINE = InnoDB;
DROP TABLE productos CASCADE CONSTRAINT;
DROP TABLE proveedor CASCADE CONSTRAINT;

CREATE TABLE proveedor (


idProveedor NUMBER(3),
nombreProveedor CHAR(50) NOT NULL,
contacto CHAR(50),
CONSTRAINT PK_Proveedor PRIMARY KEY (idProveedor)
);

CREATE TABLE productos (


idProducto NUMBER(5),
idProveedor NUMBER(3),
nombreProducto CHAR(50),
precioProducto NUMBER(8,2),
CONSTRAINT PK_Productos PRIMARY KEY (idProducto),
CONSTRAINT FK_Proveedor
FOREIGN KEY (idProveedor)
REFERENCES proveedor (idProveedor)
ON DELETE SET NULL
);

Reglas de negocio

Toda aplicación trata de reflejar parte del funcionamiento del mundo real, para automatizar
tareas que de otro modo serían llevadas a cabo de modo más ineficiente, o bien no podrían
realizarse. Para ello, es necesario que cada aplicación refleje las restricciones que existen en
el negocio dado, de modo que nunca sea posible llevar a cabo acciones no válidas. A las
reglas que debe seguir la aplicación para garantizar se les denomina reglas de negocio.

Ejemplos de tales reglas son:

 No permitir crear facturas pertenecientes a clientes inexistentes


 Controlar que el saldo negativo de un cliente nunca sobrepase cierta cantidad ,
 No emitir facturas sin RFC (Registro Federal de Causante)
 Limitar o cancelar los números de celular no registrados
 Limitar el servicio telefónico por falta de pago
En realidad, la información puede ser manipulada por muchos programas distintos: así, una
empresa puede tener un departamento de contabilidad que controle todo lo relacionado con
compras, cobros, etc., y otro departamento técnico, que esté interesado en relacionar
diversos parámetros de producción con los costes.

La visión que ambos departamentos tendrán de la información y sus necesidades serán


distintas, pero en cualquier caso siempre se deberán respetar las reglas de negocio. El
hecho de que la información sea manipulada por diversos programas hace más difícil
garantizar que todos respetan las reglas, especialmente si las aplicaciones corren en
diversas máquinas, bajo distintos sistemas operativos, y están desarrolladas con distintos
lenguajes y herramientas.

Ejemplo: Considere el diagrama entidad relación que a continuación se expone y su


correspondiente traducción a sentencias MySQL y Oracle. El cual involucra artistas, sus
discos y las canciones que contiene dicho disco.

CREATE TABLE artista (


idArtista INTEGER,
nombreArtista CHAR(35) NOT NULL,
CONSTRAINT pk_Artista PRIMARY KEY (idArtista),
CONSTRAINT ak_nombreArtista UNIQUE ( nombreArtista )
) ENGINE = InnoDB;

CREATE TABLE disco (


asin CHAR(12),
idArtista INTEGER NOT NULL,
nombreAlbum CHAR(20) NOT NULL,
yearLanzamiento INTEGER(4),
marca CHAR(20),
CONSTRAINT pk_disco PRIMARY KEY (asin),
CONSTRAINT fk_artistaDisco FOREIGN KEY (idArtista) REFERENCES artista
(idArtista)
) ENGINE = InnoDB;
CREATE TABLE canciones (
idCancion INTEGER,
asin CHAR(12) NOT NULL,
nombreCancion CHAR(30) NOT NULL,
duracion CHAR(6),
estilo CHAR(15),
CONSTRAINT pk_canciones PRIMARY KEY (idCancion),
CONSTRAINT fk_DiscoCanciones FOREIGN KEY (asin) REFERENCES disco (asin)
) ENGINE = InnoDB;

CREATE TABLE artista (


idArtista NUMBER,
nombreArtista CHAR(35) NOT NULL,
CONSTRAINT pk_Artista PRIMARY KEY (idArtista),
CONSTRAINT ak_nombreArtista UNIQUE ( nombreArtista )
);

CREATE TABLE disco (


asin CHAR(12),
idArtista NUMBER NOT NULL,
nombreAlbum CHAR(20) NOT NULL,
yearLanzamiento NUMBER(4),
marca CHAR(20),
CONSTRAINT pk_disco PRIMARY KEY (asin),
CONSTRAINT fk_artistaDisco FOREIGN KEY (idArtista) REFERENCES artista
(idArtista)
);

CREATE TABLE canciones (


idCancion NUMBER,
asin CHAR(12) NOT NULL,
nombreCancion CHAR(30) NOT NULL,
duracion CHAR(6),
estilo CHAR(15),
CONSTRAINT pk_canciones PRIMARY KEY (idCancion),
CONSTRAINT fk_DiscoCanciones FOREIGN KEY (asin) REFERENCES disco (asin)
);

Integridad referencial declativa

La integridad de los datos es la propiedad que asegura que información dada es correcta, al
cumplir ciertas aserciones.
Las restricciones de integridad aseguran que la información contenida en una base de datos
es correcta.

Las restricciones de integridad son propiedades de la base de datos que se deben satisfacer
en cualquier momento.

Tanto Oracle y MySql son sistemas de gestión de base de datos (SGBD) relacional que
permite la definición de restricciones de integridad dentro del diseño de su base de datos al
ser creada.

Las restricciones de integridad aseguran que la información contenida en la base de datos


cumple ciertas normas o reglas para los diferentes estados.

Existen dos tipos de restricciones:

 Estáticas: limitan los estados permitidos de la Base de Datos.


 Dinámicas: restringen las posibles transiciones de estados de la base datos.

Para incorporar el tratamiento de las restricciones de integridad en el sistema pueden


realizarse:

 Añadiendo código adicional para verificar y asegurar que se cumplen las restricciones
(Mecanismos declarativos: Procedure o Trigger
 Declarando las restricciones como parte del esquema de la base de datos.

La definición en la fase de diseño de las restricciones de integridad proporciona mayor


número de ventajas, ya que:

 Reduce el costo de desarrollo de software.


 Es más confiable al ser centralizado y uniforme.
 Mantenimiento más fácil.

De acuerdo con la forma de especificación del comando CREATE TABLE dada


anteriormente, la cláusula CONSTRAINT puede entonces tener las siguientes formas:
 CONSTRAINT <constraint_name> PRIMARY KEY (<column_name >[,<column_name>])
 CONSTRAINT <constraint_name> UNIQUE (<column_name>[,<column_name>])
 CONSTRAINT <constraint_name> FOREIGN KEY (<column_name>[,<column_name>])
REFERENCES <table_name>
 CONSTRAINT <constraint_name> CHECK (<condición>)

Donde:

 <constraint_name> es el nombre con el que se designará al CONSTRAINT en el esquema


donde se crea la tabla que lo incluye.
 <column_name> es el nombre de una columna de la tabla en la que se define el
CONSTRAINT
 <table_name> es el nombre de una tabla definida en el esquema donde existe la tabla que
incluye el CONSTRAINT.
 <condición> es una expresión lógica en SQL.

En el manual de referencia de SQL usted podrá encontrar información sobre las reglas de
formación de expresiones lógicas de SQL.

Un punto importantísimo a destacar es el de garantizar que los nombres de los


CONSTRAINT sean nemónicos. Toda vez que un CONSTRAINTsea violado, el SGBD
generará un mensaje de error indicando el CONSTRAINT que ha fallado. Asignar nombres
nemónicos permitirá hacer la depuración de programas y la carga de datos mucho más
sencilla, además de garantizar una perfecta cohesión entre el esquema de implantación y la
documentación del esquema lógico.
Es así como se sugiere utilizar el siguiente estándar de nomenclatura:

 Para restricciones de no-nulidad se recomienda no crear CONSTRAINT sino declarar la no-


nulidad al momento de crear la tabla y para cada columna.
 Para asociar un CONSTRAINT de clave primaria a una tabla <table_name> se recomienda
designar el “constraint" con el nombre PK_<table_name>.
 Para asociar un CONSTRAINT de unicidad relacionado con una clave alterna de la
tabla<table_name>, se recomienda designar el CONSTRAINT con el nombre
AK_<table_name>
 Para asociar un CONSTRAINT de clave foránea a una tabla <table_name1> que referencia a
una tabla <table_name2> designe el CONSTRAINT con el nombre
FK_<table_name1>_<table_name2>.
 Asociar un CONSTRAINT que represente una restricción de dominio sobre una columna
<column_name> de una tabla <table_name>, se sugiere utilizar
D_<table_name>__<column_name> como nombre del CONSTRAINT
 Para asociar un CONSTRAINT que represente una restricción explícita, descrita a través de
una restricciôn de tipo CHECK, de una tabla <table_name> use
EXP_<table_name>__R<constraint_number> como nombre del “constraint
constraint_number> representará el número de restricción explícita asociado en la
documentación del esquema relacional que se implanta.

Los CONSTRAINT pueden ser agregados a una tabla previamente creada, o eliminados de
una tabla existente. Para tal fin se pueden utilizar dos variaciones del comando ALTER
TABLE, cuya sintaxis a continuación se indica:

ALTER TABLE <table_name> ADD (<table_constraint> [,<table_constraint>]);

Permitirá agregar una o más CONSTRAINT a la tabla existente en la base de datos. Cada
uno de los CONSTRAINT que se añaden a la tabla seguirán las convenciones sintácticas de
la cláusula <table_constraint>.

ALTER TABLE <table_name> DROP CONSTRAINT <constraint_name> [CASCADE];

Eliminará de la tabla la restricción <constraint_name>.

Si se utiliza la cláusula CASCADE, la eliminación del CONSTRAINT tendrá como efecto


eliminar cualquier otro CONSTRAINT relacionado con elCONSTRAINT que se elimina.

Por ejemplo, si se elimina un CONSTRAINT de clave primaria de una tabla A bajo modalidad
CONSTRAINT entonces se eliminarán losCONSTRAINT de clave foránea que referencien a
A.

SOBRE LÍMITES

ORACLE impone los siguientes límites en lo que respecta a los objetos descritos en esta
sección:

 La longitud de cualquier identificador (nombre de tabla, nombre de columna, nombre de


"constraints", entre otros) se limita a un máximo de 30 caracteres.

 El número máximo de columnas que puede tener una tabla es de 1000.

 El número máximo de columnas que pueden constituir una clave primaria, una clave alterna o
una clave foránea es de 16.

Ejemplo: Torneo Primera División Federación Mexicana de Futbol


CREATE TABLE posicion (
idPosicion NUMBER(1),
nombrePosicion CHAR(20) NOT NULL,
CONSTRAINT PK_Posicion PRIMARY KEY (idPosicion)
);

CREATE TABLE nacionalidad (


idNacionalidad NUMBER(3),
nombreNacionalidad CHAR(20) NOT NULL,
CONSTRAINT PK_Nacionalidad PRIMARY KEY (idNacionalidad)
);

CREATE TABLE estadio (


idEstadio NUMBER(3),
nombreEstadio CHAR(25) NOT NULL,
direccion CHAR(35) NOT NULL,
codigoPostal NUMBER(5),
ciudad CHAR(30) NOT NULL,
fechaInaguracion DATE,
capacidad NUMBER NOT NULL,
foto CHAR(30),
CONSTRAINT PK_Estadio PRIMARY KEY (idEstadio)
);

CREATE TABLE equipo (


idEquipo NUMBER,
nombreEquipo CHAR(25) NOT NULL,
seudonimo CHAR(25) NOT NULL,
nombre_oficial CHAR(60) NOT NULL,
direccion CHAR(35) NOT NULL,
codigoPostal NUMBER(5),
ciudad CHAR(30) NOT NULL,
escudo CHAR(50),
fechaFundacion DATE,
paginaWeb CHAR(50) NOT NULL,
CONSTRAINT PK_Equipo PRIMARY KEY (idEquipo)
);

CREATE TABLE jugador (


idJugador NUMBER,
nombreJugador CHAR(40),
idEquipo NUMBER,
idPosicion NUMBER NOT NULL,
jj NUMBER DEFAULT 0,
jc NUMBER DEFAULT 0,
jt NUMBER DEFAULT 0,
ec NUMBER DEFAULT 0,
sc NUMBER DEFAULT 0,
minutos NUMBER DEFAULT 0,
goles NUMBER DEFAULT 0,
ta NUMBER DEFAULT 0,
tr NUMBER DEFAULT 0,
numero NUMBER NOT NULL,
fechaNacimiento DATE NOT NULL,
estatura NUMBER,
peso NUMBER,
idNacionalidad NUMBER DEFAULT 1,
CONSTRAINT PK_Jugador PRIMARY KEY (idJugador),
CONSTRAINT FK_Juega_En FOREIGN KEY (idEquipo) REFERENCES equipo
(idEquipo),
CONSTRAINT FK_Juega_Como FOREIGN KEY (idPosicion) REFERENCES posicion
(idPosicion),
CONSTRAINT FK_Origen FOREIGN KEY (idNacionalidad)
REFERENCES nacionalidad (idNacionalidad)
);

CREATE TABLE partido (


idPartido NUMBER,
jornada NUMBER(2) NOT NULL,
fecha DATE NOT NULL,
hora CHAR(5) NOT NULL,
idLocal NUMBER(3) NOT NULL,
golLocal NUMBER(2) DEFAULT 0,
idVisitante NUMBER(3) NOT NULL,
golVisitante NUMBER(3) DEFAULT 0,
idEstadio NUMBER(3) NOT NULL,
arbitro CHAR(50) NOT NULL,
asistente1 CHAR(50) NOT NULL,
asistentente2 CHAR(50) NOT NULL,
cJuez CHAR(50),
idEquipoLocal NUMBER(3) NOT NULL,
idEquipoVisitante NUMBER(3) NOT NULL,
CONSTRAINT PK_Partido PRIMARY KEY (idPartido),
CONSTRAINT FK_Partidos_En FOREIGN KEY (idEstadio) REFERENCES estadio
(idEstadio),
CONSTRAINT FK_Local FOREIGN KEY (idLocal) REFERENCES equipo
(idEquipo),
CONSTRAINT FK_Visitante FOREIGN KEY (idVisitante) REFERENCES equipo
(idEquipo)
);

CREATE TABLE posicion (


idPosicion INTEGER(1),
nombrePosicion CHAR(20) NOT NULL,
CONSTRAINT PK_Posicion PRIMARY KEY (idPosicion)
);

CREATE TABLE nacionalidad (


idNacionalidad INTEGER(3),
nombreNacionalidad CHAR(20) NOT NULL,
CONSTRAINT PK_Nacionalidad PRIMARY KEY (idNacionalidad)
);

CREATE TABLE estadio (


idEstadio INTEGER(3),
nombreEstadio CHAR(25) NOT NULL,
direccion CHAR(35) NOT NULL,
codigoPostal INTEGER(5),
ciudad CHAR(30) NOT NULL,
fechaInaguracion DATE,
capacidad INTEGER NOT NULL,
foto CHAR(30),
CONSTRAINT PK_Estadio PRIMARY KEY (idEstadio)
);

CREATE TABLE equipo (


idEquipo INTEGER,
nombreEquipo CHAR(25) NOT NULL,
seudonimo CHAR(25) NOT NULL,
nombre_oficial CHAR(60) NOT NULL,
direccion CHAR(35) NOT NULL,
codigoPostal INTEGER(5),
ciudad CHAR(30) NOT NULL,
escudo CHAR(50),
fechaFundacion DATE,
paginaWeb CHAR(50) NOT NULL,
CONSTRAINT PK_Equipo PRIMARY KEY (idEquipo)
);

CREATE TABLE jugador (


idJugador INTEGER,
nombreJugador CHAR(40),
idEquipo INTEGER,
idPosicion INTEGER NOT NULL,
jj INTEGER DEFAULT 0,
jc INTEGER DEFAULT 0,
jt INTEGER DEFAULT 0,
ec INTEGER DEFAULT 0,
sc INTEGER DEFAULT 0,
minutos INTEGER DEFAULT 0,
goles INTEGER DEFAULT 0,
ta INTEGER DEFAULT 0,
tr INTEGER DEFAULT 0,
numero INTEGER NOT NULL,
fechaNacimiento DATE NOT NULL,
estatura INTEGER,
peso INTEGER,
idNacionalidad INTEGER,
CONSTRAINT PK_Jugador PRIMARY KEY (idJugador),
CONSTRAINT FK_Juega_En FOREIGN KEY (idEquipo) REFERENCES equipo
(idEquipo),
CONSTRAINT FK_Juega_Como FOREIGN KEY (idPosicion) REFERENCES posicion
(idPosicion),
CONSTRAINT FK_Origen FOREIGN KEY (idNacionalidad)
REFERENCES nacionalidad (idNacionalidad)
);

CREATE TABLE partido (


idPartido INTEGER(5) NOT NULL,
jornada INTEGER(2) NOT NULL,
fecha DATE NOT NULL,
hora CHAR(5) NOT NULL,
idLocal INTEGER(3) NOT NULL,
golLocal INTEGER(2) DEFAULT 0,
idVisitante INTEGER(3) NOT NULL,
golVisitante INTEGER(3) DEFAULT 0,
idEstadio INTEGER(3) NOT NULL,
arbitro CHAR(50) NOT NULL,
asistente1 CHAR(50) NOT NULL,
asistente2 CHAR(50) NOT NULL,
cJuez CHAR(50),
idEquipoLocal INTEGER(3) NOT NULL,
idEquipoVisitante INTEGER(3) NOT NULL,
CONSTRAINT PK_Partido PRIMARY KEY (idPartido),
CONSTRAINT FK_Partidos_En FOREIGN KEY (idEstadio) REFERENCES estadio
(idEstadio),
CONSTRAINT FK_Local FOREIGN KEY (idLocal) REFERENCES equipo
(idEquipo),
CONSTRAINT FK_Visitante FOREIGN KEY (idVisitante) REFERENCES equipo
(idEquipo)
);

Ejemplo: El departamento de Postgrado e investigación del Tecnológico Virtual ha diseñado


una base de datos (BD) para la gestión de los proyectos de investigación en los que
participan sus investigadores.

Se presenta a continuación el diagrama Entidad Relación propuesto mismo que es


perfectible. Si lo hace justique sus cambios.
DROP TABLE asignado CASCADE CONSTRAINTS;
DROP TABLE proyecto CASCADE CONSTRAINTS;
DROP TABLE linea CASCADE CONSTRAINTS;
DROP TABLE investigador CASCADE CONSTRAINTS;
DROP TABLE depAcademico CASCADE CONSTRAINTS;

CREATE TABLE linea (


idLinea CHAR(20),
nombreLinea CHAR(100) NOT NULL,
financiadoPor CHAR(30) NOT NULL,
CONSTRAINT PK_Linea PRIMARY KEY (idLinea)
);

CREATE TABLE proyecto (


idProyecto CHAR(20),
idLinea CHAR(20) NOT NULL,
nombreProyecto CHAR(100) NOT NULL,
F_Inicio DATE NOT NULL,
F_Terminacion DATE NOT NULL,
Presupuesto NUMBER(10,0) NOT NULL,
CONSTRAINT PK_Proyecto PRIMARY KEY (idProyecto),
CONSTRAINT FK_Linea FOREIGN KEY (idLinea) REFERENCES
linea (idLinea)
);

CREATE TABLE depAcademico (


idDepartamento NUMBER,
Departamento CHAR(30) NOT NULL,
CONSTRAINT PK_DepAcademico PRIMARY KEY (idDepartamento)
);

CREATE TABLE investigador (


ife CHAR(13),
nombreInvestigador CHAR(50) NOT NULL,
telefono CHAR(10) NOT NULL,
email CHAR(50) NOT NULL,
idDepartamento NUMBER NOT NULL,
CONSTRAINT PK_Investigador PRIMARY KEY (ife),
CONSTRAINT FK_DepAcademico FOREIGN KEY (idDepartamento)
REFERENCES depAcademico (idDepartamento)
);
CREATE TABLE asignado (
ife CHAR(13) NOT NULL,
idProyecto CHAR(20) NOT NULL,
F_Inicio DATE NOT NULL,
F_Termino DATE,
tipoParticipacion CHAR(20) NOT NULL,
CONSTRAINT FK_Investigador FOREIGN KEY (ife) REFERENCES
investigador (ife),
CONSTRAINT FK_Proyecto FOREIGN KEY (idProyecto) REFERENCES
proyecto (idProyecto)
);

DROP TABLE IF EXISTS asignado, proyecto, linea, investigador,


depAcademico;

CREATE TABLE linea (


idLinea CHAR(20),
nombreLinea CHAR(100) NOT NULL,
financiadoPor CHAR(30) NOT NULL,
CONSTRAINT PK_Linea PRIMARY KEY (idLinea)
);

CREATE TABLE proyecto (


idProyecto CHAR(20),
idLinea CHAR(20) NOT NULL,
nombreProyecto CHAR(100) NOT NULL,
F_Inicio DATE NOT NULL,
F_Terminacion DATE NOT NULL,
Presupuesto DECIMAL(10,0) NOT NULL,
CONSTRAINT PK_Proyecto PRIMARY KEY (idProyecto),
CONSTRAINT FK_Linea FOREIGN KEY (idLinea) REFERENCES
LINEA (idLinea)
);

CREATE TABLE depAcademico (


idDepartamento INTEGER,
Departamento CHAR(30) NOT NULL,
CONSTRAINT PK_DepAcademico PRIMARY KEY (idDepartamento)
);

CREATE TABLE investigador (


ife CHAR(13),
nombreInvestigador CHAR(50) NOT NULL,
telefono CHAR(10) NOT NULL,
email CHAR(50) NOT NULL,
idDepartamento INTEGER NOT NULL,
CONSTRAINT PK_Investigador PRIMARY KEY (ife),
CONSTRAINT FK_DepAcademico FOREIGN KEY (idDepartamento)
REFERENCES depAcademico (idDepartamento)
);

CREATE TABLE asignado (


ife CHAR(13) NOT NULL,
idProyecto CHAR(20) NOT NULL,
F_Inicio DATE NOT NULL,
F_Termino DATE,
tipoParticipacion CHAR(20) NOT NULL,
CONSTRAINT FK_Investigador FOREIGN KEY (ife) REFERENCES
investigador (ife),
CONSTRAINT FK_Proyecto FOREIGN KEY (idProyecto) REFERENCES
proyecto (idProyecto));
UNIDAD II. LENGUAJE
DE MANIPULACIÓN DE
DATOS
2.1. INSERT

La sentencia INSERT permite agregar nuevas filas de datos a las tablas existentes.
Está sentencia tiene como sintaxis genérica.

INSERT INTO tabla_o_vista [(lista_de_columnas)] VALUES


(lista_de_valores_de_datos)

Para insertar datos en una relación, se específica la tupla que se desea insertar o
se formula una consulta cuyo resultado sea el conjunto de tuplas que se desea
insertar. Obviamente, los valores de los atributos de las tuplas que se inserten deben
pertenecer al dominio de los atributos. De igual modo, las tuplas insertadas deben
ser de la aridad -número de atributos- correcta.

Considere el siguiente Diagrama Entidad Relación y su correspondiente script Oracle

CREATE TABLE departamento (


idDepartamento NUMBER(3),
nombre CHAR(15) NOT NULL,
ciudad CHAR(10) NOT NULL,
CONSTRAINT DOM_Ciudad
CHECK (ciudad IN ('Veracruz', 'Xalapa', 'Orizaba', 'Regional')),
CONSTRAINT PK_Departamento PRIMARY KEY (idDepartamento)
);

CREATE TABLE empleado(


idEmpleado NUMBER(3),
rfc CHAR(14),
nombreEmpleado CHAR(40) NOT NULL,
oficio CHAR(11) NOT NULL,
cargo CHAR(9) NOT NULL,
jefe NUMBER(3),
ingreso DATE NOT NULL,
salario NUMBER(10,2),
comision NUMBER(10,2),
idDepartamento NUMBER(3) NOT NULL,
CONSTRAINT DOM_Empleado_Salario CHECK ( salario > 0 ),
CONSTRAINT PK_Empleado PRIMARY KEY (idEmpleado),
CONSTRAINT AK_Empleado UNIQUE (rfc),
CONSTRAINT FK_Empleado_Jefe FOREIGN KEY (jefe)
REFERENCES Empleado,
CONSTRAINT FK_Empleado FOREIGN KEY (idDepartamento)
REFERENCES Departamento,
CONSTRAINT DOM_Empleado_NombreEmpleado
CHECK (nombreEmpleado = NLS_UPPER(nombreEmpleado))
);
Considere los siguientes datos

Tabla: Departamento

idDepartament Departament
Ciudad
o o

1 Ventas Veracruz

2 Ventas Xalapa
3 Cobranza Veracruz

4 Cobranza Xalapa

5 Credito Orizaba

6 Credito Veracruz

7 Credito Xalapa

Un formato posible es:

INSERT INTO nombre-tabla VALUES (serie de valores);

El orden en el que se asignen los valores en la cláusula VALUES tiene que


coincidir con el orden en que se definieron las columnas en la creación del
objeto tabla, dado que los valores se asignan por posicionamiento relativo.

Por ejemplo:

INSERT INTO departamento VALUES (1,'Ventas','Veracruz');


INSERT INTO departamento VALUES (2,'Ventas','Xalapa');
INSERT INTO departamento VALUES (3,'Cobranza','Veracruz');
INSERT INTO departamento VALUES (4,'Cobranza','Xalapa');
INSERT INTO departamento VALUES (5,'Credito','Orizaba');
INSERT INTO departamento VALUES (6,'Credito','Veracruz');
INSERT INTO departamento VALUES (7,'Credito','Xalapa');

Otra forma de usar la sentecia INSERT es:

INSERT INTO nombre-tabla (columna1, columna2...)


VALUES (valor1, valor2...);

En este caso los valores se asignarán a cada una de las columnas mencionadas por
posicionamiento relativo.

Es necesario que por lo menos se asignen valores a todas aquellas columnas que
no admiten valores nulos en la tabla (NOT NULL).

Por ejemplo:
INSERT INTO empleado (idempleado, rfc, nombreempleado, oficio, cargo,
jefe, ingreso, salario, comision, idDepartamento) VALUES (12,
'ROTL790411FRT', 'ROMERO TERRENOS, LUIS', 'Ingeniero', 'Director', NULL,
'01/01/2006', 7000,0.2,4);
INSERT INTO empleado (idempleado, rfc, nombreempleado, oficio, cargo,
jefe, ingreso, salario, comision, idDepartamento) VALUES (5,
'NACA6411116TY', 'NAVARRO CARDOZA, ALEJANDRO', 'LAE', 'Gerente', 12,
'05/05/2004', 5000, 0.15, 2);
INSERT INTO empleado (idempleado, rfc, nombreempleado, oficio, cargo,
jefe, ingreso, salario, comision, idDepartamento) VALUES
(8,'ADRC6908085T4','ADAME RAMIREZ, CARLOS','LAE','Gerente', 12,
'11/05/2005', 5000, 0.15, 3);
INSERT INTO empleado (idempleado, rfc, nombreempleado, oficio, cargo,
jefe, ingreso, salario, comision, idDepartamento) VALUES (1,
'PECJ65030265T', 'PEREZ CARMONA, JUAN','Mecanico', 'Vendedor', 5,
'01/01/2002', 3000, 0.1, 1);
INSERT INTO empleado (idempleado, rfc, nombreempleado, oficio, cargo,
jefe, ingreso, salario, comision, idDepartamento) VALUES (2,
'GAZP721012RGR', 'GARCIA ZARATE, PEDRO', 'Chofer', 'Chofer', 5,
'05/06/2003', 3500, 0, 1);
INSERT INTO empleado (idempleado, rfc, nombreempleado, oficio, cargo,
jefe, ingreso, salario, comision, idDepartamento) VALUES
(3,'MOME89011068A', 'MORALEZ MORALES, ELIZABETH', 'Secretaria',
'Secretaria', 5, '5/08/2008', 3000, 0, 2);
INSERT INTO empleado (idempleado, rfc, nombreempleado, oficio, cargo,
jefe, ingreso, salario, comision, idDepartamento) VALUES
(4,'ZAVJ840612XYZ','ZARATE VALERIO, JUANA','Sin oficio', 'Vendedor', 5,
'4/01/2009', 2000,0.1,2);
INSERT INTO empleado (idempleado, rfc, nombreempleado, oficio, cargo,
jefe, ingreso, salario, comision, idDepartamento) VALUES
(6,'OLTF841123TYS','OLIVEROS TORRES, FANNY','Secretaria', 'Secretaria', 8,
'01/01/2009', 3000, 0, 3);
INSERT INTO empleado (idempleado, rfc, nombreempleado, oficio, cargo,
jefe, ingreso, salario, comision, idDepartamento) VALUES
(7,'CESS700313TRG','CEDILLO SALAS,SERGIO', 'Electrico', 'Cobrador', 8,
'10/07/2006', 4200, 0, 3);
INSERT INTO empleado (idempleado, rfc,nombreempleado, oficio, cargo, jefe,
ingreso, salario, comision, idDepartamento) VALUES (9, 'HEGZ781111YTD',
'HERNANDEZ GARCIA, ZAIDA', 'Finanzas', 'Gestor', 12, '01/01/2006', 6000, 0,
4);
INSERT INTO empleado (idempleado, rfc, nombreempleado, oficio, cargo,
jefe, ingreso, salario, comision, idDepartamento) VALUES (10,
'ROCR820506RGT', 'ROSALDO CASTRO, ROXANA', 'Finanzas', 'Gestor', 12,
'01/01/2006', 5000, 0, 4);
INSERT INTO empleado (idempleado, rfc, nombreempleado, oficio, cargo,
jefe, ingreso, salario, comision, idDepartamento) VALUES (11,
'RORP890911RFT', 'ROSAS RAMOS, PETRA', 'Secretaria', 'Secretaria', 12,
'01/01/2006',3500,0,4);

Insertar mediante un SELECT

CREATE GLOBAL TEMPORARY TABLE detalle (


rfc CHAR(14) PRIMARY KEY,
nombreEmpleado CHAR(40) NOT NULL,
salarioNeto NUMBER(10,2)
) ON COMMIT PRESERVE ROWS;

INSERT INTO detalle


SELECT rfc, nombreEmpleado, salario + salario*comision
FROM empleado
WHERE comision > 0;

Inserción por selección Sentencia WHEN

Ejemplo: Usaremos la cotización del dolar para solventar obligaciones el archivo


original contiene valores de 1995 al 18 de enero de 2011. Separemos esta tabla
en cotizaciones mayores de 14 pesos, entre 13 a 14 y otras

Utilice el script Dolar.SQL

2.2. UPDATE

En determinadas situaciones puede ser deseable cambiar un valor dentro de una


tupla, sin cambiar todos los valores de la misma. Para ello se utiliza el comando
UPDATE cuya sintaxis se muestra a continuación.

UPDATE tabla SET {columna = expresión,} + [WHERE condición;]

Se especificará en la cláusula SET las columnas que se actualizarán y con qué


valores. La cláusula WHERE indica las filas con las que se va a trabajar, sin la
cláusula WHERE la actualización afectará a todas las filas de la tabla.

Si se desea actualizar a nulos, se asignará el valor NULL.

UPDATE cliente SET observaciones = NULL;


Por ejemplo, cambie el nombre del departamento Credito por Crédito.

UPDATE Departamento SET nombre = 'Crédito' WHERE nombre = 'Credito';

La cláusula WHERE permite SELECT anidados como en el caso del INSERT o el


DELETE.

SQL ofrece el constructor CASE, que puede usarse para formular actualizaciones
dependientes. Por ejemplo;

CREATE TABLE moreliaC2012(


numero NUMBER(3),
nombreJugador CHAR(40),
posicion CHAR(4),
jj NUMBER(2),
jc NUMBER(2),
jt NUMBER(2),
ec NUMBER(2),
sc NUMBER(2),
minutos NUMBER(6),
gol NUMBER(4),
ppg NUMBER(2),
tr NUMBER(2),
ta NUMBER(2)
);

INSERT INTO moreliaC2012 VALUES(3,'Federico


Vilar','POR',2,2,2,0,0,180,4,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Jesús
Urbina','POR',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Carlos Felipe
Rodríguez','POR',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(25,'Alonso
Arciga','POR',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(16,'Adrián
Aldrete','DEF',2,2,2,0,0,180,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(2,'Enrique
Pérez','DEF',2,2,2,0,0,180,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(24,'Marvin
Cabrera','DEF',2,1,2,0,1,147,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(33,'Joel
Huiqui','DEF',1,1,1,0,0,90,0,0,1,0);
INSERT INTO moreliaC2012 VALUES(0,'Diego
Jiménez','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Francisco Javier
Dorame','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Alberto
Lucio','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Marvin de la
Cruz','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(19,'Oscar Francisco
Razo','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Luis Fernando
Silva','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(5,'Mauricio Martín
Romero','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Carlos
Guzmán','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(10,'Joao
Rojas','MED',2,1,1,1,0,131,0,0,1,0);
INSERT INTO moreliaC2012 VALUES(21,'Jaime
Lozano','MED',2,1,1,1,0,123,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(8,'Jorge Kalú
Gastelum','MED',2,0,2,0,2,112,0,0,2,0);
INSERT INTO moreliaC2012 VALUES(28,'Aldo Leao
Ramírez','MED',1,1,1,0,0,90,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(26,'Christian
Valdez','MED',1,0,0,1,0,27,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(22,'Diego Andrei
Mejía','MED',1,0,0,1,0,7,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(15,'Felipe de Jesús
Ayala','MED',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Ismael
Pineda','MED',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(31,'Claudio Boy
Ramón','MED',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(23,'Edgar Gerardo
Lugo','DEL',2,2,2,0,0,180,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(7,'Rafael
Márquez','DEL',2,1,2,0,1,173,1,0,0,0);
INSERT INTO moreliaC2012 VALUES(11,'Luis Alonso
Sandoval','DEL',2,1,2,0,1,163,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(9,'Miguel
Sabah','DEL',2,1,2,0,1,160,0,1,0,0);
INSERT INTO moreliaC2012 VALUES(14,'Edison
Toloza','DEL',1,0,0,1,0,20,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(20,'Ángel Baltazar
Sepúlveda','DEL',1,0,0,1,0,17,0,0,0,0);

CREATE TABLE juegoLimpio (


nombre CHAR(45),
juega CHAR(15)
);

INSERT INTO juegoLimpio (nombre,juega)


SELECT nombreJugador,(TA+TR) FROM moreliaC2012;
UPDATE juegoLimpio SET juega = CASE
WHEN juega = '0' THEN 'Limpio' ELSE 'Sucio'
END;

SELECT * FROM juegoLimpio;

CREATE TABLE moreliaC2012(


numero INTEGER(3),
nombreJugador CHAR(40),
posicion CHAR(4),
jj INTEGER(2),
jc INTEGER(2),
jt INTEGER(2),
ec INTEGER(2),
sc INTEGER(2),
minutos INTEGER(6),
gol INTEGER(4),
ppg INTEGER(2),
tr INTEGER(2),
ta INTEGER(2)
);

INSERT INTO moreliaC2012 VALUES(3,'Federico


Vilar','POR',2,2,2,0,0,180,4,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Jesús
Urbina','POR',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Carlos Felipe
Rodríguez','POR',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(25,'Alonso
Arciga','POR',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(16,'Adrián
Aldrete','DEF',2,2,2,0,0,180,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(2,'Enrique
Pérez','DEF',2,2,2,0,0,180,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(24,'Marvin
Cabrera','DEF',2,1,2,0,1,147,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(33,'Joel
Huiqui','DEF',1,1,1,0,0,90,0,0,1,0);
INSERT INTO moreliaC2012 VALUES(0,'Diego
Jiménez','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Francisco Javier
Dorame','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Alberto
Lucio','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Marvin de la
Cruz','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(19,'Oscar Francisco
Razo','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Luis Fernando
Silva','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(5,'Mauricio Martín
Romero','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Carlos
Guzmán','DEF',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(10,'Joao
Rojas','MED',2,1,1,1,0,131,0,0,1,0);
INSERT INTO moreliaC2012 VALUES(21,'Jaime
Lozano','MED',2,1,1,1,0,123,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(8,'Jorge Kalú
Gastelum','MED',2,0,2,0,2,112,0,0,2,0);
INSERT INTO moreliaC2012 VALUES(28,'Aldo Leao
Ramírez','MED',1,1,1,0,0,90,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(26,'Christian
Valdez','MED',1,0,0,1,0,27,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(22,'Diego Andrei
Mejía','MED',1,0,0,1,0,7,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(15,'Felipe de Jesús
Ayala','MED',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(0,'Ismael
Pineda','MED',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(31,'Claudio Boy
Ramón','MED',0,0,0,0,0,0,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(23,'Edgar Gerardo
Lugo','DEL',2,2,2,0,0,180,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(7,'Rafael
Márquez','DEL',2,1,2,0,1,173,1,0,0,0);
INSERT INTO moreliaC2012 VALUES(11,'Luis Alonso
Sandoval','DEL',2,1,2,0,1,163,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(9,'Miguel
Sabah','DEL',2,1,2,0,1,160,0,1,0,0);
INSERT INTO moreliaC2012 VALUES(14,'Edison
Toloza','DEL',1,0,0,1,0,20,0,0,0,0);
INSERT INTO moreliaC2012 VALUES(20,'Ángel Baltazar
Sepúlveda','DEL',1,0,0,1,0,17,0,0,0,0);

CREATE TABLE juegoLimpio (


nombre CHAR(45),
juega CHAR(15)
);

INSERT INTO juegoLimpio (nombre,juega)


SELECT nombreJugador,(TA+TR) FROM moreliaC2012;

UPDATE juegoLimpio SET juega = CASE


WHEN juega = '0' THEN 'Limpio' ELSE 'Sucio'
END;

SELECT * FROM juegoLimpio;

2.3. DELETE (Oracle y MySQL)

Borrará todas las filas que cumplan la condición especificada en la cláusula WHERE. Si esta
cláusula se omite, se borrarán todas las filas de la tabla. DELETE borra todas las filas de una
tabla, pero no la definición de la tabla del diccionario. Esta es una diferencia con la sentencia
DROP TABLE, que elimina el contenido de la tabla y la definición de la misma.

La sintaxis es la que sigue:

DELETE FROM tabla [WHERE condición];

Obsérvese que cada comando DELETE sólo opera sobre una relación. Si se desea borrar
tuplas de varias relaciones es necesario utilizar una orden DELETE por cada relación.
La consulta

DELETE FROM empleados;


Borra todas las tuplas de la tabla empleados

La consulta

DELETE FROM empleados WHERE cargo = 'Chofer';

Borra los empleados con cargo de chofer

Cuando trabajemos con la sentencia DELETE debemos tener en cuenta las siguientes


consideraciones:

 Solo podemos borrar datos de una única tabla.


 Cuando borramos datos de una vista, los estamos borrando también de la tabla. Las vistas
son solo una forma de ver los datos, no una copia.
 Si intentamos borrar un registro de una tabla referenciada por una FOREING KEY como
tabla maestra, si la tabla dependiente tiene registros relacionados la
sentencia DELETE fallará a no ser que la tabla hija contenga la sentencia ON DELETE
CASCADE..

TRUNCATE

TRUNCATE es una mejor alternativa a DELETE cuando se desea borrar todo el contenido


de la tabla. La sintaxis es:

TRUNCATE TABLE nombre_tabla;

 Eliminar registros con la sentencia TRUNCATE es más rápido que con la sentencia DELETE,


especialmente cuando la tabla tiene numerosos disparadores, índices y otras dependencias
como por ejemplo integridad referencial.
 La sentencia TRUNCATE no es transaccional. No se puede deshacer ( ROLL BACK) y ocurre
un error en casos de bloqueo de tabla.
 la tabla puede recrearse como una vacía con TRUNCATE TABLE, incluso si los archivos de
datos o de índice se han corrompido
 En MySQL el manejador de tablas reinicia el valor AUTO_INCREMENT usado. Esto es
cierto incluso para MyISAM y InnoDB

2.4. SELECT

La recuperación de los datos en el lenguaje SQL se realiza mediante la sentencia SELECT,


seleccionar. Esta sentencia permite indicar al SGBD la información que se quiere recuperar.
Esta es la sentencia SQL, más habitual. La sentencia SELECT consta de cuatro partes
básicas:

 La cláusula SELECT seguida de la descripción de lo que se desea ver, los nombres de las
columnas a seleccionar. Esta parte es obligatoria.
 La cláusula FROM seguida de la especificación de las tablas de las que se han de obtener los
datos. Esta parte es obligatoria.
 La cláusula WHERE seguida por un criterio de selección, una condición. Esta parte es
opcional.
 La cláusula ORDER BY seguida por el criterio de ordenación. Esta parte es opcional.
Una primera aproximación a la sintaxis de la sentencia SELECT puede mostrarnos la
siguiente expresión:

SELECT {* | {columna,}+} FROM {tabla,}+ [WHERE condición] [ORDER BY


{expresiónColumna [ASC | DESC],}+];

Selección de columnas

Las columnas a seleccionar se enumeran sin más en la cláusula SELECT. Para seleccionar
todas las columnas use el carácter asterisco ' *'.

Cuando se consulta una base de datos, los nombres de las columnas se usan como
cabeceras de presentación. Si éste resulta demasiado largo, corto o críptico, puede
cambiarse con la misma sentencia SQL de consulta, creando un alias de columna
Cláusula FROM

La cláusula FROM define las tablas de las que se van a seleccionar las columnas.

Se puede añadir al nombre de las tablas el usuario propietario de las mismas de la forma
usuario.tabla. De esta manera podemos distinguir entre las tablas de un usuario y
otro.

Oracle siempre considera como prefijo el nombre del propietario de las tablas, aunque no se
lo indiquemos. De esta forma dos o más usuarios pueden tener tablas que se llamen igual sin
que surjan conflictos. Si quisiéramos acceder a las filas de la tabla departamento del usuario
epacheco, (además de tener privilegios de lectura sobre esa tabla) deberíamos escribir la
siguiente sentencia SQL:

También se puede asociar un alias a las tablas para abreviar los nombres de las tablas. Un
ejemplo se puede ver en la sentencia SQL siguiente:

SELECT d.nombre "Nombre Departamento", d.ciudad "Ubicado en"


FROM departamento d
Un campo calculado o campo derivado es una expresión numérica y que deberá ser
referenciada mediante un alias mediante el uso de la cláusula AS, en Oracle y MySQL está
sentencia es opcional. Por ejemplo calcular el sueldo diario de un empleado.

SELECT nombreEmpleado "Nombre Empleado",


TO_CHAR(salario/30,'999,999.99') "Salario Diario"
FROM empleado

SELECT nombreEmpleado "Nombre Empleado",


FORMAT(salario/30,2) "Salario Diario"
FROM empleado;

Ejemplo: Valores distintos y limitados

SELECT DISTINCT nombreJugador


FROM femexfut LIMIT 20;

2.5.Restricción y ordenación de datos

La sentencia SELECT recupera todas las columnas o un subconjunto de ellas de una tabla.
Esto afecta a todas las filas de la tabla, a menos que especifiquemos una condición en la
cláusula WHERE.

Esta condición regresa todas las filas que cumplen dicha condicional. La complejidad del
criterio de búsqueda es prácticamente ilimitada, y en él se pueden combinar operadores de
diversos tipos con funciones de columnas, componiendo expresiones más o menos
complejas.

Condición de búsqueda basada en una comparación compuesta

En este ejemplo, se utiliza el operador lógico OR en la cláusula WHERE para localizar los
empleados que son chofer o secretaria. La consulta y la tabla resultados se muestra a
continuación.

SELECT nombreEmpleado "Nombre Empleado", oficio


FROM empleado
WHERE (oficio = 'Chofer') OR (oficio = 'Secretaria')
Condición de búsqueda basada en rango

La condición BETWEEN indica los puntos extremos del rango, por lo cual el resultado incluirá
también a todos los empleados cuyo salario esté entre 2,500 y 5,000 pesos.

SELECT nombreEmpleado "Nombre Empleado",


oficio, TO_CHAR(salario,'999,999') Salario
FROM empleado WHERE salario BETWEEN 2500 AND 5000;

SELECT nombreEmpleado "Nombre Empleado",


oficio, FORMAT(salario,0) as Salario
FROM empleado WHERE salario BETWEEN 2500 AND 5000;

La condición de pertenencia de un conjunto (IN) comprueba si un valor de los datos se


corresponde con uno de los valores especificados en una determinada lista, que en este
caso está compuesta por sólo dos opciones 'Chofer' y 'Secretaria'. La consulta se muestra a
continuación.

SELECT nombreEmpleado "Nombre Empleado",


oficio, TO_CHAR(salario,'999,999') Salario
FROM Empleado
WHERE oficio IN ('Chofer', 'Secretaria');

SELECT nombreEmpleado "Nombre Empleado",


oficio, FORMAT(salario, 0) Salario
FROM Empleado
WHERE oficio IN ('Chofer', 'Secretaria');

La operación más utilizada sobre las cadenas de caracteres es la comparación de patrones,


para la que se usa el operador LIKE. Para la descripción de los patrones se utilizan dos
caracteres especiales:

% El carácter % coincide con cualquier subcadena de caracteres

_ El carácter _ coincide con cualquier carácter

Considere la consulta: Determinar que empleados se apellidan o se llaman 'OLIVEROS'

SELECT nombreEmpleado "Nombre Empleado", oficio,


TO_CHAR(salario,'999,999') Salario
FROM Empleado
WHERE nombreEmpleado LIKE '%OLIVEROS%';

SELECT nombreEmpleado "Nombre Empleado", oficio,


FORMAT(salario,2) Salario
FROM Empleado
WHERE nombreEmpleado LIKE '%OLIVEROS%';

Cláusula ORDER BY

En general, las filas de la tabla resultados de una consulta SQL, no están ordenadas por
ningún criterio particular. Sin embargo podemos garantizar que los resultados de la consulta
queden ordenados utilizando la cláusula ORDER BY en la instrucción SELECT. La cláusula
ORDER BY está compuesta por una lista de identificadores de columna según los cuales hay
que ordenar los resultados, separados por comas.

ORDER BY se usa para especificar el criterio de ordenación de la respuesta a la consulta.


Por defecto la ordenación es ascendente, aunque se puede especificar un orden
descendente (DESC). La ordenación se puede establecer sobre el contenido de columnas o
sobre expresiones con columnas.

Ejemplo: Consulta de los empleados ordenado de manera descendente por su salario y en


caso de igualdad de salario, ordenado ascendentemente por su nombre.

SELECT nombreEmpleado "Nombre Empleado", oficio,


TO_CHAR(salario,'999,999') Salario
FROM empleado
ORDER BY Salario DESC, nombreEmpleado;

SELECT nombreEmpleado "Nombre Empleado", oficio,


FORMAT(salario,0) Salario
FROM empleado
ORDER BY Salario DESC, nombreEmpleado;

Ejemplo MySQL: Se presentan los campeones NBA ordenados por temporada.

SELECT temporada,
campeon,
ganador,
perdedor,
subcampeon
FROM campeonesNBA
ORDER BY temporada DESC
CREATE TABLE IF NOT EXISTS campeonesNBA (
temporada char(10) NOT NULL,
campeon char(30) NOT NULL,
subcampeon char(30) NOT NULL,
ganador int(11) NOT NULL,
perdedor int(11) NOT NULL,
mvp char(40) default NULL,
entrenador char(30) default NULL,
equipo char(30) default NULL,
PRIMARY KEY (temporada)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Volcar la base de datos para la tabla campeonesNBA
--

INSERT INTO campeonesNBA (temporada, campeon, subcampeon, ganador, perdedor, mvp,


entrenador, equipo) VALUES
('1946-1947', 'Philadelphia Warriors', 'Chicago Stags', 4, 1, '', '', ''),
('1947-1948', 'Baltimore Bullets', 'Philadelphia Warriors', 4, 2, '', '', ''),
('1948-1949', 'Minneapolis Lakers', 'Washington Capitols', 4, 2, '', '', ''),
('1949-1950', 'Minneapolis Lakers *', 'Syracuse Nationals *', 4, 2, '', '', ''),
('1950-1951', 'Rochester Royals', 'New York Knicks', 4, 3, '', '', ''),
('1951-1952', 'Minneapolis Lakers', 'New York Knicks', 4, 3, '', '', ''),
('1952-1953', 'Minneapolis Lakers', 'New York Knicks', 4, 1, '', '', ''),
('1953-1954', 'Minneapolis Lakers', 'Syracuse Nationals', 4, 3, '', '', ''),
('1954-1955', 'Syracuse Nationals', 'Fort Wayne Pistons', 4, 3, '', '', ''),
('1955-1956', 'Philadelphia Warriors', 'Fort Wayne Pistons', 4, 1, 'Bob Pettit, St. Louis', '', ''),
('1956-1957', 'Boston Celtics', 'Saint Louis Hawks', 4, 3, 'Bob Cousy, Boston', '', ''),
('1957-1958', 'Saint Louis Hawks', 'Boston Celtics', 4, 2, 'Bill Russell, Boston', '', ''),
('1958-1959', 'Boston Celtics', 'Minneapolis Lakers', 4, 0, 'Bob Pettit, St. Louis', '', ''),
('1959-1960', 'Boston Celtics', 'Saint Louis Hawks', 4, 3, 'Wilt Chamberlain, Philadelphia', '', ''),
('1960-1961', 'Boston Celtics', 'Saint Louis Hawks', 4, 1, 'Bill Russell, Boston', '', ''),
('1961-1962', 'Boston Celtics', 'Los Angeles Lakers', 4, 3, 'Bill Russell, Boston', '', ''),
('1962-1963', 'Boston Celtics', 'Los Angeles Lakers', 4, 2, 'Bill Russell, Boston', 'Harry Gallatin',
'St. Louis'),
('1963-1964', 'Boston Celtics', 'San Francisco Warriors', 4, 1, 'Oscar Robertson, Cincinnati',
'Alex Hannum', 'San Francisco'),
('1964-1965', 'Boston Celtics', 'Los Angeles Lakers', 4, 1, 'Bill Russell, Boston', 'Red
Auerbach', 'Boston'),
('1965-1966', 'Boston Celtics', 'Los Angeles Lakers', 4, 3, 'Wilt Chamberlain, Philadelphia',
'Dolph Schayes', 'Philadelphia'),
('1966-1967', 'Philadelphia 76ers', 'San Francisco Warriors', 4, 2, 'Wilt Chamberlain,
Philadelphia', 'Johnny Kerr', 'Chicago'),
('1967-1968', 'Boston Celtics', 'Los Angeles Lakers', 4, 2, 'Wilt Chamberlain, Philadelphia',
'Richie Guerin', 'St. Louis'),
('1968-1969', 'Boston Celtics', 'Los Angeles Lakers', 4, 3, 'Wes Unseld, Baltimore', 'Gene
Shue', 'Baltimore'),
('1969-1970', 'New York Knicks', 'Los Angeles Lakers', 4, 3, 'Willis Reed, New York', 'Red
Holzman', 'New York'),
('1970-1971', 'Milwaukee Bucks', 'Baltimore Bullets', 4, 0, 'Kareem Abdul-Jabbar, Milwaukee',
'Dick Motta', 'Chicago'),
('1971-1972', 'Los Angeles Lakers', 'New York Knicks', 4, 1, 'Kareem Abdul-Jabbar,
Milwaukee', 'Bill Sharman', 'LA Lakers'),
('1972-1973', 'New York Knicks', 'Los Angeles Lakers', 4, 1, 'Dave Cowens, Boston', 'Tom
Heinsohn', 'Boston'),
('1973-1974', 'Boston Celtics', 'Milwaukee Bucks', 4, 3, 'Kareem Abdul-Jabbar, Milwaukee',
'Ray Scott', 'Detroit'),
('1974-1975', 'Golden State Warriors', 'Washington Bullets', 4, 0, 'Bob McAdoo, Buffalo', 'Phil
Johnson', 'Kansas City-Omaha'),
('1975-1976', 'Boston Celtics', 'Phoenix Suns', 4, 2, 'Kareem Abdul-Jabbar, LA Lakers', 'Bill
Fitch', 'Cleveland'),
('1976-1977', 'Portland Trail Blazers', 'Philadelphia 76ers', 4, 2, 'Kareem Abdul-Jabbar, LA
Lakers', 'Tom Nissalke', 'Houston'),
('1977-1978', 'Washington Bullets', 'Seattle SuperSonics', 4, 3, 'Bill Walton, Portland', 'Hubie
Brown', 'Atlanta'),
('1978-1979', 'Seattle SuperSonics', 'Washington Bullets', 4, 1, 'Moses Malone, Houston',
'Cotton Fitzsimmons', 'Kansas City'),
('1979-1980', 'Los Angeles Lakers', 'Philadelphia 76ers', 4, 2, 'Kareem Abdul-Jabbar, LA
Lakers', 'Bill Fitch', 'Boston'),
('1980-1981', 'Boston Celtics', 'Houston Rockets', 4, 2, 'Julius Erving, Philadelphia', 'Jack
McKinney', 'Indiana'),
('1981-1982', 'Los Angeles Lakers', 'Philadelphia 76ers', 4, 2, 'Moses Malone, Houston', 'Gene
Shue', 'Washington'),
('1982-1983', 'Philadelphia 76ers', 'Los Angeles Lakers', 4, 0, 'Moses Malone, Philadelphia',
'Don Nelson', 'Milwaukee'),
('1983-1984', 'Boston Celtics', 'Los Angeles Lakers', 4, 3, 'Larry Bird, Boston', 'Frank Layden',
'Utah'),
('1984-1985', 'Los Angeles Lakers', 'Boston Celtics', 4, 2, 'Larry Bird, Boston', 'Don Nelson',
'Milwaukee'),
('1985-1986', 'Boston Celtics', 'Houston Rockets', 4, 2, 'Larry Bird, Boston', 'Mike Fratello',
'Atlanta'),
('1986-1987', 'Los Angeles Lakers', 'Boston Celtics', 4, 2, 'Magic Johnson, LA Lakers', 'Mike
Schuler', 'Portland'),
('1987-1988', 'Los Angeles Lakers', 'Detroit Pistons', 4, 3, 'Michael Jordan, Chicago', 'Doug
Moe', 'Denver'),
('1988-1989', 'Detroit Pistons', 'Los Angeles Lakers', 4, 0, 'Magic Johnson, LA Lakers', 'Cotton
Fitzsimmons', 'Phoenix'),
('1989-1990', 'Detroit Pistons', 'Portland Trail Blazers', 4, 1, 'Magic Johnson, LA Lakers', 'Pat
Riley', 'LA Lakers'),
('1990-1991', 'Chicago Bulls', 'Los Angeles Lakers', 4, 1, 'Michael Jordan, Chicago', 'Don
Chaney', 'Houston'),
('1991-1992', 'Chicago Bulls', 'Portland Trail Blazers', 4, 2, 'Michael Jordan, Chicago', 'Don
Nelson', 'Golden State'),
('1992-1993', 'Chicago Bulls', 'Phoenix Suns', 4, 2, 'Charles Barkley, Phoenix', 'Pat Riley',
'New York'),
('1993-1994', 'Houston Rockets', 'New York Knicks', 4, 3, 'Hakeem Olajuwon, Houston', 'Lenny
Wilkens', 'Atlanta'),
('1994-1995', 'Houston Rockets', 'Orlando Magic', 4, 0, 'David Robinson, San Antonio', 'Del
Harris', 'LA Lakers'),
('1995-1996', 'Chicago Bulls', 'Seattle SuperSonics', 4, 2, 'Michael Jordan, Chicago', 'Phil
Jackson', 'Chicago'),
('1996-1997', 'Chicago Bulls', 'Utah Jazz', 4, 2, 'Karl Malone, Utah', 'Pat Riley', 'Miami'),
('1997-1998', 'Chicago Bulls', 'Utah Jazz', 4, 2, 'Michael Jordan, Chicago', 'Larry Bird',
'Indiana'),
('1998-1999', 'San Antonio Spurs', 'New York Knicks', 4, 1, 'Karl Malone, Utah', 'Mike
Dunleavy', 'Portland'),
('1999-2000', 'Los Angeles Lakers', 'Indiana Pacers', 4, 2, 'Shaquille O''Neal, LA Lakers', 'Doc
Rivers', 'Orlando'),
('2000-2001', 'Los Angeles Lakers', 'Philadelphia 76ers', 4, 1, 'Allen Iverson, Philadelphia',
'Larry Brown', 'Philadelphia'),
('2001-2002', 'Los Angeles Lakers', 'New Jersey Nets', 4, 0, 'Tim Duncan, San Antonio', 'Rick
Carlisle', 'Detroit'),
('2002-2003', 'San Antonio Spurs', 'New Jersey Nets', 4, 2, 'Tim Duncan, San Antonio', 'Gregg
Popovich', 'San Antonio'),
('2003-2004', 'Detroit Pistons', 'Los Angeles Lakers', 4, 1, 'Kevin Garnett, Minnesota', 'Hubie
Brown', 'Memphis'),
('2004-2005', 'San Antonio Spurs', 'Detroit Pistons', 4, 3, 'Steve Nash, Phoenix', 'Mike
D''Antoni', 'Phoenix'),
('2005-2006', 'Miami Heat', 'Dallas Mavericks', 4, 2, 'Steve Nash, Phoenix', 'Avery Johnson',
'Dallas'),
('2006-2007', 'San Antonio Spurs', 'Cleveland Cavaliers', 4, 0, 'Dirk Nowitzki, Dallas', 'Sam
Mitchell', 'Toronto'),
('2007-2008', 'Boston Celtics', 'Los Angeles Lakers', 4, 2, 'Kobe Bryant, LA Lakers', 'Byron
Scott', 'New Orleans'),
('2008-2009', 'Los Angeles Lakers', 'Orlando Magic', 4, 1, 'LeBron James, Cleveland', 'Mike
Brown', 'Cleveland'),
('2009-2010', 'Los Angeles Lakers', 'Boston Celtis', 4, 3, 'Kobe Bryant, LA Lakers', 'Scott
Brooks', 'Thunder de Oklahoma City'),
('2010-2011', 'Dallas Mavericks' ,'Miami Heat' , 4, 2, 'Derrick Rose, Chicago' , 'Tom
Thibodeau','Chicago');

SELECT temporada, campeon, ganador, perdedor, subcampeon


FROM campeonesNBA
ORDER BY temporada DESC

Cláusula DISTINCT
Cuando se realiza una consulta sobre una tabla en la que se extrae información de varias
columnas, puede ocurrir que, si no incluimos la/s columna/s que forman la clave principal,
obtengamos filas repetidas en la respuesta.

Si este comportamiento es no satisfactorio podemos utilizar la cláusula DISTINCT para


eliminar las filas duplicadas obtenidas como respuesta a una consulta.

Ejemplo: Obtener los campeones NBA

SELECT DISTINCT campeon


FROM campeonesNBA
ORDER BY campeon

Ejemplo: Antiguedad de los empleados en la empresa

SELECT nombreEmpleado,
TRUNC(MONTHS_BETWEEN(SYSDATE, ingreso)/12) AS antiguedad
FROM empleado
ORDER BY antiguedad DESC, nombreEmpleado;

SELECT nombreEmpleado,
(YEAR(CURDATE()) - YEAR(ingreso))
- (RIGHT(CURDATE(), 5) < RIGHT(ingreso,5)) AS antiguedad
FROM empleado
ORDER BY antiguedad DESC, nombreEmpleado;

Expresión CASE

La expresión CASE permite utilizar la lógica IF-THEN-ELSE en sentencias SQL sin tener que
invocar procedimientos. Esta expresión se incluye a partir de la versión Oracle9i Server y
MySQL 5.

La siguiente es la sintaxis que presenta la expresión CASE:

SELECT campos,
CASE expresión WHEN Comparación_1 THEN return_expresión_1
[ WHEN Comparación_2 THEN return_expresión_2
WHEN Comparación_n THEN return_expresión_n
ELSE else_expresión]
END
FROM tabla
Expresión es opcional. (ie: Comparación_1, Comparación_2, ... Comparación_n) deben ser
del mismo tipo y son evaluadas en el orden que se listan y regresara return_expresión de la
primera Comparación que regresa TRUE, si ninguna expresión es evaluada como TRUE se
regresa el valor declarado en el ELSE.

Si la clausula ELSE es omitida y ninguna condición es evaluda TRUE. La sentencia CASE


regresa NULL.

Es posible declarar un máximo de 255 comparaciones en la sentencia CASE. Cada clausula


WHEN ... THEN es considerada como 2 comparaciones.

Ejemplo: Se requiere saber si un empleado tiene derecho al estimulo por antiguedad de 10


o 6 años

SELECT nombreEmpleado,
CASE
WHEN TRUNC(MONTHS_BETWEEN(SYSDATE, ingreso)/12) = 10 THEN
'Estimulo 10 años'
WHEN TRUNC(MONTHS_BETWEEN(SYSDATE, ingreso)/12) = 6 THEN 'Estimulo 6
años'
ELSE ''
END AS Estimulo
FROM empleado
ORDER BY nombreEmpleado

SELECT nombreEmpleado,
CASE
WHEN (YEAR(CURDATE()) - YEAR(ingreso))
- (RIGHT(CURDATE(), 5) < RIGHT(ingreso,5)) = 10 THEN 'Estimulo 10 años'
WHEN (YEAR(CURDATE()) - YEAR(ingreso))
- (RIGHT(CURDATE(), 5) < RIGHT(ingreso,5)) = 6 THEN 'Estimulo 6 años'
ELSE ''
END AS Estimulo
FROM empleado
ORDER BY nombreEmpleado

2.6. GROUP BY

La cláusula GROUP BY combina los registros con valores idénticos en la lista de campos
especificada en un único registro. Para cada registro se puede crear un valor agregado si se
incluye una función SQL agregada como por ejemplo SUM o COUNT, en la instrucción
SELECT. Su sintaxis es:

SELECT [ALL | DISTINCT ]


<nombre_campo> [{,<nombre_campo>}] [{,<funcion_agregación>}]
FROM <nombre_tabla>|<nombre_vista>
[{,<nombre_tabla>|<nombre_vista>}]
[WHERE <condición> [{ AND|OR <condición>}]]
[GROUP BY <nombre_campo> [{,<nombre_campo >}]]
[HAVING <condición>[{ AND|OR <condición>}]]
[ORDER BY <nombre_campo>|<campo_índice> [ASC | DESC]
[{,<nombre_campo>|<campo_índice> [ASC | DESC ]}]]

En la cláusula GROUP BY se colocan las columnas por las que vamos a agrupar. Y en la
cláusula HAVING filtra los registros una vez agrupados.

La evaluación de las diferentes cláusulas en tiempo de ejecución, se efectúa en el siguiente


orden:

Cláusula Descripción
WHERE Filtra las filas

GROUP BY Crea una tabla de grupo nueva

HAVING Filtra los grupos

ORDER BY Clasifica la salida

Los valores NULL en los campos de GROUP BY se agrupan y no se omiten. Sin embargo,
los valores NULL no se calculan en ninguna función de agregado SQL.

Un ejemplo de SELECT de grupos es consultar los empleados agrupados por su oficio. Un


primer intento de consulta es el siguiente:

SELECT oficio, nombreEmpleado


FROM empleado
GROUP BY oficio

Se presenta un error debido a que cuando se utiliza GROUP BY, las columnas implicadas en
el SELECT y que no aparezcan en la cláusula GROUP BY deben tener una función de
agrupamiento. En otras palabras, la columna nombreEmpleado debe tener una
función de agrupamiento que actúe sobre ella ( MAX, MIN, SUM, COUNT, AVG). De no
ser posible, deberá aparecer dicha columna a la cláusula GROUP BY.

La consulta correcta quedaría así;

SELECT oficio, COUNT(nombreEmpleado) Elementos


FROM empleado
GROUP BY oficio
ORDER BY oficio

Ejemplo: Considere los alumnos inscritos en las materias que imparto durante Enero Junio
2011 en el ITSX La siguiente consulta obtiene el número de alumnos por género y materia.

SELECT Genero, COUNT(*) Alumnos


FROM alumnosITSX
GROUP BY Genero

DROP DATABASE IF EXISTS alumnosITSX;

CREATE DATABASE alumnosITSX;

USE alumnosITSX;

CREATE TABLE IF NOT EXISTS alumnosITSX (


idAlumno int(11) NOT NULL auto_increment,
NControl char(9) NOT NULL,
Materia char(15) NOT NULL,
Genero char(1) NOT NULL,
Nombre char(45) NOT NULL,
PRIMARY KEY (idAlumno)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Volcar la base de datos para la tabla 'alumnosITSX'
--

INSERT INTO alumnosITSX (idAlumno, NControl, Materia, Genero, Nombre) VALUES


(1, 'E07021011', 'Pweb', 'M', 'ALVARADO SALVADOR MANUEL ALEJANDRO'),
(2, 'E09020006', 'Pweb', 'M', 'BUCKIEWICZ CORY JOSEPH'),
(3, 'E06020041', 'Pweb', 'M', 'CHAVEZ HERNANDEZ HAYME A.'),
(4, 'E09020015', 'Pweb', 'M', 'COSTE?O CASAS ALBERTO CARITINO'),
(5, 'E07020112', 'Pweb', 'F', 'D?AZ HERN?NDEZ FAVIOLA ANTONIA'),
(6, 'E09020026', 'Pweb', 'M', 'FIGUEROA GARCIA EDGAR MANUEL'),
(7, 'E08020445', 'Pweb', 'M', 'GARCIA ALMANZA IRVING RAFAEL'),
(8, 'E09020035', 'Pweb', 'M', 'GONZALEZ FLORES JOSE ARTURO'),
(9, 'E07020895', 'Pweb', 'M', 'GUENDULAY LAGUNES FERNANDO ANTONIO'),
(10, 'E08020454', 'Pweb', 'F', 'GUTIERREZ MOLINA HORTENSIA'),
(11, 'E07021007', 'Pweb', 'F', 'MADRID BETANCOURT ILIANA'),
(12, 'E08020126', 'Pweb', 'M', 'MARTINEZ ARELLANO MARIO'),
(13, 'E07020876', 'Pweb', 'M', 'MART?NEZ CORT?S ALFONSO JES?S'),
(14, 'E07020909', 'Pweb', 'M', 'MENDO ESCOBEDO HUGO ENRIQUE'),
(15, 'E08020476', 'Pweb', 'M', 'MORALES ANZURES CARLOS ALFREDO'),
(16, 'E08020479', 'Pweb', 'F', 'MORALES PAVON JUANA'),
(17, 'E07021234', 'Pweb', 'M', 'MORFINEZ MOJICA JORGE'),
(18, 'E07020896', 'Pweb', 'M', 'MURILLO GUTIERREZ FRANCISCO'),
(19, 'E08020487', 'Pweb', 'M', 'OLIVARES ROSAS VICTOR EMMANUEL'),
(20, 'E09020661', 'Pweb', 'M', 'ORTEGA LANDA JOSE EDUARDO'),
(21, 'E08020133', 'Pweb', 'F', 'ORTIZ AG?ERO ADELA'),
(22, 'E07021273', 'Pweb', 'M', 'REYES PIMENTEL ABEL'),
(23, 'E07020115', 'Pweb', 'F', 'REYES REBOLLEDO ROSA BEATR?Z'),
(24, 'E08020150', 'Pweb', 'M', 'SANTACRUZ MARTINEZ JOSE MARTIN'),
(25, 'E07020158', 'Pweb', 'M', 'SOLANO P?REZ HERIBERTO'),
(26, 'E08020155', 'Pweb', 'M', 'VERDEJO BUENO CARLOS ADIEL'),
(27, 'E06020025', 'Seguridad', 'F', 'ALEMAN HERNANDEZ MARIA ELENA'),
(28, 'E06021435', 'Seguridad', 'M', 'BALTAZAR GOMEZ ABRAHAM'),
(29, 'E06021505', 'Seguridad', 'F', 'CASAS HERNANDEZ MARICRUZ'),
(30, 'E07020146', 'Seguridad', 'F', 'CRUZ DELF?N MAR?A SELENE'),
(31, 'E05600195', 'Seguridad', 'M', 'CRUZ RAMIREZ ANTONIO'),
(32, 'E07020829', 'Seguridad', 'M', 'DOMINGUEZ ARIES WILLIAMS FELICIANO'),
(33, 'E06021475', 'Seguridad', 'M', 'GONZALEZ RAMIREZ FERNANDO'),
(34, 'E07020405', 'Seguridad', 'M', 'LE?N NAVA ANTONIO'),
(35, 'E06020205', 'Seguridad', 'M', 'LOPEZ MIGUEL VALERIO'),
(36, 'E06022114', 'Seguridad', 'M', 'LUNA BENDIMEZ EDGAR'),
(37, 'E07021007', 'Seguridad', 'F', 'MADRID BETANCOURT ILIANA'),
(38, 'E05020347', 'Seguridad', 'M', 'ESTEVEZ FERNANDEZ MANUEL ALEJANDRO'),
(39, 'E07020402', 'Seguridad', 'F', 'M?NDEZ AHUJA CRISTHELL MONTSERRAT'),
(40, 'E07020889', 'Seguridad', 'M', 'MILAGRO TRUJILLO ANDRES ALBERTO'),
(41, 'E07020348', 'Seguridad', 'M', 'NEIRA HERNANDEZ JULIO C?SAR'),
(42, 'E08020134', 'Seguridad', 'M', 'PE?A MORENO ELEAZAR'),
(43, 'E07020902', 'Seguridad', 'M', 'PERALTA SANCHEZ EDUARDO MANUEL'),
(44, 'E08020500', 'Seguridad', 'M', 'RAMIREZ DURAN CRISTHIAN RENE'),
(45, 'E08020141', 'Seguridad', 'M', 'RIVERA HERNANDEZ FELIX OCTAVIO'),
(46, 'E07020613', 'Seguridad', 'M', 'USCANGA COLMENERO RAFAEL'),
(47, 'E06021430', 'Seguridad', 'M', 'VALDES CASTRO MANFREDO'),
(48, 'E06022202', 'Seguridad', 'F', 'VALENCIA GONZ?LEZ CAROLINA'),
(49, 'E07020864', 'Seguridad', 'M', 'VAZQUEZ GALICIA JESUS'),
(50, 'E07020161', 'Seguridad', 'M', 'V?ZQUEZ GONZ?LEZ REN'),
(51, 'E07021003', 'Seguridad', 'M', 'VIVAR L?PEZ EDUARDO'),
(52, 'E07021272', 'TallerBD', 'F', 'ALVARADO ESCAS?N ROSA LUZ'),
(53, 'E06021505', 'TallerBD', 'F', 'CASAS HERNANDEZ MARICRUZ'),
(54, 'E08020440', 'TallerBD', 'F', 'ENRIQUEZ PITA ALHELI'),
(55, 'E09020023', 'TallerBD', 'M', 'ESPONDA CORTES MARIO'),
(56, 'E09020024', 'TallerBD', 'M', 'ESQUIVEL MOTA ALBERTO ADRIAN'),
(57, 'E09020028', 'TallerBD', 'F', 'FUSTER ROJAS VANIA BEATRIZ'),
(58, 'E07021270', 'TallerBD', 'M', 'HERNANDEZ CINTA OSCAR'),
(59, 'E07020865', 'TallerBD', 'M', 'HERNANDEZ HERRERA RICARDO JOSE'),
(60, 'E07021363', 'TallerBD', 'M', 'HERRERA CID LUIS ANGEL'),
(61, 'E09020042', 'TallerBD', 'M', 'INCLAN LAGUNA JAZIEL'),
(62, 'E08020468', 'TallerBD', 'M', 'MARCOS RAMIREZ JOVANY'),
(63, 'E09020053', 'TallerBD', 'M', 'MARTINEZ MALDONADO CARLOS'),
(64, 'E08020472', 'TallerBD', 'M', 'MEDINA PALACIOS GUILLERMO SEBASTIAN'),
(65, 'E08020473', 'TallerBD', 'F', 'MENDOZA BARRALES EDNA ELIDETH'),
(66, 'E07020862', 'TallerBD', 'M', 'MORALES COLINA JOS? FERNANDO'),
(67, 'E07021234', 'TallerBD', 'M', 'MORFINEZ MOJICA JORGE'),
(68, 'E08020489', 'TallerBD', 'M', 'ORTIZ ESQUIVEL ARIEL ESAU'),
(69, 'E08020497', 'TallerBD', 'M', 'PRIETO POLITO JULIO CESAR'),
(70, 'E07020759', 'TallerBD', 'M', 'ROMERO SILVA CHRISTIAN'),
(71, 'E07021127', 'TallerBD', 'F', 'SIMON GARCIA RUBI'),
(72, 'E07021257', 'TallerBD', 'M', 'TEXON CORTES DANIEL'),
(73, 'E08020521', 'TallerBD', 'F', 'TRONCO CARO NURIA VICTORIA'),
(74, 'E08020153', 'TallerBD', 'M', 'USCANGA DOMINGUEZ OSCAR LUIS'),
(75, 'E08020524', 'TallerBD', 'F', 'VEGA BRAVO ANA CAROLINA'),
(76, 'E07020132', 'TallerBD', 'M', 'VERA CID SERGIO');

-- Consulta

SELECT Genero, COUNT(*) Alumnos


FROM alumnosITSX
GROUP BY Genero

Ejemplo: Para ser campeón de la NBA hay que ganar cuatro partidos de siete. El
ejemplo muestra el número de juegos necesarios para ser campeón de 1946 a 2011.

SELECT ganador, perdedor, COUNT(*) ocurrencias


FROM campeonesNBA
GROUP BY ganador, perdedor
ORDER BY ganador, perdedor
CREATE DATABASE NBA;
USE NBA;

CREATE TABLE IF NOT EXISTS campeonesNBA (


temporada char(10) NOT NULL,
campeon char(30) NOT NULL,
subcampeon char(30) NOT NULL,
ganador int(11) NOT NULL,
perdedor int(11) NOT NULL,
mvp char(40) default NULL,
entrenador char(30) default NULL,
equipo char(30) default NULL,
PRIMARY KEY (temporada)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Volcar la base de datos para la tabla campeonesNBA
--

INSERT INTO campeonesNBA (temporada, campeon, subcampeon, ganador,


perdedor, mvp, entrenador, equipo) VALUES
('1946-1947', 'Philadelphia Warriors', 'Chicago Stags', 4, 1, '', '', ''),
('1947-1948', 'Baltimore Bullets', 'Philadelphia Warriors', 4, 2, '', '', ''),
('1948-1949', 'Minneapolis Lakers', 'Washington Capitols', 4, 2, '', '', ''),
('1949-1950', 'Minneapolis Lakers *', 'Syracuse Nationals *', 4, 2, '', '', ''),
('1950-1951', 'Rochester Royals', 'New York Knicks', 4, 3, '', '', ''),
('1951-1952', 'Minneapolis Lakers', 'New York Knicks', 4, 3, '', '', ''),
('1952-1953', 'Minneapolis Lakers', 'New York Knicks', 4, 1, '', '', ''),
('1953-1954', 'Minneapolis Lakers', 'Syracuse Nationals', 4, 3, '', '', ''),
('1954-1955', 'Syracuse Nationals', 'Fort Wayne Pistons', 4, 3, '', '', ''),
('1955-1956', 'Philadelphia Warriors', 'Fort Wayne Pistons', 4, 1, 'Bob Pettit, St.
Louis', '', ''),
('1956-1957', 'Boston Celtics', 'Saint Louis Hawks', 4, 3, 'Bob Cousy, Boston', '', ''),
('1957-1958', 'Saint Louis Hawks', 'Boston Celtics', 4, 2, 'Bill Russell, Boston', '', ''),
('1958-1959', 'Boston Celtics', 'Minneapolis Lakers', 4, 0, 'Bob Pettit, St. Louis', '',
''),
('1959-1960', 'Boston Celtics', 'Saint Louis Hawks', 4, 3, 'Wilt Chamberlain,
Philadelphia', '', ''),
('1960-1961', 'Boston Celtics', 'Saint Louis Hawks', 4, 1, 'Bill Russell, Boston', '', ''),
('1961-1962', 'Boston Celtics', 'Los Angeles Lakers', 4, 3, 'Bill Russell, Boston', '',
''),
('1962-1963', 'Boston Celtics', 'Los Angeles Lakers', 4, 2, 'Bill Russell, Boston',
'Harry Gallatin', 'St. Louis'),
('1963-1964', 'Boston Celtics', 'San Francisco Warriors', 4, 1, 'Oscar Robertson,
Cincinnati', 'Alex Hannum', 'San Francisco'),
('1964-1965', 'Boston Celtics', 'Los Angeles Lakers', 4, 1, 'Bill Russell, Boston', 'Red
Auerbach', 'Boston'),
('1965-1966', 'Boston Celtics', 'Los Angeles Lakers', 4, 3, 'Wilt Chamberlain,
Philadelphia', 'Dolph Schayes', 'Philadelphia'),
('1966-1967', 'Philadelphia 76ers', 'San Francisco Warriors', 4, 2, 'Wilt
Chamberlain, Philadelphia', 'Johnny Kerr', 'Chicago'),
('1967-1968', 'Boston Celtics', 'Los Angeles Lakers', 4, 2, 'Wilt Chamberlain,
Philadelphia', 'Richie Guerin', 'St. Louis'),
('1968-1969', 'Boston Celtics', 'Los Angeles Lakers', 4, 3, 'Wes Unseld, Baltimore',
'Gene Shue', 'Baltimore'),
('1969-1970', 'New York Knicks', 'Los Angeles Lakers', 4, 3, 'Willis Reed, New York',
'Red Holzman', 'New York'),
('1970-1971', 'Milwaukee Bucks', 'Baltimore Bullets', 4, 0, 'Kareem Abdul-Jabbar,
Milwaukee', 'Dick Motta', 'Chicago'),
('1971-1972', 'Los Angeles Lakers', 'New York Knicks', 4, 1, 'Kareem Abdul-Jabbar,
Milwaukee', 'Bill Sharman', 'LA Lakers'),
('1972-1973', 'New York Knicks', 'Los Angeles Lakers', 4, 1, 'Dave Cowens, Boston',
'Tom Heinsohn', 'Boston'),
('1973-1974', 'Boston Celtics', 'Milwaukee Bucks', 4, 3, 'Kareem Abdul-Jabbar,
Milwaukee', 'Ray Scott', 'Detroit'),
('1974-1975', 'Golden State Warriors', 'Washington Bullets', 4, 0, 'Bob McAdoo,
Buffalo', 'Phil Johnson', 'Kansas City-Omaha'),
('1975-1976', 'Boston Celtics', 'Phoenix Suns', 4, 2, 'Kareem Abdul-Jabbar, LA
Lakers', 'Bill Fitch', 'Cleveland'),
('1976-1977', 'Portland Trail Blazers', 'Philadelphia 76ers', 4, 2, 'Kareem Abdul-
Jabbar, LA Lakers', 'Tom Nissalke', 'Houston'),
('1977-1978', 'Washington Bullets', 'Seattle SuperSonics', 4, 3, 'Bill Walton,
Portland', 'Hubie Brown', 'Atlanta'),
('1978-1979', 'Seattle SuperSonics', 'Washington Bullets', 4, 1, 'Moses Malone,
Houston', 'Cotton Fitzsimmons', 'Kansas City'),
('1979-1980', 'Los Angeles Lakers', 'Philadelphia 76ers', 4, 2, 'Kareem Abdul-
Jabbar, LA Lakers', 'Bill Fitch', 'Boston'),
('1980-1981', 'Boston Celtics', 'Houston Rockets', 4, 2, 'Julius Erving, Philadelphia',
'Jack McKinney', 'Indiana'),
('1981-1982', 'Los Angeles Lakers', 'Philadelphia 76ers', 4, 2, 'Moses Malone,
Houston', 'Gene Shue', 'Washington'),
('1982-1983', 'Philadelphia 76ers', 'Los Angeles Lakers', 4, 0, 'Moses Malone,
Philadelphia', 'Don Nelson', 'Milwaukee'),
('1983-1984', 'Boston Celtics', 'Los Angeles Lakers', 4, 3, 'Larry Bird, Boston',
'Frank Layden', 'Utah'),
('1984-1985', 'Los Angeles Lakers', 'Boston Celtics', 4, 2, 'Larry Bird, Boston', 'Don
Nelson', 'Milwaukee'),
('1985-1986', 'Boston Celtics', 'Houston Rockets', 4, 2, 'Larry Bird, Boston', 'Mike
Fratello', 'Atlanta'),
('1986-1987', 'Los Angeles Lakers', 'Boston Celtics', 4, 2, 'Magic Johnson, LA
Lakers', 'Mike Schuler', 'Portland'),
('1987-1988', 'Los Angeles Lakers', 'Detroit Pistons', 4, 3, 'Michael Jordan,
Chicago', 'Doug Moe', 'Denver'),
('1988-1989', 'Detroit Pistons', 'Los Angeles Lakers', 4, 0, 'Magic Johnson, LA
Lakers', 'Cotton Fitzsimmons', 'Phoenix'),
('1989-1990', 'Detroit Pistons', 'Portland Trail Blazers', 4, 1, 'Magic Johnson, LA
Lakers', 'Pat Riley', 'LA Lakers'),
('1990-1991', 'Chicago Bulls', 'Los Angeles Lakers', 4, 1, 'Michael Jordan, Chicago',
'Don Chaney', 'Houston'),
('1991-1992', 'Chicago Bulls', 'Portland Trail Blazers', 4, 2, 'Michael Jordan,
Chicago', 'Don Nelson', 'Golden State'),
('1992-1993', 'Chicago Bulls', 'Phoenix Suns', 4, 2, 'Charles Barkley, Phoenix', 'Pat
Riley', 'New York'),
('1993-1994', 'Houston Rockets', 'New York Knicks', 4, 3, 'Hakeem Olajuwon,
Houston', 'Lenny Wilkens', 'Atlanta'),
('1994-1995', 'Houston Rockets', 'Orlando Magic', 4, 0, 'David Robinson, San
Antonio', 'Del Harris', 'LA Lakers'),
('1995-1996', 'Chicago Bulls', 'Seattle SuperSonics', 4, 2, 'Michael Jordan, Chicago',
'Phil Jackson', 'Chicago'),
('1996-1997', 'Chicago Bulls', 'Utah Jazz', 4, 2, 'Karl Malone, Utah', 'Pat Riley',
'Miami'),
('1997-1998', 'Chicago Bulls', 'Utah Jazz', 4, 2, 'Michael Jordan, Chicago', 'Larry
Bird', 'Indiana'),
('1998-1999', 'San Antonio Spurs', 'New York Knicks', 4, 1, 'Karl Malone, Utah',
'Mike Dunleavy', 'Portland'),
('1999-2000', 'Los Angeles Lakers', 'Indiana Pacers', 4, 2, 'Shaquille O''Neal, LA
Lakers', 'Doc Rivers', 'Orlando'),
('2000-2001', 'Los Angeles Lakers', 'Philadelphia 76ers', 4, 1, 'Allen Iverson,
Philadelphia', 'Larry Brown', 'Philadelphia'),
('2001-2002', 'Los Angeles Lakers', 'New Jersey Nets', 4, 0, 'Tim Duncan, San
Antonio', 'Rick Carlisle', 'Detroit'),
('2002-2003', 'San Antonio Spurs', 'New Jersey Nets', 4, 2, 'Tim Duncan, San
Antonio', 'Gregg Popovich', 'San Antonio'),
('2003-2004', 'Detroit Pistons', 'Los Angeles Lakers', 4, 1, 'Kevin Garnett,
Minnesota', 'Hubie Brown', 'Memphis'),
('2004-2005', 'San Antonio Spurs', 'Detroit Pistons', 4, 3, 'Steve Nash, Phoenix',
'Mike D''Antoni', 'Phoenix'),
('2005-2006', 'Miami Heat', 'Dallas Mavericks', 4, 2, 'Steve Nash, Phoenix', 'Avery
Johnson', 'Dallas'),
('2006-2007', 'San Antonio Spurs', 'Cleveland Cavaliers', 4, 0, 'Dirk Nowitzki,
Dallas', 'Sam Mitchell', 'Toronto'),
('2007-2008', 'Boston Celtics', 'Los Angeles Lakers', 4, 2, 'Kobe Bryant, LA Lakers',
'Byron Scott', 'New Orleans'),
('2008-2009', 'Los Angeles Lakers', 'Orlando Magic', 4, 1, 'LeBron James,
Cleveland', 'Mike Brown', 'Cleveland'),
('2009-2010', 'Los Angeles Lakers', 'Boston Celtis', 4, 3, 'Kobe Bryant, LA Lakers',
'Scott Brooks', 'Thunder de Oklahoma City'),
('2010-2011', 'Dallas Mavericks' ,'Miami Heat' , 4, 2, 'Derrick Rose, Chicago' ,
'Tom Thibodeau','Chicago');

SELECT temporada, campeon, ganador, perdedor, subcampeon


FROM campeonesNBA
ORDER BY temporada DESC

Ejemplo: Número de jugadores registrados por equipo en primera división de la


primera división del Futbol Mexicano.

SELECT equipo, COUNT(*) registrados


FROM femexfut
WHERE torneo = 'Bicentenario 2010'
GROUP BY equipo

Ejemplo: Número de jugadores por equipo que no participaron ni un minuto en


primera división en el torneo Bicentenario 2010 de la primera división del Futbol Mexicano.

SELECT equipo, COUNT(*) jugadores


FROM femexfut
WHERE torneo = 'Apertura 2010' AND minutos = 0
GROUP BY equipo
ORDER BY jugadores DESC, equipo

HAVING
La cláusula HAVING se utiliza para especificar una condición, se comporta como WHERE,
con la diferencia que HAVING se aplica a grupos y no a tuplas (registros). Es decir HAVING
filtra los registros agrupados.

Ejercicio: Considere la siguiente información relativa a automóviles, modelos y precios

 Cree la base de datos automoviles.


 Cree la tabla carros.
 Inserte los datos de la tabla proporcionada que se encuentra a continuación de estos
puntos.
 Ejecute la consulta propuesta.
 Compare sus resultados con la tabla muestra, y explique lo que sucedió.

MODELO AÑO PRECIO


200
SABLE 50,000
1

200 420,00
AUDI-A4
7 0

200 115,00
BMW-323
0 0

PORSCHE BOXSTER- 200 310,00


987 2 0

199
MALIBU 32,000
8

200
STRATUS-RT 97,500
5

200 185,00
CHRYSLER 300-C
5 0

200 150,00
FUSION
6 0

CUTLASS 199
25,000
EUROSPORT 2

200 135,00
CIVIC COUPE
6 0

200
CIVIC LS-4L 89,000
4

ACCORD EXR-L4 199 53,000


8

200
PLATINA 65,000
5

200
PLATINA 60,000
4

200
ALTIMA 92,000
3

200 179,00
ALTIMA
7 0

200 105,00
ALTIMA
5 0

200
PEUGEOT 206 XR 65,000
6

TOYOTA COROLLA 200 190,00


XRS 9 0

199
VW SEDAN 25,000
8

Calcule el promedio por año para todas las marcas a partir del 2003.

CREATE TABLE carros (


modelo CHAR(25),
year CHAR(4),
precio NUMBER
);

SELECT year,
TO_CHAR(AVG(precio),'999,999.22') media
FROM carros
GROUP BY year
HAVING year > 2002
ORDER BY year;

CREATE TABLE carros (


modelo CHAR(25),
year CHAR(4),
precio INTEGER
) ENGINE = innoDB;

SELECT year, FORMAT(AVG(precio),2) media


FROM carros
GROUP BY year
HAVING year > 2002
ORDER BY year;

2.7. Consultas sobre múltiples tablas

Todos los ejemplos ejecutados hasta ahora tienen una limitación significativa, es decir todas
las columnas incluidas en la tabla resultados provienen de una misma tabla.

La verdadera potencia del SQL se alcanza cuando combinamos el contenido de más de una
tabla. Suponga que desea conseguir una lista con los empleados y los departamentos para
los que trabajan. Esta información está repartida en las dos tablas empleado y
departamento.

Si necesitamos obtener información de más de una tabla, tendremos la opción de utilizar


subconsultas o combinaciones. Si la tabla de resultados final debe contener columnas de
tablas diferentes, entonces deberemos utilizar obligatoriamente una combinación. Para
realizar una combinación, basta incluir más de un nombre en la cláusula FROM, utilizando
una coma como separador y, normalmente, incluyendo una cláusula WHERE para
especificar la columna o columnas con las que hay que realizar la combinación.

Así, podríamos intentar una consulta que seleccionara el campo nombre de la tabla
empleado y el nombre del departamento. Y aquí surge el primer problema, ¿cómo
distinguimos entre dos columnas que llamándose igual, pertenecen a tablas distintas?

El uso de alias para las tablas incluidas en el FROM o en las columnas del SELECT
permite evitar la ambigüedad, el alias se separa por un espacio.

Considere el siguiente modelo físico relacional y su correspondiente código SQL en MySQL y


Oracle
La traducción a SQL es

CREATE TABLE artista (


idArtista NUMBER,
nombreArtista CHAR(35) NOT NULL,
CONSTRAINT pk_Artista PRIMARY KEY (idArtista),
CONSTRAINT ak_nombreArtista UNIQUE ( nombreArtista )
);

CREATE TABLE disco (


asin CHAR(12),
idArtista NUMBER NOT NULL,
nombreAlbum CHAR(20) NOT NULL,
yearLanzamiento NUMBER(4),
marca CHAR(20),
CONSTRAINT pk_disco PRIMARY KEY (asin),
CONSTRAINT fk_artistaDisco FOREIGN KEY (idArtista) REFERENCES artista
(idArtista)
);

CREATE TABLE canciones (


idCancion NUMBER,
posicion NUMBER NOT NULL,
asin CHAR(12) NOT NULL,
nombreCancion CHAR(30) NOT NULL,
duracion CHAR(6),
estilo CHAR(15),
CONSTRAINT pk_canciones PRIMARY KEY (idCancion),
CONSTRAINT fk_DiscoCanciones FOREIGN KEY (asin) REFERENCES disco (asin)
);
-- MySQL

CREATE DATABASE Discos;


USE Discos;

DROP TABLE IF EXISTS canciones, disco, artista;


CREATE TABLE artista (
idArtista INTEGER,
nombreArtista CHAR(35) NOT NULL,
CONSTRAINT pk_Artista PRIMARY KEY (idArtista),
CONSTRAINT ak_nombreArtista UNIQUE ( nombreArtista )
) ENGINE = innoDB;

CREATE TABLE disco (


asin CHAR(12),
idArtista INTEGER NOT NULL,
nombreAlbum CHAR(20) NOT NULL,
yearLanzamiento INTEGER(4),
marca CHAR(20),
CONSTRAINT pk_disco PRIMARY KEY (asin),
CONSTRAINT fk_artistaDisco FOREIGN KEY (idArtista)
REFERENCES artista (idArtista)
) ENGINE = innoDB;

CREATE TABLE canciones (


idCancion INTEGER AUTO_INCREMENT,
posicion INTEGER NOT NULL,
asin CHAR(12) NOT NULL,
nombreCancion CHAR(30) NOT NULL,
duracion CHAR(6),
estilo CHAR(15),
CONSTRAINT pk_canciones PRIMARY KEY (idCancion),
CONSTRAINT fk_DiscoCanciones FOREIGN KEY (asin) REFERENCES
disco (asin)
) ENGINE = innoDB;

INSERT INTO artista VALUES (1, 'Marc Anthony');


INSERT INTO disco VALUES ('B000ROALCG',1,'El
cantante',2007,'Sony International');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (1,'B000ROALCG', 'El
cantante','6:49','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (2,'B000ROALCG', 'Mi
gente','3:52','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (3,'B000ROALCG',
'Escandalo','3:59','Bolero');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (4,'B000ROALCG',
'Aguanile','5:16','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (5,'B000ROALCG', 'Che Che
Colé','3:26','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (6,'B000ROALCG', 'El día de mi
suerte','5:20','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (7,'B000ROALCG', 'Qué
lío','4:24','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (8,'B000ROALCG', 'Quítate tú pa
ponerme yo','4:24','Bolero');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (9,'B000ROALCG', 'Todo tiene su
final','4:56','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (10,'B000ROALCG', 'Toma de
mí','4:29','Salsa');
INSERT INTO artista VALUES (2, 'Victor Manuelle');
INSERT INTO disco VALUES ('B005STGJ2Q',2,'Busco un
pueblo',2011,'Sony U.S. Latin');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (1,'B005STGJ2Q', 'Cómo le digo al
alma','4:05','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (2,'B005STGJ2Q', 'Duele sin
ti','3:41','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (3,'B005STGJ2Q', 'Junto a
ti','4:28','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (4,'B005STGJ2Q', 'Si tú me
besas','4:19','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (5,'B005STGJ2Q', 'Busco un
pueblo','4:24','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (6,'B005STGJ2Q', 'Ella cambió mi
vida','5:11','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (7,'B005STGJ2Q', 'Ella lo que quiere
es salsa','4:07','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (8,'B005STGJ2Q', 'Termina en un
beso','3:07','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (9,'B005STGJ2Q', 'Amar de
nuevo','4:28','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (10,'B005STGJ2Q', 'Duele sin ti
','3:57','Balada');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (11,'B005STGJ2Q', 'Llegaste
tú','4:44','Balada');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (12,'B005STGJ2Q', 'Amar de
nuevo','3:56','Balada');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (13,'B005STGJ2Q', 'Si tú me
besas','4:17','Balada');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (14,'B005STGJ2Q', 'Llegaste
tú','4:34','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (15,'B005STGJ2Q', 'Las huellas de tu
amor','3:55','Salsa');
INSERT INTO artista VALUES (3, 'Tito Nieves');
INSERT INTO disco VALUES ('B005KG4D8O',2,'Mi última
grabación',2011,'No registrada');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (1,'B005KG4D8O', 'Éres
linda','4:30','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (2,'B005KG4D8O', 'Por eso estoy
contigo','3:42','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (3,'B005KG4D8O', 'Éres
linda','3:27','Balada');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (4,'B005KG4D8O', 'La
verdad','4:44','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (5,'B005KG4D8O', 'Lo mejor que me ha
pasado','4:35','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (6,'B005KG4D8O', 'Si tú
supieras','3:27','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (7,'B005KG4D8O', 'Cuando estoy
contigo','4:52','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (8,'B005KG4D8O', 'Dícelo
así','3:34','Salsa');
INSERT INTO canciones (posicion, asin, nombreCancion,
duracion, estilo) VALUES (9,'B005KG4D8O', 'El silencio de tu
amor','3:36','Salsa');

SELECT * FROM artista, disco

El resultado es incorrecto, ya que obtenemos es el producto cartesiano de todos los artistas


por todos los discos. SQL tomo cada fila de la tabla disco y le ha asociado todos los
idArtista de la tabla artista.

Reglas de Combinación:
 Pueden combinarse tantas tablas como se desee.
 El criterio de combinación puede estar formado por más de una pareja de columnas.
 En la cláusula SELECT pueden citarse columnas de ambas tablas, condicionen o no la
combinación.
 Si hay columnas con el mismo nombre en las distintas tablas, deben identificarse
especificando la tabla de procedencia o utilizando un alias de tabla.
 Es necesario incluir una clasula WHERE que asocie las tablas mediante las correspondientes
llaves
Para lograr el resultado correcto necesitamos asociar un disco con el nombre del artista que
lo interpreta. Y esto se puede hacer si añadimos la condición en la cual idArtista el mismo
valor en la fila de la tabla disco que en la fila correspondiente de la tabla artista.

SELECT * FROM artista A, disco D


WHERE A.idArtista = D.idArtista

Ejemplo: Considere el siguiente Modelo físico relacional. Que descibe las relaciones
existentes para el torneo apertura 2009 del futbol Mexicano de 1era división.

Para crear la estructura y los datos, es necesario realizar el siguiente procedimiento:

Utilice el script Apertura.sql

Ejemplo: Generar un listado con los nombres de todos los jugadores del América que
jugaron como porteros durante el torneo Apertura 2009.

SELECT E.nombreEquipo,
J.nombre Nombre,
P.nombrePosicion Posicion
FROM equipo E, posicion P, jugador J
WHERE (J.idEquipo = E.idEquipo) AND ( J.idEquipo = 1)
AND (J.idPosicion = 1)
AND (P.idPosicion = J.idPosicion) AND (J.jj >0 )
ORDER BY J.nombre

2.8. Subconsultas

Una subconsulta es una instrucción SELECT anidada dentro de una sentencia SELECT,
SELECT...INTO, INSERT...INTO,DELETE, o UPDATE o dentro de otra subconsulta.

Una subconsulta, a su vez, puede contener otra subconsulta y así hasta un máximo de 16
niveles. Las particularidades de las subconsultas son:

1. Su resultado no se visualiza, sino que se pasa a la consulta principal para su


comprobación.
2. Puede devolver un valor único o una lista de valores y en dependencia de esto se debe
usar el operador del tipo correspondiente.
3. No puede usar el operador BETWEEN, ni contener la sentencia ORDER BY.
4. Puede contener una sola columna, que es lo más común, o varias columnas. Este último
caso se llama subconsulta con columnas múltiples. Cuando dos o más columnas serán
comprobadas al mismo tiempo, deben encerrarse entre paréntesis.

Ejemplo: Municipios sin asentamientos en el estado de Veracruz (idEstado = 30)

SELECT M.municipio, M.idMunicipio FROM municipios M


LEFT JOIN asentamientos A
ON M.idMunicipio = A.idMunicipio
WHERE (M.idEstado = 30) AND (A.idMunicipio IS NULL)
ORDER BY M.municipio

Ejemplo: Nombres de los jugadores que han participado más que el promedio, equipo y
posición durante un torneo

Ejecute el script FedMexFut.sql


La consulta más interna calcula el promedio de minutos jugados, y la consulta más externa lo
utiliza para seleccionar los nombres de los jugadores que participan más del promedio.

El valor de comparación puede ser un valor simple, como en el ejemplo anterior, o un


conjunto de valores. Hay que tener en cuenta este detalle ya que el tipo de operador a utilizar
varía. En el primer caso se puede utilizar un operador de comparación de carácter aritmético
(<, >, etc.). Y en el segundo uno de tipo lógico (IN).

Las subconsultas pueden devolver más de una columna, y se habrán de comparar de


manera consecuente:

 Las columnas de la clausula WHERE de la consulta principal deben estar agrupadas por
paréntesis.
 Las columnas encerradas entre paréntesis deben coincidir en número y tipo de datos con
los datos que devuelve la subconsulta.

Se puede utilizar una subconsulta para insertar valores en una tabla en el momento de la
creación de la misma.

Ejemplo: Crear una tabla con los datos de los jugadores que participan más que el promedio
y su desviación:

CREATE TABLE borrame


SELECT minutos, nombreJugador FROM femexfut
WHERE minutos > (
SELECT AVG(minutos) + STDDEV(minutos)
FROM femexfut
WHERE jj > 0 AND torneo = 'Bicentenario 2010')
AND torneo = 'Bicentenario 2010'
ORDER BY minutos DESC, nombreJugador

No es necesario especificar tipos ni tamaños de las columnas, ya que vienen determinados


por los tipos y tamaños de las columnas recuperadas en la subconsulta.
Ejemplo: Valor más reciente del dólar en la base de datos

SELECT fecha, precio


FROM dolar
WHERE fecha = ( SELECT MAX(fecha) FROM dólar;

2.9. Operadores Join

Las consultas multitabla o JOINS también denominadas combinaciones o composiciones,


permiten recuperar datos de dos tablas o más según las relaciones lógicas entre ellas. Las
combinaciones indican cómo debería utilizar el SGBD los datos de una tabla para seleccionar
los datos de otra tabla.

Una condición de combinación (o composición) define la forma en la que dos tablas se


relacionan en una consulta al:

 Especificar la columna de cada tabla que debe usarse para la combinación. Una condición de
combinación específica una clave externa de una tabla y su clave asociada en otra tabla.
Relación padre - hija.
 Especificar un operador lógico (=, <>, etc.) para usarlo en los valores de comparación de las
columnas

Es una operación que combina registros de dos tablas en una base de datos relacional que
resulta en una nueva tabla (temporal) llamada tabla de JOIN. En el lenguaje de consulta SQL
hay dos tipos de JOIN: INNER y OUTER.

Como caso especial, una tabla (tabla base, vista o una tabla JOIN) puede realizar la
operación JOIN sobre ella misma. Esto se conoce como self-JOIN.

Ejemplo: Jugadores que participaron con el Cruz Azul durante el torneo Apertura 2011,
minutos jugados y partidos en los que participo (JJ)

Utilice el script Apertura2011.sql

Ejemplo: Jugadores por posición del Cruz Azul que participaron al menos un minuto en el
Apertura 2011

SELECT J.nombre, J.jj, J.minutos, P.nombrePosicion


FROM jugadores_Clausura2011 J, equipos E, posicion P
WHERE (J.idEquipo = E.idEquipo)
AND (E.idEquipo = 5) AND (J.minutos > 0 )
AND (J.idPosicion = P.idPosicion)
ORDER BY J.jj DESC, J.minutos DESC, J.nombre

Left outer join produce el conjunto completo de registros de la tabla Equipos, con los
registros coincidentes (si están disponibles) en la tablaJugadores. Si no hay coincidencia, el
lado derecho contendrá NULL.

Note que la integridad referencial de la tabla Jugadores, no permite que los deportistas no
esten asignados a un Equipo.

SELECT E.equipo, J.nombre, J.jj


FROM equipos E
LEFT OUTER JOIN jugadores_Clausura2011 J
ON E.idEquipo = J.idEquipo
ORDER BY E.equipo, J.nombre, J.jj;

SELECT E.equipo, J.nombre, J.jj


FROM equipos E, jugadores_Clausura2011 J
WHERE E.idEquipo = J.idEquipo(+)
ORDER BY E.equipo, J.nombre, J.jj;
Para producir el conjunto de registros en la tabla Equipos, pero no en la tabla Participa,
usamos la sentencia Left Outer Join, y luego excluimos los registros que no
queremos del lado derecho mediante una cláusula where. El resultado de la consulta
son todos aquellos equipos que no participan en el torneo Clasura 2012.

SELECT * FROM equipos E, participa P


WHERE E.idEquipo = P.idEquipo(+)
AND P.idEquipo IS NULL

SELECT E.Equipo FROM equipos E


LEFT OUTER JOIN
(SELECT idEquipo FROM participa WHERE idTorneo = 88) P
ON E.idEquipo = P.idEquipo
WHERE P.idEquipo IS NULL
Para producir el conjunto de registros únicos de la tabla Departamento y la tabla Empleado,
usamos el mismo Full Outer Join, y luego excluimos los registros que no queremos de
los dos lados mediante una cláusula Where

SELECT * FROM departamento d


FULL OUTER JOIN empleado e
ON d.idDepartamento = e.idDepartamento
WHERE e.idDepartamento IS NULL
OR d.idDepartamento IS NULL

SELECT * FROM departamento d, empleado e


WHERE d.idDepartamento = e.idDepartamento(+)
AND (e.idDepartamento IS NULL
OR d.idDepartamento IS NULL)

Full outer join produce el conjunto de todos los registros en las tablas Departamento y
Empleado, con registros coincidentes en ambos lados cuando sea posible. Si no hay
coincidencia, el lado que falta contendrá null.

SELECT * FROM departamento d


FULL OUTER JOIN empleado e
ON d.idDepartamento =
e.idDepartamento

2.10. Vistas

Una vista es una tabla virtual cuyo contenido está definido por una consulta..

Una vista es sencillamente un objeto de base de datos que presenta datos de tablas. Se trata
de una consulta SQL que está permanentemente almacenada en la Base de datos y a la que
se le asigna un nombre, de modo que los resultados de la consulta almacenada son visibles
a través de la vista, y SQL permite acceder a estos resultados como si fueran de hecho una
tabla real en la base de datos.

Las tablas y las vistas comparten el mismo espacio de nombres en la base de datos, por lo
tanto, una base de datos no puede contener una tabla y una vista con el mismo nombre.

Las vistas suelen utilizarse para centrar, simplificar y personalizar la percepción de la base de
datos para cada usuario. Las vistas pueden emplearse como mecanismos de seguridad, que
permiten a los usuarios obtener acceso a los datos por medio de la vista, pero no les
conceden el permiso de obtener acceso directo a las tablas subyacentes de la vista. Las
vistas se pueden utilizar para realizar particiones de datos y para mejorar el rendimiento
cuando se copian, se importan y se exportan datos.

Mediante vistas es posible presentar datos de distintos servidores. Por ejemplo, para
combinar datos de distintos servidores remotos o en un servidor de múltiples procesadores,
cada uno de los cuales almacenan datos para una región distinta de su organización, puede
crear consultas distribuidas o paralelas aumentando la eficiencia de las consultas.

Mediante diversas cláusulas es factible crear, modificar, eliminar y administrar vistas. La


sintaxis básica para estas cláusulas es genérica entre diversos gestores de base de datos.
Sin embargo en lo particular cada gestor implementa la administración de estas de forma
diferente. En este documento se presenta la sintaxis particular de Oracle 10g, comparando
en forma genérica con MySQL 5.

La sintaxis básica de una vista (Oracle y MySQL) es:

CREATE VIEW nombre_vista AS consulta;

Sintaxis CREATE VIEW

CREATE [OR REPLACE]


VIEW nombre_vista
AS sentencia_select
[WITH [CASCADED | LOCAL] CHECK OPTION]
WITH READ ONLY;

CREATE [OR REPLACE]


[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW nombre_vista [(columnas)]
AS sentencia_select
[WITH [CASCADED | LOCAL] CHECK OPTION]

Ejemplo: Paises del continente Americano


Utilice el scripts Paises.sql

Ahora solo tenemos que hacer una consulta para obtener la vista correspondiente.
SELECT * FROM america;

Ejemplo: En el futbol se conoce como Caballo de Hierro a los deportistas que jugaron los 90
minutos en todos los partidos de un campeonato. Y Considerando que en el torneo de
Apertura 2011 se disputaron 17 fechas en la fase regular. La vista que define a estos
futbolistas es la siguiente.

CREATE OR REPLACE VIEW caballoDeHierro AS


SELECT e.nombreEquipo, j.nombre, j.JJ
FROM equipo e, jugadores j
WHERE e.idEquipo = j.idEquipo
AND j.JJ >= 17 AND minutos >= (j.JJ * 90)
AND (j.JJ % 2 != 0)
ORDER BY j.minutos DESC, j.nombre;

Ahora solo tenemos que hacer una consulta para obtener la vista correspondiente.

SELECT * FROM caballoDeHierro;

Ejemplo. El cual modificará la vista caballo de hierro con los jugadores que no recibieron
amonestaciones.

CREATE OR REPLACE VIEW caballoDeHierro AS


SELECT nombrePosicion, e.nombreEquipo equipo, j.nombre, j.JJ,j.ta
FROM equipo e, jugador j, posicion p
WHERE e.idEquipo = j.idEquipo
AND p.idPosicion = j.idPosicion
AND j.JJ >= 17 AND minutos >= (j.JJ * 90)
AND (j.JJ % 2 != 0) AND (j.ta = 0 )
ORDER BY nombre;

SELECT * FROM caballoDeHierro;

Actualización de vistas

Algunas vistas pueden actualizarse mediante sentencias INSERT, DELETE o UPDATE


sobre ellas, considerando las siguientes reglas:
 No se debe especificar DISTINCT para que las filas duplicadas no se eliminen de los
resultados de las consultas.
 La cláusula FROM debe especificar sólo una tabla actualizable.
 Cada elemento de selección debe ser una referencia de columna simple (no puede contener
expresiones, columnas calculadas, ni funciones de columna).
 La cláusula WHERE no debe incluir una subconsulta.
 La consulta no debe incluir una cláusula GROUP BY o HAVING.
 La consulta no debe incluir sentencias: UNION, UNION ALL, INTERSECT, MINUS
 Si una columna NOT NULL no contiene un DEFAULT, no es posible insertar mediante
vistas

Para que la vista sea de solo lectura, usaremos la cláusula WITH READ ONLY (Oracle).
Observe que esta opción no soporta la cláusula ORDER BY

La cláusula CHECK OPTION evita que sean insertados o modificados registro que no
sean posteriormente incluidos en la vista mediante la sentencia WHERE.

Ejemplo: Población por entidad federativa 2010 INEGI (INSTITUTO NACIONAL DE


ESTADISTICA, GEOGRAFIA E INFORMATICA). El ejemplo siguiente crea una vista que usa
la cláusula CHECK OPTION donde seleccionan aquellas entidades federativas que tienen
menos de 2 millones de habitantes.

CREATE TABLE entidad (


estado CHAR(30) NOT NULL,
poblacion NUMBER NOT NULL
);

CREATE TABLE entidad (


estado CHAR(30) NOT NULL,
poblacion INTEGER NOT NULL
) ENGINE = InnoDB;

INSERT INTO entidad values ('Estado de México', 15175862);


INSERT INTO entidad values ('Distrito Federal', 8851080);
INSERT INTO entidad values ('Veracruz', 7643194);
INSERT INTO entidad values ('Jalisco', 7350682);
INSERT INTO entidad values ('Puebla', 5779829);
INSERT INTO entidad values ('Guanajuato', 5486372);
INSERT INTO entidad values ('Chiapas', 4796580);
INSERT INTO entidad values ('Nuevo León', 4653458);
INSERT INTO entidad values ('Michoacán de Ocampo',4351037);
INSERT INTO entidad values ('Oaxaca', 3801962);
INSERT INTO entidad values ('Chihuahua', 3406465);
INSERT INTO entidad values ('Guerrero', 3388768);

CREATE OR REPLACE VIEW entidades AS


SELECT * FROM entidad
WHERE poblacion < 2000000
WITH CHECK OPTION;

Ahora considere la siguiente información. Para insertarla en la vista recién creada.

Entidad Población
Tamaulipas 3,268,554

Baja California 3,155,070

Sinaloa 2,767,761

Coahuila de
2,748,391
Zaragoza

Hidalgo 2,665,018

Sonora 2,662,480

San Luis Potosí 2,585,518

Tabasco 2,238,603

Yucatán 1,955,577

Querétaro 1,827,937
Morelos 1,777,227

Durango 1,632,934

Zacatecas 1,490,668

Quintana Roo 1,325,578

Aguascalientes 1,213,445

Tlaxcala 1,169,936

Nayarit 1,084,979

Campeche 822,441

Colima 650,555

Baja California Sur 637,026

Con la cláusula CHECK OPTION cada vez que se trata de hacer una violación de la
condición dentro del WHERE obtendremos un error ORA-01402. Que error le regresa
MySQL

Borrado de vistas con DROP VIEW

La sentencia DROP VIEW permite borrar una vista de la base de datos. Su sintaxis se
presenta a continuación:

DROP VIEW [usuario.] nombre_vista [CASCADE CONSTRAINTS];

DROP VIEW [IF EXISTS] nombre_vista;


UNIDAD III. CONTROL
DE ACCESO
3.1. Tipos de usuarios

El objetivo de la creación de usuarios es establecer una cuenta segura y útil, que tenga los
privilegios adecuados y los valores por defecto apropiados

Para acceder a los datos en una BD Oracle, se debe tener acceso a una cuenta en esa BD.
Cada cuenta debe tener una palabra clave o password asociada. Una cuenta en una BD
puede estar ligada con una cuenta de sistema operativo. Los passwords son fijados cuando
se crea un usuario y pueden ser alterados por el DBA o por el usuario mismo. La BD
almacena una versión encriptada del password en una tabla del diccionario llamada
dba_users. Si la cuenta en la BD está asociada a una cuenta del sistema operativo puede
evitarse la comprobación del password, dándose por válida la comprobación de la identidad
del usuario realizada por el SO.

Un usuario Oracle tiene las siguientes características

 Un nombre de usuario de 30 caracteres o menos, sin caracteres especiales y que inicie con
una letra.
 Un método de autentificación, el más común es un password pero Oracle 10G soporta otros
métodos como biometric, certificado y autentificacion por medio de token.
 Un tablespace de default, el cuál es donde el usuario va a poder crear sus objetos por defecto.
Ojo, no porque tenga un tablespace de default va a significar que puede crear objetos, o una
quota de espacio. Estos permisos se asignan de forma separada.
 Un tablespace temporal, donde el usuario pueda crear sus objetos temporales y hacer ordenar
las consultas.
 Un perfil de usuario, es decir las restricciones o privilegios de su cuenta.

Una cuenta MySQL se define en términos de un nombre de usuario y el equipo o equipos


desde los que el usuario puede conectar al servidor. La cuenta también tiene una contraseña
(deseable). Los nombres de usuario y contraseñas en MySQL no están relacionadas con los
del sistema operativo.

 Nombre de usuarios en MySQL pueden tener como máximo 16 caracteres de longitud


 La contraseña es segura incluso si los paquetes TCP/IP pasan por un sniffer o la base de
datos mysql se captura.
3.2. Creación de usuarios

CREATE USER: Crear un usuario oracle.

Un usuario es un nombre de acceso a la base de datos oracle asociado a una clave


(password).

Lo que puede hacer un usuario logeado a la base de datos depende de los permisos que
tenga asignados ya sea directamente ( GRANT) como sobre algún rol que tenga asignado
(CREATE ROLE).

El perfil que tenga asignado influye en los recursos del sistema de los que dispone un
usuario a la hora de ejecutar Oracle (CREATE PROFILE).

CREATE USER usuarioLimitado


IDENTIFIED BY miClaveSecreta;

CREATE USER usuarioLimitado2


IDENTIFIED BY miClaveSecreta
PASSWORD EXPIRE;

CREATE USER usuarioLimitado


IDENTIFIED BY 'miClaveSecreta';

SELECT * FROM dba_users;

USE mysql;

SELECT host, user, password


FROM user;

Borrar usuarios

Tanto Oracle como MySQL permiten eliminar usuarios mediante la sentencia DROP USER,
con una sintaxis similar

DROP USER usuarioLimitado CASCADE;

CASCADE borra todos los objetos del esquema del usuario Oracle antes de borrar el
usuario. Si el esquema contiene tablas, Oracle borrará todos las tablas y automáticamente
eliminará cualquier restricción de integridad referencial referida a claves primarias o únicas
en otros esquemas

MySQL realiza la misma actividad mediante la combinación de sentencias REVOKE y DROP.

REVOKE ALL PRIVILEGES, GRANT OPTION FROM usuario;

DROP USER usuario;

Comando GRANT
Se utiliza para crear usuarios y concederle privilegios. La sintaxis general del comando
GRANT es la siguiente:

GRANT privilegios (columnas)


ON elemento
TO nombre_usuario IDENTIFIED BY 'contraseña'
(whith grant option);

Lo que está dentro de los paréntesis son opcionales, y los paréntesis no hay que ponerlos.
Es importantísimo que al final poner el ';' después de poner cada línea pulsar 'intro', pues si
hay algún error mysql nos indicará en que línea está el error.

3.3. Privilegios de usuarios

Una vez creados los usuarios será necesario dotarlos de privilegios para que puedan realizar
operaciones específicas en la base de datos. Estos privilegios suelen clasificarse en
privilegios del sistema (operaciones que afectan a todo el sistema) y privilegios de objeto
(tablas, vistas, etc.). Para conocer los privilegios y su sintaxis es necesario consultar los
manuales de referencia de su SGBD.

SELECT * FROM system_privilege_map;

Las sentencias GRANT y REVOKE permiten a los administradores de SGBD crear cuentas
de usuario, conceder y revocar derechos de esas cuentas.

GRANT CONNECT, RESOURCE, CREATE TABLE


TO usuarioLimitado;

La información sobre cuentas MySQL se almacena en las tablas de la base de datos mysql.
Los privilegios pueden ser concedidos en varios niveles:

Nivel global

Los privilegios globales se aplican a todas las bases de datos de un servidor dado. Estos
privilegios se almacenan en la tabla mysql.user.
GRANT ALL ON *.* y REVOKE ALL ON *.*
Conceden y revocan sólo privilegios globales.

Nivel de base de datos

Los privilegios de base de datos se aplican a todos los objetos en una base de datos dada.
Estos privilegios se almacenan en las tablas mysql.dby mysql.host.
GRANT ALL ON db_name.* y REVOKE ALL ON db_name.*
Otorgan y revocan sólo privilegios de base de datos.
Nivel de tabla

Los privilegios de tabla se aplican a todas las columnas de una tabla dada. Estos privilegios
se almacenan en la tabla mysql.tables_priv.
GRANT ALL ON db_name.tbl_name y REVOKE ALL ON db_name.tbl_name
Conceden y revocan únicamente privilegios de tabla.

Nivel de columna

Los privilegios de columna se aplican a una columna individual en una tabla dada. Estos
privilegios se almacenan en la tabla mysql.columns_priv. Cuando se usa REVOKE, se
deben especificar las mismas columnas que cuando se concedieron los privilegios.

Nivel de procedimiento

Los privilegios CREATE ROUTINE, ALTER ROUTINE, EXECUTE y GRANT se aplican a


procedimientos almacenados. Pueden ser concedidos en el nivel global y de base de datos.
Además, excepto para CREATE ROUTINE, estos privilegios pueden ser concedidos en el
nivel de procedimiento para procedimientos individuales y se almacenan en la tabla
mysql.procs_priv. Para hacer más sencillo revocar todos los privilegios, MySQL añadido la
siguiente sintaxis, que elimina todos los privilegios de los niveles de global, de base de datos,
tabla y columna para los usuarios nombrados:

mysql> REVOKE ALL PRIVILEGES, GRANT OPTION FROM usuario [, usuario] ...

Asignar todos los privilegios menos los GRANT OPTION

GRANT ALL ON *.* TO miUsuario


Mostrar los privilegios del usuario
3.4. Roles

Un rol es una colección de privilegios del sistema y de objetos que se otorgan a usuarios y a
otras tareas. Oracle dispone de muchos roles predeterminados mientras que MySQL no los
soporta.

El rol CONNECECT permite al usuario conectarse a la base de datos, crear tablas, vistas,
secuencias, sinónimos y otros objetos en el esquema asociado.

El rol RESOURCE permite al usuario utilizar los recursos típicos para la programación de
aplicaciones (clusters, disparadores, paquetes, funciones, etc.)

El rol DBA, típico de los administradores, permite al usuario realizar cualquier función de
base de datos y disponer de cualquier privilegio

La sentencia que permite crear roles es CREATE ROL. Su sintaxis es la siguiente

CREATE ROLE rol


[ NOT IDENTIFIED
| IDENTIFIED {BY password | USING [usuario.] paquete
| EXTERNALLY | GLOBALLY }
];

NOT IDENTIFIED indica que no se requiere contraseña para utilizar el rol,


INDENTIFIED BY password indica que se requiere la contraseña especificada.
EXTERNALLY crea un rol de usuario externo y GLOBALLY crea un rol de usuario global.

Ejemplo: Crear un rol y asignarle privilegios

CREATE ROLE miPrimerRole;


GRANT SELECT, INSERT, UPDATE, DELETE ON tabla
TO miPrimerRole;

Ejemplo: Crear un rol y asignarle todos los privilegios

CREATE ROLE miPrimerRole;


GRANT all ON tabla
TO miPrimerROLE;
Ejemplo: Asignar un rol a un usuario

GRANT miPrimerRole TO miUsuario;

Ejemplo: Eliminar un rol

DROP ROLE miPrimerRole;


UNIDAD IV.
CONCURRENCIA
4.1. Conceptos básicos

Desde el punto de vista del usuario la interacción con la base de datos se lleva a cabo
mediante operaciones con significado en el modelo semántico (por ejemplo, una
transferencia de fondos en un banco).

Desde el punto de vista de la base de datos estas operaciones pueden estar formadas por
varias operaciones elementales (por ejemplo, quitar fondos de una cuenta y añadírselos a
otra)

Se llama Transacción a una colección de operaciones que forman una unidad lógica de
trabajo en una BD realizada por una o más sentencias SQL estrechamente relacionadas.

Una transacción es una unidad de la ejecución de un programa que lee y escribe datos a y
desde la Base de Datos. Puede consistir en varias operaciones de acceso a la base de
datos. Una Transacción está delimitada por instrucciones de inicio transacción y fin
transacción (la transacción consiste en todas las operaciones que se ejecutan entre inicio
transacción y fin transacción).

El concepto de transacción se desarrolló para atender los casos en los que el estado
resultante de la base de datos depende del éxito completo en una serie de operaciones. Este
concepto vio la luz debido a que varias operaciones sucesivas pueden modificar el resultado
de operaciones anteriores. En esos casos, si alguna operación produce un error, el estado
resultante puede ser indeterminado.

Para solucionar este problema, las transacciones agrupan una serie de operaciones de
manera que es posible garantizar la integridad del resultado final. O todas las operaciones se
ejecutan con éxito y se confirman (se escriben en la base de datos), o toda la transacción se
considera no realizada. La acción de cancelar una transacción se denomina deshacer la
transacción. Deshacer una transacción permite anular los cambios y recuperar el estado de
la base de datos previo a la transacción.

Por ejemplo, en una transacción bancaria automatizada, si un banco transfiere dinero desde
la cuenta A a la cuenta B, la retirada de fondos de A y el depósito en B deben producirse con
éxito para procesar los fondos correctamente, de lo contrario la transacción entera debe
cancelarse.

Esquematizando el proceso de transacciones temos: O se ejecutan todas las operaciones


que componen la transacción, o no se realiza ninguna.
En SQL

Éxito Fracaso

Begin transacction Begin transacction


Instrucción 1 Instrucción 1
Instrucción 2 Instrucción 2
... ...
Commit work Rollback work
End transacction End transacction

4.2. Propiedades de la Transacción

Una unidad lógica de trabajo debe exhibir cuatro propiedades, conocidas como propiedades
ACID (atomicidad, coherencia, aislamiento y durabilidad),
para ser calificada como transacción.

 Atomicidad: Una Transacción (Tx) se ejecuta completamente o de otra manera se eliminan


los cambios parciales realizados.

Begin Transaction - Programa - End Transaction

Responsable: El método de recuperación, de no completar todas las operaciones, devuelve


la BD a su estado anterior a empezar esa Tx(rollback).

 Coherencia: Asegura que los datos que observamos no cambian (por otros usuarios) hasta
que acabemos la Transacción.

Después de terminar una Transacción la Base de datos no viola ninguna de sus reglas:
valores obligatorios, claves únicas, etc.

Responsable: los programadores mediante la definición adecuada de la integridad


referencial: check, triggers, primary key,foreign key,…

 Aislamiento: Los efectos de una Tx no son visibles a otros usuarios mientras no se


confirmen.

Una Transacción en ejecución no puede revelar sus resultados a otras transacciones


concurrentes antes de finalizar.

Más aún, si varias transacciones, se ejecutan concurrentemente, los resultados deben ser los
mismos que si ellas se hubieran ejecutado secuencialmente. Esto se conoce como
seriabilidad debido a que su resultado es la capacidad de volver a cargar los datos iniciales y
reproducir una serie de transacciones para finalizar con los datos en el mismo estado en que
estaban después de realizar transacciones originales.

Responsable: el método de concurrencia: mecanismos, reglas, protocolos

 Durabilidad: Si el sistema falla no debe permitir que se pierdan las operaciones realizadas
por Tx ya confirmadas.

Responsable: el método o gestor de recuperación.

Estados y operaciones de una transacción

Control de transacciones en Oracle

Inicio de transacción

Cuando no hay ya una transacción en progreso, y se ejecuta una sentencia LDD o LMD
(interactivamente o dentro de una aplicación)

Cada sentencia LDD es tratada como una transacción N

No existe sentencia de tipo BEGIN TRANSACTION


Fin de transacción
COMMIT: Finaliza la transacción actual y hace permanentes (confirma) los cambios
realizados
ROLLBACK: Finaliza la transacción actual y deshace los cambios realizados

Sentencia COMMIT

Una sentencia COMMIT marca el final de una transacción correcta, implícita o definida por el
usuario. COMMIT hace que todas las modificaciones efectuadas sobre los datos desde el
inicio de la transacción sean parte permanente de la base de datos, y además, libera los
recursos mantenidos por la conexión. Su sintaxis es la siguiente:

COMMIT COMMENT 'mensaje' | FORCE 'texto']


COMMENT sirve para comentar la transacción en un máximo 255 caracteres. FORCE fuera
de modo manual una transacción dudosa y es de uso exclusivo en sistemas distribuidos de
base de datos.

Sentencia SAVEPOINT

Esta sentencia permite crear un punto de restauración dentro de una transacción, es decir,
un punto al que podremos retroceder deshaciendo todo lo hecho deshaciendo todo lo hecho
desde él en adelante. Su sintaxis es la siguiente

SAVEPOINT nombrePuntoRestauración;

Sentencia ROLLBACK
Señala el final sin éxito de una transacción, elimina todas las modificaciones de datos
realizadas desde el inicio de la transacción y también libera los recursos que retiene la
transacción. Su sintaxis es la siguiente:

ROLLBACK [WORK] [TO SAVEPOINT nombrePuntoRestauración | FORCE 'texto'];

4.3. Grados de consistencia

Consistencia es un término más amplio que el de integridad. Podría definirse como la


coherencia entre todos los datos de la base de datos. Cuando se pierde la integridad también
se pierde la consistencia. Pero la consistencia también puede perderse por razones de
funcionamiento.

Una transacción finalizada (confirmada parcialmente) puede no confirmarse definitivamente


(consistencia).

 Si se confirma definitivamente el sistema asegura la persistencia de los cambios que ha


efectuado en la base de datos.

 Si se anula los cambios que ha efectuado son deshechos.

La ejecución de una transacción debe conducir a un estado de la base de datos consistente


(que cumple todas las restricciones de integridad definidas).

 Si se confirma definitivamente el sistema asegura la persistencia de los cambios que ha


efectuado en la base de datos.

 Si se anula los cambios que ha efectuado son deshechos.


Una transacción que termina con éxito se dice que está comprometida (commited), una
transacción que haya sido comprometida llevará a la base de datos a un nuevo estado
consistente que debe permanecer incluso si hay un fallo en el sistema. En cualquier
momento una transacción sólo puede estar en uno de los siguientes estados.

 Activa (Active): el estado inicial; la transacción permanece en este estado durante su


ejecución.

 Parcialmente comprometida (Uncommited): Después de ejecutarse la última transacción.


 Fallida (Failed): tras descubrir que no se puede continuar la ejecución normal.

 Abortada (Rolled Back): después de haber retrocedido la transacción y restablecido la base


de datos a su estado anterior al comienzo de la transacción.

 Comprometida (Commited): tras completarse con éxito.

Aspectos relacionados al procesamiento de transacciones

Los siguientes son los aspectos más importantes relacionados con el procesamiento de
transacciones:

 Modelo de estructura de transacciones . Es importante considerar si las transacciones son


planas o pueden estar anidadas.

 Consistencia de la base de datos interna . Los algoritmos de control de datos semántico


tienen que satisfacer siempre las restricciones de integridad cuando una transacción pretende
hacer un commit.

 Protocolos de confiabilidad. En transacciones distribuidas es necesario introducir medios


de comunicación entre los diferentes nodos de una red para garantizar la atomicidad y
durabilidad de las transacciones. Así también, se requieren protocolos para la recuperación
local y para efectuar los compromisos (commit) globales.

 Algoritmos de control de concurrencia. Los algoritmos de control de concurrencia deben


sincronizar la ejecución de transacciones concurrentes bajo el criterio de correctitud. La
consistencia entre transacciones se garantiza mediante el aislamiento de las mismas.

 Protocolos de control de réplicas . El control de réplicas se refiere a cómo garantizar la


consistencia mutua de datos replicados. Por ejemplo se puede seguir la estrategia read-one-
write-all (ROWA).

4.4. Niveles de aislamiento

Las transacciones especifican un nivel de aislamiento que define el grado en que se debe
aislar una transacción de las modificaciones de recursos o datos realizadas por otras
transacciones. Los niveles de aislamiento se describen en cuanto a los efectos secundarios
de la simultaneidad que se permiten, como las lecturas desfasadas o ficticias.

Control de los niveles de aislamiento de transacción:


 Controla si se realizan bloqueos cuando se leen los datos y qué tipos de bloqueos se solicitan.
 Duración de los bloqueos de lectura.
 Si una operación de lectura que hace referencia a filas modificadas por otra transacción:
o Se bloquea hasta que se libera el bloqueo exclusivo de la fila.
o Recupera la versión confirmada de la fila que existía en el momento en el que empezó la instrucción
o la transacción.
o Lee la modificación de los datos no confirmados.

El nivel de aislamiento para una sesión SQL establece el comportamiento de los bloqueos
para las instrucciones SQL.

El estándar ANSI/ISO SQL define cuatro niveles de aislamiento transaccional en función de


tres eventos que son permitidos o no dependiendo del nivel de aislamiento. Estos eventos
son:

Lectura sucia. Las sentencias SELECT son ejecutadas sin realizar bloqueos, pero podría
usarse una versión anterior de un registro. Por lo tanto, las lecturas no son consistentes al
usar este nivel de aislamiento.

 Lectura no repetible. Una transacción vuelve a leer datos que previamente había leído y
encuentra que han sido modificados o eliminados por una transacción cursada.
 Lectura fantasma. Una transacción vuelve a ejecutar una consulta, devolviendo un conjunto
de registros que satisfacen una condición de búsqueda y encuentra que otros registro que
satisfacen la condición han sido insertadas por otra transacción cursada.

Los niveles de aislamiento SQL son definidos basados en si ellos permiten a cada uno de los
eventos definidos anteriormente. Es interesante notar que el estándar SQL no impone un
esquema de cierre específico o confiere por mandato comportamientos particulares, pero
más bien describe estos niveles de aislamiento en términos de estos teniendo muchos
mecanismos de cierre/coincidencia, que dependen del evento de lectura.

Niveles de aislamiento: Comportamiento permitido

Nivel de aislamiento Lectura

No repetible Fantasma
Sucia
Lectura no comprometida Sí Sí Sí

Lectura comprometida No Sí Sí

Lectura repetible No No Sí

Secuenciable No No No

Según el estándar SQL 1992, SQL Server y MySQL permiten todos estos niveles, Oracle
sólo permite la lectura comprometida y secuenciable. Los niveles se pueden establecer en
ambos para cada transacción. Sin embargo esto no es necesariamente cierto.

El estándar SQL trataba de establecer los niveles de aislamiento que permitirían a varios
grados de consistencia para querys ejecutadas en cada nivel de aislamiento. Las lecturas
repetibles "REPEATABLE READ" es el nivel de aislamiento que garantiza que un query un
resultado consistente.

En la definición SQL estándar, la lectura comprometida "READ COMMITTED" no regresa


resultados consistentes, en la lectura no comprometida "READ UNCOMMITTED" las
sentencias SELECT son ejecutadas sin realizar bloqueos, pero podría usarse una versión
anterior de un registro. Por lo tanto, las lecturas no son consistentes al usar este nivel de
aislamiento.

A mayor grado de aislamiento, mayor precisión, pero a costa de menor concurrencia.

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL


{READ UNCOMMITTED | READ COMMITTED
| REPEATABLE READ | SERIALIZABLE}

4.5. COMMIT Y ROLLBACK

Ejemplo básico en MySQL precio del dólar con respecto al peso 1995 al 2012.
Utilice el script BD0505.sql

Considere la siguiente información

Fecha Precio
2012/02/01 13.0077

2012/02/02 12.8900

2012/02/03 12.8038

2012/02/07 12.7120

2012/02/08 12.6472

2012/02/09 12.6833

2012/02/10 12.7200

Lecturas consistentes

Por default, las tablas InnoDB ejecutan un lectura consistente (consistent read). Esto
significa que cuando una sentencia SELECT es ejecutada, MySQL regresa los valores
presentes en la base de datos hasta la transacción más reciente que ha sido completada. Si
alguna transacción está en progreso, los cambios hechos por alguna sentencia INSERT o
UPDATE no serán reflejados. Sin embargo, existe una excepción: las transacciones abiertas
si pueden ver sus propios cambios. Para demostrar esto, necesitamos establecer dos
conexiones al servidor MySQL.

Observe el caso feliz de las transacciones. Sin violaciones de integridad referencial u otra
clase de errores

Cliente 1 Cliente 2
SET AUTOCOMMIT = 0 SET AUTOCOMMIT = 0
INSERT INTO dolar INSERT INTO dolar
VALUES('2012-02-01', 13.0077); VALUES('2012-02-07', 12.7120);
INSERT INTO dolar INSERT INTO dolar
VALUES('2012-02-02', 12.8900); VALUES('2012-02-08', 12.6472);
INSERT INTO dolar INSERT INTO dolar
VALUES('2012-02-03', 12.8038); VALUES('2012-02-09', 12.6833);
SELECT * FROM dolar WHERE INSERT INTO dolar
VALUES('2012-02-10', 12.7200);
fecha >= '2012/02/01'; SELECT * FROM dolar WHERE
fecha >= '2012/02/01';

SELECT * FROM dolar WHERE fecha


COMMIT;
>= '2012/02/01';

Por defecto, MySQL se ejecuta con el modo autocommit activado. Esto significa que en
cuanto ejecute un comando que actualice (modifique) una tabla, MySQL almacena la
actualización en disco.

Si usa tablas transaccionales (como InnoDB o BDB), puede desactivar el modo autocommit
con el siguiente comando: SET AUTOCOMMIT = 0;

Tras deshabilitar el modo autocommit poniendo la variable AUTOCOMMIT a cero, debe usar
COMMIT para almacenar los cambios en disco o ROLLBACK si quiere ignorar los cambios
hechos desde el comienzo de la transacción.
START TRANSACTION

El siguiente código crea una tabla InnoDB de nombre resumen;

?
1 CREATE TABLE resumen (
2 year INTEGER,
3 mes INTEGER,
4 promedio DECIMAL(8,4),
5 PRIMARY KEY (year, mes)
6 )engine = innodb;

Cliente 1 Cliente 2
START
TRANSACTION;
SELECT @prom:=
AVG(precio) FROM
dolar
WHERE YEAR(fecha) =
2011 AND
MONTH(fecha) = 1;
INSERT INTO
resumen VALUES
(2011, 1, @prom);
SELECT * FROM
resumen;

SELECT @prom:= AVG(precio) FROM dolar


WHERE YEAR(fecha) = 2011 AND
MONTH(fecha) = 2;
INSERT INTO resumen VALUES (2011, 2,
@prom);
SELECT * FROM resumen;
SELECT * FROM
resumen;

COMMIT;

SELECT * FROM SELECT * FROM resumen;


resumen;
UNIDAD V. SQL
PROCEDURAL
5.1. Disparadores
Un disparador (o trigger) es un tipo especial de procedimiento almacenado asociado a una
tabla que se ejecuta al realizar una operación “básica” (INSERT, DELETE SELECT o
UPDATE) sobre ésta. La operación básica que despierta al trigger es conocida como
sentencia disparadora.

Los triggers constituyen una potente herramienta para mantener la integridad de la base de
datos, ya que pueden llevar a cabo cualquier acción que sea necesaria para el
mantenimiento de dicha integridad.

Los triggers pueden llamar a otros procedimientos y disparar otros triggers, pero no admiten
parámetros y no pueden ser invocados desde otros procedimientos.

Los disparadores se activan automáticamente al crearlos.

Eliminar un disparador: DROP TRIGGER nombre_disparador;

Activar/ Desactivar dispadores: Existen dos opciones.

 ALTER TRIGGER nombre_disparador {DISABLE | ENABLE};


 ALTER TABLE nombre_tabla {ENABLE | DISABLE} ALL TRIGGERS;

La ejecución del disparador puede ser antes (before) o después (after) de llevar a cabo la
sentencia disparadora. Es posible especificar condiciones adicionales para la ejecución del
disparador (restrictores).

Dado que una sentencia disparadora puede afectar una o más filas de una tabla, es
necesario especificar si se quiere que el disparador se ejecute para cada una de las filas
afectadas o para el bloque en general.

Para diseñar un disparador hay que cumplir dos requisitos:

 Especificar las condiciones en las que se va a ejecutar el disparador. Esto se descompone


en un evento que causa la comprobación del disparador y una condición que se debe
cumplir para ejecutar el disparador.
 Especificar las acciones que se van a realizar cuando se ejecute el disparador.

Temporalidad del Evento: AFTER / BEFORE

BEFORE: Ejecutan la acción asociada antes de que la sentencia sea ejecutada


 Decidir si la acción debe realizarse o no
 Utilizar valores alternativos para la sentencia

?
1 CREATE TRIGGER NombreTrigger
2 BEFORE Insert ON NombreTabla ….

AFTER: Ejecutan la acción asociada después de que se haya ejecutado la sentencia

?
1 CREATE TRIGGER NombreTrigger
2 AFTER Insert ON NombreTabla

La sintaxis de un disparador es

1
CREATE [OR REPLACE] TRIGGER nombre
2
{BEFORE | AFTER | INSTEAD OF} // Temporalidad del Evento
3
{INSERT | DELETE | UPDATE [OF <lista de columnas>]} ON <tabla>
4
[FOR EACH ROW] //Granularidad
5
[WHEN condición]
6
[DECLARE //Declaración de variables
7 . . .]
8 BEGIN
9 cuerpo del trigger
10 [EXCEPTION
11 . . .]
END
12

1 CREATE [OR REPLACE] TRIGGER nombre


2 {BEFORE | AFTER } // Temporalidad del Evento
3 {INSERT | DELETE | UPDATE} ON <tabla>
4 [FOR EACH ROW] //Granularidad
5 BEGIN
6 cuerpo del trigger
7 END
Registros old y new.

Estas variables se utilizan del mismo modo que cualquier otra variable, con la salvedad de
que no es necesario declararlas, son de tipo %ROWTYPE y contienen una copia del registro
antes (OLD) y después (NEW) de la acción SQL (INSERT, UPDATE, DELETE) que ha
ejecutado el trigger. Utilizando esta variable podemos acceder a los datos que se están
insertando, actualizando o borrando.

De uso exclusivo en los disparadores de nivel de fila, si se intenta hacer referencia a


cualquiera de los dos dentro de otro tipo de disparador, se obtendrá un error de compilación.

La siguiente tabla resume los valores regresados por estos seudoregistros en diferentes
eventos

Seudoregistros
Evento
:OLD :NEW

INSERT NULL Nuevos valores

DELETE Valores almacenados NULL

UPDATE Valores almacenados Nuevos valores

Ejemplo: Suponga que se tienen las siguientes relaciones, asociadas a la concesión de


préstamos en un banco:

Para implementar el diagrama entidad relación se tiene en Oracle el siguiente código

CREATE SEQUENCE secuencia;


CREATE TABLE deudor (

ife CHAR(13),

nombre CHAR(50) NOT NULL,

direccion CHAR(100) NOT NULL,

telefono CHAR(10) NOT NULL,

CONSTRAINT PKDeudor PRIMARY KEY (ife)

);

CREATE TABLE prestamo (

nPrestamo NUMBER(5),

ife CHAR(13),

fechaPrestamo DATE NOT NULL,

monto NUMBER(8) NOT NULL CHECK(monto > 0 AND monto <= 100000),

saldo NUMBER(10,2) NOT NULL,

interes NUMBER(5,2) NOT NULL,

CONSTRAINT PKPrestamo PRIMARY KEY (nPrestamo),

CONSTRAINT FKDeudorPrestamo FOREIGN KEY (ife) REFERENCES deudor(ife)

);

CREATE TABLE pagos (

nPago NUMBER,

nPrestamo NUMBER(5) NOT NULL,

F_Venc DATE NOT NULL,

saldo NUMBER(10,2) NOT NULL,

intereses NUMBER(5,2) NOT NULL,


abono NUMBER(8,2) CHECK (abono >= 0),

F_Pago DATE,

CONSTRAINT PKCUOTA PRIMARY KEY (nPago),

CONSTRAINT FKCUOTA_PRESTAMO FOREIGN KEY (NPRESTAMO) REFERENCES


PRESTAMO(NPRESTAMO)

);

CREATE OR REPLACE TRIGGER Tpagos

AFTER INSERT ON prestamo FOR EACH ROW

BEGIN

INSERT INTO pagos VALUES(secuencia.NextVal, :NEW.nPrestamo, SYSDATE +


30, :NEW.saldo, :NEW.saldo * :NEW.interes, 0, NULL);

END;

INSERT INTO deudor VALUES (1234567890123,'Jorge Pérez García', 'Algun lugar del
mundo','9340664');

INSERT INTO prestamo VALUES (secuencia.NextVal, 1234567890123, SYSDATE, 10000, 10000,


0.05 );

Ejecute el script Deudor.sql

Ejemplo: Torneo Clausura 2012 Futbol Mexicano de Primera División


Utilice el script Torneo2012.sql

5.2. Procedimientos Almacenados


Un procedimiento es un subprograma que ejecuta una acción específica y que no devuelve
ningún valor. Un procedimiento tiene un nombre, un conjunto de parámetros (opcional) y un
bloque de código.

La sintaxis Oracle de un procedimiento almacenado es la siguiente:

1 CREATE [OR REPLACE]


2 PROCEDURE <nombre_procedure> [(<param1> [IN | OUT | IN OUT] <type>,
3 <param2> [IN | OUT | IN OUT] <type>, ...)] IS
4 -- Declaración de variables locales
BEGIN
5
-- Sentencias
6 [EXCEPTION]
7 -- Sentencias control de excepción
8 END [<nombre_procedure>];

La sintaxis MySQL de un procedimiento almacenado es la siguiente:


1 CREATE
2 PROCEDURE <nombre_procedure> [(<param1> [IN|OUT|IN OUT] <type>,
3 <param2> [IN|OUT|IN OUT] <type>, ...)]
4 BEGIN
5 -- Sentencias
6 END ;

Ejemplo: Precio máximo del dólar historico

Utilice el script DolarO.sql

Utilice el script DolarSP.sql

Al especificar el tipo de dato del parámetro no debemos especificar la longitud del tipo.

Los parámetros pueden ser de entrada (IN), de salida (OUT) o de entrada salida (IN OUT). El
valor por defecto es IN, y se toma ese valor en caso de que no especifiquemos nada.

Considere el diagrama entidad relación siguiente:

A continuación se presenta un procedimiento almacenado que asigna una calificación a un


alumno en una materia X.
El procedimiento posee instrucciones para atrapar, capturar y gestionar esta excepción
"ORA-01403: no data found" que sucedería si los nombres de la materia o del alumno no se
encontraran en las tablas correspondientes.

BEGIN inscripcion('Compiladores e Interpretes ','LILIANA LIZBET',


'ENEJUN09',90); END;

El siguiente procedimiento almacenado registra la renta de una película, checando que el


número de películas rentadas no exceda el límite permitido.
begin rentaPelicula('Sergio Avila Pacheco', 39, 3); end;

También es posible usar cursores dentro de un procedimiento almacenado. Observe el


siguiente ejemplo que a diferencia de los ejercicios anteriores no genera error si la consulta
no regresa registros. Si usamos %ROWCOUNT es posible conocer cuántos registros regresa
la consulta 0 ... n.
BEGIN inscripcionCursores('Compiladores','LILIANA','ENEJUN09',90); END;

MySQL
Modificando procedimientos almacenados en MySQL
MySQL no proporciona la habilidad de modificar el contenido de un procedimiento
almacenados. Dado que el comando ALTER PROCEDURE, solo puede modificar algunas
caracteristicas del procedimiento. Si es necesario cambiar el código SQL, La mejor
alternativa es borra dicho procedimiento.
Eliminando procedimientos almacenados en MySQL
Use el comando DROP PROCEDURE.

Sintaxis

1 CREATE FUNCTION nombre (parámetro)


2 RETURNS tipo
3 [características] definición
Puede haber más de un parámetro (se separan con comas) o puede no haber ninguno (en
este caso deben seguir presentes los paréntesis, aunque no haya nada dentro). Los
parámetros tienen la siguiente estructura:nombre tipo

Donde:
 nombre: es el nombre del parámetro.
 tipo: es cualquier tipo de dato de los provistos por MySQL.

Dentro de características es posible incluir comentarios o definir si la función devolverá los


mismos resultados ante entradas iguales, entre otras cosas.

 definición: es el cuerpo del procedimiento y está compuesto por el procedimiento en sí:


aquí se define qué hace, cómo lo hace y cuándo lo hace.
Un procedimiento se invoca usando un comando CALL, y sólo puede pasar valores usando
variables de salida. Una función puede llamarse desde dentro de un comando como
cualquier otra función (esto es, invocando el nombre de la función), y puede retornar un valor
escalar. Las rutinas almacenadas pueden llamar otras rutinas almacenadas.

5.3. Cursores

Los cursores se utilizan para manejar las sentencias SELECT. Un cursor está formado por
un conjunto de registros devueltos por una instrucción SQL del tipo SELECT. Desde un
punto de visto interno a la base de datos, los cursores son segmentos de memoria utilizados
para realizar operaciones con los registros devueltos tras ejecutar una sentencia SELECT.
Reciben el nombre de cursores implícitos, cuando la sentencia SELECT regresa solo un
registro. Para procesar instrucciones SELECT que devuelvan más de una fila, son
necesarios cursores explícitos combinados con una estructura de bloque.

Un cursor admite el uso de parámetros. Los parámetros deben declararse junto con el cursor.

El siguiente diagrama representa como se procesa una instrucción SQL a través de un


cursor.
Fases de un cursor

Cursores implícitos

Se utilizan cuando la sentencia SELECT devuelve un solo registro. En cada cursor implicito
debe existir palabra reservada INTO.

Las variables que reciben los datos devueltos por el cursor tienen que contienen el mismo
tipo de dato que las columnas de la tabla.

MySQL no soporta esta clase de cursores pero podemos visualizarlos así.

Importante poner un delimitador nuevo, (suele ser ";") ya que si no se cambia toma el punto y
coma como delimitador, es decir que seria el final del procedimiento o función (Línea 2).

El comando DECLARE (línea 5) sirve para declarar variables locales y cursores. Solo
funcionan dentro de procedimientos inmediatamente del BEGIN.

1. DROP PROCEDURE IF EXISTS precioDolar;


2. DELIMITER $$;
3. CREATE PROCEDURE precioDolar(
4. OUT fechas DATE,
5. OUT precioActual DECIMAL(8,4)
6. )
7. BEGIN
8. DECLARE c CURSOR
9. FOR SELECT fecha, precio
10. FROM dolar
11. WHERE fecha = (SELECT MAX(fecha) FROM dolar);
12. SET precioActual = 0;
13. OPEN c;
14. FETCH c INTO fechas, precioActual;
15. CLOSE c;
16. END$$
17. DELIMITER ;
18. CALL precioDolar(@fecha,@precio);
19. SELECT @fecha, @precio;

Utilice el script DB_Dolar_Cursor.sql


Ejemplo: BD_Video_Patito. Obtener el director de una determinada pelicula.

DROP PROCEDURE IF EXISTS dirige;

DELIMITER $$
CREATE PROCEDURE dirige (IN _Pelicula CHAR(40),
OUT _Director CHAR(50))
BEGIN
DECLARE _Dirige CURSOR FOR
SELECT a.NombreActor
FROM actua ac, rol r, pelicula p, actor a
WHERE ac.idActor = a.idActor
AND ac.idPelicula = p.idPelicula
AND ac.idRol = r.idRol
AND r.NombreRol = 'Director'
AND p.NombrePelicula = _Pelicula;
OPEN _Dirige;
FETCH _Dirige INTO _Director;
CLOSE _Dirige;
END$$
DELIMITER ;
-- Llamada al procedimiento
CALL dirige('Contrabando', @Quien);
SELECT @Quien;

Ejecute el script BD_Video_Patito.sql

DECLARE
nombreDirector CHAR(50);
BEGIN
SELECT a.NombreActor INTO nombreDirector
FROM actua ac, rol r, pelicula p, actor a
WHERE ac.idActor = a.idActor
AND ac.idPelicula = p.idPelicula
AND ac.idRol = r.idRol
AND r.NombreRol = 'Director'
AND p.NombrePelicula = 'Contrabando';
dbms_output.put_line('El director de Contrabando es: ' ||
nombreDirector);
END;

Ejecute el script BD_Video_Patito2.sql

Cursores explícitos:

Se utilizan cuando la sentencia SELECT puede devolver varios registros. También se pueden
utilizar en consultas que devuelvan un solo registro por razones de eficiencia con respecto a
los cursores implícitos, eficiencia que mejorará especialmente si el cursor explícito se tiene
que ejecutar varias veces dentro del bloque de código.

Un cursor explícito tiene que ser definido previamente como cualquier otra variable
cursores explícitos admiten el uso de parámetros. Los parámetros deben declararse junto
con el cursor.

Ejemplo: BD_Reloj_checador
Iniciaremos creando las siguientes tablas

1. CREATE TABLE empleados (


2. idEmpleado INTEGER AUTO_INCREMENT,
3. nombre CHAR(40) NOT NULL,
4. PRIMARY KEY (idEmpleado, nombre)
5. ) ENGINE = InnoDB
6. DEFAULT CHARACTER SET = utf8 COLLATE = utf8_spanish_ci;
7.
8. CREATE TABLE checar (
9. idChecar INTEGER AUTO_INCREMENT,
10. fecha DATE NOT NULL,
11. hora TIME NOT NULL,
12. idEmpleado INT NOT NULL,
13. PRIMARY KEY (idchecar),
14. CONSTRAINT fk_idEmpleado FOREIGN KEY (idEmpleado )
15. REFERENCES empleados (idEmpleado )
16. ) ENGINE = InnoDB
17. DEFAULT CHARACTER SET = utf8 COLLATE = utf8_spanish_ci;

Ingresaremos los siguientes empleados

1. INSERT INTO empleados VALUES (1,'Jorge Pérez García');


2. INSERT INTO empleados VALUES (2,'Roberto Carlos Hernández Alamillo');
3. INSERT INTO empleados VALUES (3,'Francisco Argona Luis');

Declaramos ahora el cursor (línea 9 al 12) y el procedimiento correspondiente

1. DROP PROCEDURE IF EXISTS checando;


2. DELIMITER $$
3. CREATE PROCEDURE checando(IN fechas DATE,
4. IN horas TIME,
5. IN id INTEGER,
6. OUT mensaje CHAR(20))
7. BEGIN
8. DECLARE n INTEGER DEFAULT 0;
9. DECLARE nChecadas CURSOR FOR
10. SELECT COUNT(*) FROM checar WHERE (idEmpleado = id) AND (fecha =
fechas);
11. OPEN nChecadas;
12. FETCH nChecadas INTO n;
13. CLOSE nChecadas;
14. IF (n <= 1) THEN
15. IF (n = 0) THEN
16. INSERT INTO checar (fecha, hora, idEmpleado) VALUES (fechas, horas,
id);
17. SET mensaje = 'Entrada';
18. ELSE
19. INSERT INTO checar (fecha, hora, idEmpleado) VALUES (fechas, horas,
id);
20. SET mensaje = 'Salida';
21. END IF;
22. ELSE
23. SET mensaje = 'No jugar';
24. END IF;
25. END$$
26. DELIMITER ;
UNIDAD VI.
CONECTIVIDAD DE
BASE DE DATOS
6.1. ODBC

Open Data Base Conectivity


O lo que es lo mismo, conectividad abierta de bases de datos. Si escribimos una
aplicación para acceder a las tablas de una DB de Access, ¿qué ocurrirá si después
queremos que la misma aplicación, y sin reescribir nada, utilice tablas de SQL Server u otra
DB cualquiera? La respuesta es sencilla: no funcionará. Nuestra aplicación, diseñada para un
motor concreto, no sabrá dialogar con el otro. Evidentemente, si todas las DB funcionaran
igual, no tendríamos este problema.... aunque eso no es probable que ocurra nunca.
Pero si hubiera un elemento que por un lado sea siempre igual, y por el otro sea capaz de
dialogar con una DB concreta, solo tendríamos que ir cambiando este elemento, y nuestra
aplicación siempre funcionaría sin importar lo que hay al otro lado... algo así como ir
cambiando las boquillas de una manguera. A esas piezas intercambiables las
llamaremos orígenes de datos de ODBC
Casi todas las DB actuales tienen un ODBC. Debido a que este elemento impone ciertas
limitaciones, ya que no todo lo que la DB sabe hacer es compatible con la aplicación, como
velocidad de proceso, tiempos de espera, máxima longitud de registro, número máximo de
registros, versión de SQL, etc., está cayendo en desuso a cambio de otras técnicas de
programación, pero aún le quedan muchos años de buen servicio.
Todo lo referido aquí funciona con Windows NT Server 4.0 con el Service Pack 4 o superior
instalado (el último publicado es el 6). El Option Pack 4 para actualizar el IIS y las
extensiones ASP. SQL Server 6.5 y Access 97. Por supuesto, también funciona con las
versiones modernas de servidores como 2003 Server, y también XP PRO, que lleva un IIS
5.0 de serie. Igualmente es posible utilizar bases de datos de Access 2000 o 2003.
Esas otras técnicas de programación antes mencionadas, se utilizan ya en el nuevo Windows
2003, Office 2003 y SQL Server 2000, que además de ODBC pueden utilizar.... pero esa es
otra historia.
Esta es la idea: por un lado el ODBC provee de unas características siempre homogéneas, y
por el otro permite distintos controladores que aseguran la conectividad de la aplicación con
diferentes bases de datos.
6.2. ADO.NET

ADO .NET responde a las siglas de Microsoft ActiveX Data Objects de la plataforma .NET, y
es una mejora evolutiva de la tecnología ADO. Realmente es una evolución más en las
tecnologías de acceso a la información.
En este capítulo se comparan las tecnologías ADO y ADO.NET, se describen y detallan los
objetos más importantes de la tecnología, el objeto DataSet y los proveedores de acceso a
datos. Se profundizará sobre el objeto DataSet describiendo los objetos DataTable,
DataColumn, etc. En cuanto a los proveedores de acceso a datos se describirá el proveedor
para SQL Server y el proveedor para OLE DB.
Requisitos de la plataforma ADO.NET
Para utilizar los proveedores de datos de SQL Server .NET y OLE DB .NET se necesita la
instalación de la versión 2.6 o superior de Microsoft Data Access Components. Para utilizar
ADO.NET en las aplicaciones se ha de incluir el namespace System.Data.

Los objetos más importantes de la tecnología ADO son el objeto RecordSet, el objeto
Command y el objeto Connection.

También podría gustarte