Relacionar tablas
Las Consultas
Las Vistas
Si no sabes lo que es una base de datos relacional o no tienes conocimientos previos acerca de las bases de datos, puedes
leer una introduccin a las bases de datos en el siguiente bsico
Por ejemplo podemos aadir un nuevo dato en la tabla de clientes como la direccin de email sin que los esquemas
externos se vean afectados.
Seguridad e integridad.
La seguridad consiste en que los usuarios no puedan acceder a datos sin autorizacin.
Si juntamos toda la informacin de la empresa en un mismo sitio, el SGBD debe tener mecanismos para que cualquier
usuario pueda tener acceso a nicamente la informacin que necesita para las tareas que tiene encomendadas.
Esta seguridad se consigue por medio de los esquemas externos, ya que el usuario slo tiene acceso a su esquema externo
que le proporciona los datos que el administrador ha considerado incluir en ese esquema. Para el usuario no habr ms
datos que estos.
Adems los SGBD tienen mecanismos para definir autorizaciones que pueden ser de distinto tipo: autorizacin de lectura, de
insercin, de actualizacin, autorizaciones especiales para poder variar el esquema conceptual etc.
La integridad se refiere a que la informacin almacenada en la base de datos est libre de errores. Esto no siempre es
posible ya que existen distintos tipos de errores que tienen diferentes soluciones:
* Fallos de hardware. Estos errores no los puede evitar el SGBD pero se pueden subsanar facilitando copias de seguridad y
procesos de recuperacin.
* Fallos del programador. Puede que aparezcan datos errneos en la base de datos como consecuencia de errores en el
programa que genera estos datos. Para evitar al mximo este tipo de errores el sistema debe ser fcil de programar, cuantos
ms controles realice el sistema de forma automtica, menos controles habr que incluir a nivel de programacin por lo que
limitaremos la probabilidad de fallo y los programas deben ser probados con juegos de ensayos bien definidos.
* Fallos del usuario final. El usuario que introduce datos en la base de datos tambin puede cometer errores, el sistema debe
permitir controlar al mximo la informacin que se introduce para limitar el nmero de estos errores, para ello los SGBD
incluyen clusulas de validacin de los datos, validaciones de diferentes tipos que veremos con ms detalle ms adelante.
* Fallos derivados de la concurrencia. Ya que toda la informacin est centralizada y los distintos usuarios acceden a ella de
forma simultnea, pueden ocurrir problemas cuando dos usuarios quieren acceder al mismo dato a la vez. Por ello el SGBD
debe tener establecidos mecanismos para evitar este tipo de problema, bloquear registros, abortar automticamente
transacciones etc.
Redundancia mnima
La redundancia consiste en que exista algn dato repetido en varios lugares.
Por ejemplo si tenemos la direccin del cliente en la factura, en la cuenta contable, en los datos generales del cliente; esto
como ya vimos anteriormente nos producir varios problemas:
la variacin de un domicilio supone el variar ese domicilio en todos los lugares donde est almacenado.
o
posibilidad de inconsistencia
Por todo ello hay que evitar al mximo esa redundancia, esto se consigue utilizando herramientas de diseo y obteniendo un
diseo ptimo de la base de datos.
Colaborar con el administrador del sistema en las tareas de ubicacin, dimensionado y control de los archivos y
espacios de disco ocupados por el SGBD.
Establecer estndares de uso, polticas de acceso y protocolos de trabajo diario para los usuarios de las bases de
datos.
Controlar los tiempos de acceso, tasas de uso, cargas en los servidores, anomalas, etc.
Estudiar las auditoras mediante el ajuste de parmetros y con ayuda de las herramientas de monitorizacin
del sistema y de las estadsticas.
El diccionario de datos
Dentro del SGBD, hay una parte que son datos sobre los datos, es una base de datos en la que se almacena toda la
informacin necesaria para que el sistema funcione. Esta base de datos es el diccionario de datos y contiene:
Las definiciones de todos los objetos de la base de datos: tablas, vistas, ndices, disparadores (triggers) funciones,
procedimientos almacenados, etc.
Informacin que permita obtener estadsticas y evaluaciones del rendimiento del sistema.
Segn su ubicacin
Ventajas
Economa
Es la ms barata.
Simplicidad
No se necesita llevar controles de accesos concurrentes, de
transmisin de datos, etc.
Desventajas
Monousuario
En un instante determinado slo la puede utilizar una
persona.
Capacidad
Suele tener una capacidad de almacenamiento limitado.
En modo Cliente/Servidor, la base de datos se encuentra en un ordenador (el Servidor) y los usuarios acceden
simultneamente a esa base de datos a travs de la red (sea una red local o Internet) desde sus ordenadores a travs de un
programa Cliente.
A nivel de empresas es el sistema que ms se utiliza en la actualidad.
Ventajas
Desventajas
Multiusuario
Complejidad
informacin.
subesquemas.
No redundancia
Seguridad
Al estar todos los datos en el mismo servidor, la informacin Se tienen que realizar controles para garantizar la seguridad
no se duplica y es ms facil evitar fallos debidos a
redundancias.
comunicaciones.
Ventajas
Desventajas
Rendimiento
tambin se permita a usuarios no locales acceder a los datos distribuida debe considerar la fragmentacin, replicacin y
segn sus necesidades. Esto hace que la informacin se
Disponibilidad
Complejidad tcnica
En caso de que falle la base de datos de alguna localidad, el Se debe asegurar que la base de datos sea transparente, se
sistema no se colapsa, puede seguir funcionando excluyendo debe lidiar con varios sistemas diferentes que pueden
los datos de la localidad que haya fallado.
Autonoma local
Economa en el mantenimiento
pertenecen.
Economa en la implantacin
Seguridad
Es ms barato crear una red de muchas mquinas pequeas, Se debe trabajar en la seguridad de la infraestructura as
que tener una sola mquina muy poderosa.
Modularidad
Se pueden modificar, agregar o quitar sistemas de la base de
datos distribuida sin afectar a los dems sistemas (mdulos).
Los sistemas jerrquico y en red constituyen la primera generacin de los SGBD. Pero estos sistemas presentan algunos
inconvenientes:
Es necesario escribir complejos programas de aplicacin para responder a cualquier tipo de consulta de datos, por
simple que sta sea.
Los datos se organizan en relaciones compuestas por tuplas de atributos. Si convertimos esta definicin a tablas
tenemos que los datos se organizan en tablas compuestas por filas (registros) y columnas (campos).
Una tabla tiene 0 o ms filas, y cada fila contiene la informacin de un determinado sujeto de la relacin.
La lista de los atributos dispuestos en un orden especfico de izquierda a derecha y que forman la definicin de una
tabla se denomina esquema de la tabla, mientras que los valores concretos de los datos que estn almacenados en
la tabla se llaman ocurrencias.
El esquema de la tabla Piezas est compuesto por las columnas (Codigo, Denominacin, Precio, Fabricante,
Codigo_segn_fab).
Codigo es el cdigo de la pieza, Denominacion el nombre de la pieza, Fabricante el cdigo del fabricante que nos suministra
la pieza y Cdigo_segn_fab el cdigo que utiliza ese fabricante para identificar la pieza en su sistema de gestin.
Una ocurrencia de fila de la tabla Piezas sera:1, Taburete 3 patas, 25, Fab1, T123-34.
Todos los valores de una columna determinada tienen el mismo tipo de datos, y stos estn extrados de un
conjunto de valores legales llamado dominio de la columna. Muchas veces el dominio se corresponder con un tipo
de datos estndar del sistema.
Por ejemplo en la tabla Piezas la columna Codigo est definida sobre el dominio de los enteros.
A parte de los valores del dominio, la columna puede contener un valor especial, el valor nulo. El valor nulo (NULL)
es importante porque representa la ausencia de valor en el campo y no es lo mismo que el valor cero 0 o la cadena
vaca o espacios en blanco. De hecho es un valor tan especial que no funciona como los dems valores, por ejemplo
no podemos comparar (con el operador de comparacin =) un campo con el valor nulo, tenemos que utilizar un
operador especial (IS NULL). Incluso se han tenido que redefinir los operadores lgicos para tener en cuenta el valor
nulo.
Ej. En la tabla Fabricantes el campo direccin de la primera fila contiene el valor nulo (null) esto significa que este
fabricante no tiene direccin (al menos conocida).
En una tabla cada columna tiene un nico nombre y ste no se puede utilizar para nombrar otra columna de la
misma tabla pero s de otra tabla.
Por ejemplo en la tabla Piezas no se pueden definir dos columnas llamadas Codigo, por eso el segundo cdigo lo
hemos llamado Codigo_segun_fab. Pero en la tabla Fabricantes la columna IdFab se poda haber llamado Codigo
sin problema.
En una tabla no se admiten dos filas con los valores coincidentes en todos sus campos. Esta restriccin no se suele
cumplir.
Esta regla nos dice que por ejemplo en la tabla Fabricantes no pueden haber dos filas con los valores Fab1,
Muebles la Madera, null.
Realmente sera informacin redundante, por eso la existencia de esta regla, no obstante en algunos casos muy
concretos s es necesario poder almacenar dos ocurrencias de fila idnticas, por esta razn muchos SGBD no
cumplen esta regla.
En una tabla pueden existir ms de una columna que permita identificar las filas de la tabla, si queremos utilizar tales
columnas como identificadores las definiremos como claves secundarias (alternativas). Una clave secundaria tiene
las mismas restricciones que una clave primaria, pero como no podemos definir dos claves primarias, definimos la
que se vaya a utilizar ms frecuentemente como clave primaria y la otra (u otras) como secundarias.
Por ejemplo en la tabla Piezas la clave primaria es el campo Codigo ya que no hay ni puede haber dos piezas con el
mismo cdigo. Este campo realmente sirve para identificar las filas de la tabla, sabiendo un valor de cdigo (por
ejemplo el 2) sabremos que nos referimos a la fila de la mesa ovalada.
En esta misma tabla tenemos una posible clave alternativa, la formada por los campos Fabricante y
Codigo_segun_fab ya que en la tabla Piezas es imposible tener dos filas con la misma combinacin de valores en
estos campos (el cdigo_segun_fab es el cdigo que utiliza el fabricante para identificar sus piezas).
Otro concepto muy importante, fundamental en las bases de datos relacionales, es la clave ajena (externa o
fornea).
Una clave ajena es un campo (o combinacin de campos) que contiene la referencia a una fila de otra tabla, tambin
puede referirse a la misma tabla. En otras palabras, es un campo que seala a un registro de otra tabla, contiene un
valor que identifica un registro de la otra tabla. Son los campos que se utilizan para relacionar las tablas entre s.
Una tabla puede tener 0, una o varias claves ajenas (externas, forneas).
El SGBD deber velar por la integridad de los datos, para ello incluye varias reglas de integridad que se
comprobarn de forma automtica sin necesidad de la intervencin externa de los usuarios o de los programas de
aplicacin.
Existen distintos tipos de reglas de integridad:
10
La integridad de entidades (integridad de claves): Toda tabla debe tener una clave primaria que permite
identificar unvocamente los registros que contiene, por lo tanto no puede contener el valor nulo ni valores
duplicados.
En el ejemplo anterior si intentamos insertar una nueva pieza con el cdigo 2, el sistema no nos dejar
porque ya hay una pieza con este mismo cdigo en la tabla.
La integridad referencial: En una clave ajena no puede haber un valor no nulo que no exista en la tabla de
referencia. Para que no existan errores de integridad referencial en la base de datos, el sistema comprueba
automticamente que los valores introducidos en las claves ajenas existan en el campo de referencia en la
otra tabla, si no existe, no nos dejar insertar el registro.
Volviendo al ejemplo anterior, si intentamos insertar una pieza con un cdigo de fabricante que no existe en
la tabla de fabricantes, el sistema no nos dejar.
A nivel de control sobre los datos, el SGBD debe de proporcionar herramientas para poder definir restricciones de
dominio que se comprobarn de forma automtica (se comprueba que el valor introducido en una columna
pertenece al dominio de la columna, al tipo de datos), y reglas de negocio, que son reglas especficas sobre los
datos, en este tipo de reglas entran las reglas de validacin y reglas definidas a nivel superior que veremos ms
adelante.
Una regla de validacin sera por ejemplo que el precio no pueda ser inferior a 10 euros, y una regla de negocio, que
no pueda haber ms de 20 fabricantes.
Un SGBD relacional sigue la arquitectura de tres niveles en la que tenemos en el nivel externo las vistas, en nivel
conceptual el esquema conceptual con la definicin de todas las tablas, columnas que las componen y relaciones
entre ellas, en el nivel interno tenemos la definicin fsica de la base de datos.
Finalmente tenemos para poder manejar la informacin almacenada en la base de datos un lenguaje que cumple las
reglas de Codd, el lenguaje SQL que veremos en prximos temas.
11
Habilitar el SQL Server Management Studio en la instalacin (si no lo est por defecto) cuando nos pregunte qu
componentes deseamos instalar.
directo
o a travs de Inicio, Programas, Microsoft SQL Server 2005, SQL Server Management Studio.
Seleccionamos el nombre del servidor y pulsamos el botn Conectar. Se abrir la ventana inicial del SQL Server
Management Studio (en adelante SSMS):
12
En la parte izquierda tenemos abierto el panel Explorador de Objetos en el que aparece debajo del nombre del servidor con
el
que
estamos
conectados
una
serie
de
carpetas
objetos
que
forman
parte
del
servidor.
En el panel de la derecha se muestra la zona de trabajo, que vara segn lo que tengamos seleccionado en el Explorador de
objetos, en este caso vemos el contenido de la carpeta que representa el servidor ord01.
En la parte superior tenemos el men de opciones y la barra de herramientas Estndar.
13
Archivos de registro
Los archivos de registro (archivos de log) almacenan toda la informacin de registro que se utiliza para recuperar la
base de datos, el tambin denominado registro de transacciones. Como mnimo, tiene que haber un archivo de
registro por cada base de datos, aunque puede haber varios. La extensin recomendada para los nombres de
archivos de registro es .ldf.
SQL Server 2005 no exige las extensiones de nombre de archivo .mdf, .ndf y .ldf, pero estas extensiones ayudan a
identificar las distintas clases de archivos y su uso.
Cada base de datos tiene al menos 2 archivos (un archivo de datos principal y un archivo de registro) y opcionalmente un
grupo de archivos.
Los archivos de datos y de registro de SQL Server se pueden colocar en sistemas de archivos FAT o NTFS. Se recomienda
utilizar NTFS por los aspectos de seguridad que ofrece. No se pueden colocar grupos de archivos de datos de lectura y
escritura, y archivos de registro, en un sistema de archivos NTFS comprimido. Slo las bases de datos de slo lectura y los
grupos de archivos secundarios de slo lectura se pueden colocar en un sistema de archivos NTFS comprimido.
Despus de la instalacin, en la carpeta Bases de datos del sistema se habr creado una especial denominada master se
utiliza como base de datos de usuario por defecto.
Las dems bases de datos forman tambin parte del diccionario de datos y las utiliza el sistema para llevar a cabo su
gestin.
14
Las bases de datos de los usuarios se deben crear preferentemente fuera de la carpeta Bases de datos del sistema.
Para crear una nueva base de datos de usuario nos posicionamos sobre la carpeta Bases de datos y con el botn derecho
del ratn desplegamos el men contextual del que elegimos la opcin Nueva base de datos
Se abre a continuacin el cuadro de dilogo donde definiremos la base de datos que queremos crear:
15
Lo mnimo a introducir ser el campo Nombre de la base de datos, ste es el nombre de la base de datos lgica, la base de
datos a la que nos referiremos dentro del SSMS, a nivel conceptual (en la imagen Mibase).
Esta base de datos est asociada a dos archivos fsicos, en la parte inferior aparecen esos archivos. Para facilitarnos la
tarea, al teclear el nombre de la bd lgica, se rellenan automticamente los nombres de los archivos fsicos, el de datos con
el mismo nombre y el del archivo de registro con el mismo nombre seguido de _log. Estos nombres son los nombres que se
asumen por defecto pero los podemos cambiar, posicionando el cursor en el nombre y cambindolo.
Para cada archivo fsico podemos definir una serie de parmetros como el tipo de archivo (si es de datos o de transacciones
Registro) y su ocupacin inicial (Tamao inicial).
Si no indicamos ninguna ubicacin podemos ver que los guarda en la carpeta del SQL Server/MSSQL.n/MSSQL/DATA.
n representa un nmero que puede variar de una instalacin a otra.
Estos son los archivos mnimos en los que se almacenar la base de datos, pero como ya vimos anteriormente se puede
almacenar en ms archivos, los tenemos que definir todos en esta ventana a continuacin de los dos obligatorios.
Para aadir ms archivos fsicos disponemos del botn Agregar.
Al pulsar el botn Agregar se crea una nueva fila en la tabla de archivos fsicos donde deberemos escribir el nombre del
archivo, su tipo (desplegando la lista podemos elegir entre de datos o de registro) y dems parmetros.
16
Al agregar un nuevo archivo se activa el botn Quitar, siempre que estemos posicionados encima de un archivo secundario
para poder as eliminarlo si lo queremos.
No podemos eliminar ni el de datos primario, ni el de registro inicial.
Si nos fijamos en la zona de la izquierda, vemos que nos encontramos en la pestaa General, podemos cambiar otros
parmetros de la base de datos pulsando en Grupos de archivos o en Opciones:
17
Desde el Explorador de Windows podemos ver que en la carpeta indicada se han creado los archivos fsicos con los
nombres que le hemos indicado.
18
19
Pulsando en Agregar indicamos el archivo de datos primario en su ubicacin y automticamente se adjuntar la base de
datos lgica asociada a este archivo.
La opcin Adjuntar slo se utiliza la primera vez, cuando todava no tenemos la base de datos en el disco.
20
3. Haz clic con el botn secundario del ratn sobre la carpeta Bases de datos que se encuentra en el Explorador de objetos
del SSMS.
4. En el men contextual, elige Adjuntar...
5. Pulsa el botn Agregar y busca el directorio Bases de datos que contiene las dos bases que has descargado.
6. Selecciona la primera base (Gestion.mdf) y pulsa Aceptar.
7. Pulsa el botn Agregar de nuevo y esta vez selecciona GestionA.mdf. Cambia su nombre lgico (el campo Adjuntar como)
a Gestion. As es como nos referiremos a ella.
8. Si todo va bien, te indicar que se han adjuntado correctamente y las vers en el Explorador de objetos (GestionA y
GestionSimples). Si no las ves, pulsa el botn Actualizar
21
El caso ms inmediato en el que puedes necesitar conectar y desconectar la base de datos es copiar a un pendrive los
archivos de las bases que utilizars en los ejercicios para poder trabajar en diferentes ordenadores con ellos. Para aprender
cmo hacerlo, visita el siguiente Ejercicio Trasladar una base de datos a otro equipo.
Unidad 1. Ejercicio paso a paso: Trasladar una base de datos a otro equipo
Objetivo
Copiar una base de datos que est en uso en un servidor, y adjuntarla o actualizarla en otro.
2. Una vez sabemos la ruta, utilizamos el Explorador de Windows para abrir a la carpeta donde se encuentran los archivos.
3. Volvemos al SSMS y desconectamos la base de datos, como ya hemos visto: Desde el men contextual y eligiendo
Tareas > Poner fuera de conexin.
22
4. Ahora que ya est desconectada, copiamos los archivos desde el Explorador de Windows, por ejemplo, a nuestro
pendrive.
Ya tenemos una copia de la base de datos de clase. Ahora vamos a ver cmo incluirla en el otro ordenador, es decir, en
casa.
- En caso de que la base de datos no exista, debers adjuntarla como ya hemos visto: Desde el men contextual de bases
de datos y eligiendo la Adjuntar...
- En caso de que la base de datos ya exista y lo que quieras sea actualizarla, debers:
1. Desconectar la base existente desde SSMS.
2. Sobreescribir los archivos fsicos por los nuevos que llevas en el pendrive, desde el Explorador de Windows.
3. Volver a conectar la base de datos desde SSMS.
En caso de que tu versin de SQL Server no tenga las opciones Poner en conexin y Poner fuera de conexin, debers
utilizar la opcin Separar... y luego volver a adjuntarla.
Para crear una nueva tabla primero nos tenemos que posicionar en la base de datos donde queremos que se almacene la
tabla, desplegar el men contextual y seleccionar la opcin Nueva tabla.
A cada columna se le asigna un nombre, un tipo de datos, y opcionalmente una serie de propiedades, en este tema veremos
las bsicas y las dems las veremos con ms detalle cuando veamos la instruccin SQL CREATE TABLE.
De momento no tenemos definida ninguna columna, al teclear un nombre se crea una primera entrada en esta tabla con la
definicin de la primera columna. En la columna Tipo de datos elegimos qu tipo de valores se podrn almacenar en la
columna.
23
A cada columna se le asigna un nombre, un tipo de datos, y opcionalmente una serie de propiedades, en este tema veremos
las bsicas y las dems las veremos con ms detalle cuando veamos la instruccin SQL CREATE TABLE.
De momento no tenemos definida ninguna columna, al teclear un nombre se crea una primera entrada en esta tabla con la
definicin de la primera columna. En la columna Tipo de datos elegimos qu tipo de valores se podrn almacenar en la
columna.
24
En este ejemplo hemos definido una columna (Codigo) de tipo Entero corto (Smallint), y una columna (Nombre) que
almacenar hasta 20 caracteres alfanumricos (nchar(20)), en este caso la longitud la indicamos en la pestaa Propiedades
de columna en la propiedad Longitud.
Las propiedades de la columna pueden variar dependiendo del tipo de datos de la columna seleccionada, por ejemplo los
campos enteros no tienen la propiedad longitud, ya que el propio tipo define la longitud del campo, en cambio los campos de
tipo numeric o decimal no tiene la propiedad longitud pero s las propiedades escala y precisin, los valores que permiten
definir el tamao del campo.
25
En la mayora de los sistemas gestores de bases de datos tenemos un tipo de datos de tipo contador, autonumrico,
autoincremental, etc. Este tipo hace que el propio sistema es el encargado de rellenar el campo con un valor que va
incrementando conforme se crean ms filas de datos en la tabla.
Las columnas de este tipo se utilizan normalmente para numerar las filas de la tabla, como no habrn dos filas con el mismo
valor (el sistema se encarga de incrementar el valor cada vez que se crea una nueva fila), estos campos se suelen utilizar
como claves primarias.
En SQL Server 2005 no existe el tipo de datos Contador pero se consigue el mismo funcionamiento asignando a la columna
un tipo de datos numrico y definiendo la columna como columna de identidad.
En las propiedades de la columna marcamos S en la propiedad (Identidad) y a continuacin podemos indicar en qu valor
queremos que empiece el contador (Inicializacin de identidad) y en cunto incrementar cada vez que se cree un nuevo
registro (Incremento de identidad).
Aunque este tipo de columnas se utiliza frecuentemente como clave primaria, SQL Server no le asigna automticamente
esta funcin, la tenemos que definir nosotros mismos, pero s fuerza a que sea una columna sin valores nulos. No se puede
definir ms de una columna de identidad por tabla.
26
Aparecer una llave a la izquierda del nombre, smbolo de las claves principales:
Para definir una clave primaria compuesta por varias columnas, seleccionamos las columnas manteniendo pulsada la tecla
Ctrl y luego seleccionamos la opcin.
Para quitar una clave principal, hacemos lo mismo pero en esta ocasin seleccionamos la opcin Quitar clave principal.
Del mismo modo si queremos eliminar la definicin de una columna, nos posicionamos en la columna a eliminar y
seleccionamos la opcin Eliminar columna:
27
O simplemente hacemos clic en la zona a la izquierda del nombre y pulsamos la tecla Supr.
Finalmente guardamos la tabla, nos pedir el nombre de la tabla:
28
La primera columna sirve para indicarnos el estado de una fila, por ejemplo el * nos
indica que es una nueva fila, esta fila realmente no est en la tabla, nos sirve de contenedor para los nuevos datos que
queremos insertar.
Para insertar una nueva fila de datos slo tenemos que rellenar los campos que aparecen en esa fila (la del *), al cambiar de
fila los datos se guardarn automticamente en la tabla a no ser que alguno infrinja alguna regla de integridad, en ese caso
SQL Server nos devuelve un mensaje de error para que corrijamos el dato errneo, si no lo podemos corregir entonces slo
podemos deshacer los cambios.
29
Al pulsar el botn que se encuentra en la fila Especificacin de tablas y columnas se abre el dilogo donde definiremos la
relacin:
30
En la parte derecha tenemos la tabla en la que estamos y el campo que va a actuar como clave ajena, slo nos queda elegir
en el desplegable de la izquierda la tabla a la que hace referencia la clave y al seleccionar una tabla, a la izquierda del
campo clave ajena podremos elegir el campo de la otra tabla por el que se relacionarn las tablas. En nuestro caso ser:
De esta forma hemos definido una relacin entre las tablas Facturas y Clientes. Para ver las relaciones existentes entre las
diferentes tablas tenemos los diagramas.
Primero debemos definir el diagrama, para ello seleccionamos la opcin correspondiente:
31
A continuacin nos aparece el nuevo diagrama ahora si elegimos crear un nuevo diagrama nos preguntar las tablas a
incluir en el diagrama:
Seleccionamos cada una y pulsamos Agregar, cuando hayamos agregado al diagrama todas las que queremos pulsamos en
Cerrar y aparecern en el diagrama las tablas con las relaciones que tengan definidas en ese momento:
La llave indica la tabla principal (padre) y el smbolo infinito seala la tabla que contiene la clave ajena.
En el examinador de objetos en la carpeta Diagramas de base de datos aparecen todos los diagramas definidos hasta el
momento:
Hemos aprendido hasta ahora lo bsico para poder crear una base de datos y rellenarla con tablas relacionadas entre s y
con datos, ahora veamos cmo recuperar esos datos.
32
con el cual todava no hemos establecido conexin, seleccionando de la barra de mens la opcin Nuevo > Consulta de
motor de base de datos:
.
En este ltimo caso nos aparecer el cuadro de dilogo para establecer la conexin (el mismo que vimos al principio del
tema).
A continuacin se abrir una nueva pestaa donde podremos teclear las sentencias SQL:
Adems aparece una nueva barra de botones que nos permitir ejecutar los comandos ms tiles del modo query.
33
Si ahora desplegamos la carpeta Bases de Datos del Explorador de Objetos, observaremos la base de datos que hemos
creado:
Si la ejecucin de la sentencia produce un error, el sistema nos devolver el mensaje de error escrito en rojo en la pestaa
Mensajes.
Podemos incluir en una misma consulta varias sentencias SQL, cuando pulsamos Ejecutar se ejecutarn todas una detrs
de otra. Si tenemos varias consultas y slo queremos ejecutar una, la seleccionaremos antes de ejecutarla.
34
35
En la pestaa Propiedades de conexin, en el cuadro Conectar con base de datos: Seleccionamos <Examinar servidor >
para elegir la base de datos.
La elegimos y aceptamos. A partir de ese momento la base de datos elegida ser la que SQL Server coja por defecto en
todas las sesiones de ese usuario.
1.22. El editor de texto
Para facilitarnos la redaccin y correccin de las sentencias, el editor de SQL presenta las palabras de distintos colores
segn su categora y podemos utilizar el panel Explorador de Objetos para arrastrar desde l los objetos sobre la zona de
36
trabajo y as asegurarnos de que los nombres de los objetos (por ejemplo nombre de tabla, de columna, etc.) sean los
correctos.
Como hemos dicho el texto que se escribe en este editor de cdigo se colorea por categora. Los colores son los mismos
que se utilizan en todo el entorno SQL Server. En esta tabla aparecen los colores ms comunes.
Color
Categora
Rojo
Cadena de caracteres
Verde oscuro
Comentario
Verde
Azul
Palabra clave
Verde azulado
Rojo oscuro
Gris oscuro
Operadores
37
38
Para definir una vista en el Explorador de Objetos desplegamos la base de datos donde la guardaremos y elegimos la
opcin Nueva vista del men contextual de la carpeta Vistas, se pondr en funcionamiento el generador de consultas
pidindonos las tablas en las que se basar la vista. Pulsamos sobre la tabla a aadir al diseo de la vista y pulsamos el
botn Agregar, podemos aadir as cuntas tablas queramos.
Despus de Cerrar, vemos a la derecha del Explorador de Objetos la pestaa con la definicin de la vista que puede incluir
varios paneles:
39
La aparicin de estos paneles es configurable, en la barra de herramientas Diseador de vistas los iconos remarcados en
azul
son
los
correspondientes
cada
panel:
40
Desde el panel diagrama podemos aadir cmodamente campos de las tablas a la consulta marcando la casilla
correspondiente. En la imagen anterior la nica casilla seleccionada es la del * en la tabla Libros por lo que se visualizarn
todas las columnas de la tabla Libros y ninguna de la tabla Prstamos.
Conforme vamos marcando casillas de las tablas del panel diagrama, los cambios se ven reflejados en los dems paneles
excepto en el panel de resultados que se actualiza ejecutando la consulta.
En cada fila de la rejilla se define una columna del resultado o una columna que se utiliza para obtener el resultado.
En Columna tenemos el nombre de la columna de la se obtienen los datos o la expresin cuando se trata de una
columna calculada.
En Alias escribimos el nombre que tendr la columna en la vista, tambin corresponde con el encabezado de la
columna en la rejilla de resultado. Si se deja el campo en blanco, por defecto se asume el mismo nombre que hay en
Columna.
En Tabla tenemos el nombre de la tabla del origen de la consulta a la que pertenece la Columna, por ejemplo la
primera columna del resultado se saca de la columna Codigo de la tabla LIBROS y se llamar CodLibro. La cuarta
columna de la vista coger sus datos de la columna Usuario de la tabla Prestamos y se llamar Usuario (Alias se ha
dejado en blanco por lo que asume el nombre que hay en Columna.
41
En la columna Resultados indicamos si queremos que la columna se visualice o no, las columnas con la casilla
marcada se visualizan.
Las columnas Criterio de ordenacin y Tipo de orden permiten ordenar las filas del resultado segn una o ms
columnas. Se ordena por las columnas que tienen algo en Tipo de orden y cuando se ordena por varias columnas
Criterio de ordenacin indica que primero se ordena por la columna que lleva el n 1 y despus por la columna que
lleva el n 2 y as sucesivamente. En el ejemplo las filas del resultado se ordenarn primero por cdigo de libro y
despus por cdigo de prstamo, todas las filas dentro del mismo libro se ordenarn por cdigo de prstamo.
En cada celda indicamos una condicin que debe cumplir la columna correspondiente y se puede combinar varias
condiciones mediante O (OR) e Y (AND) segn coloquemos las condiciones en la misma columna o en columnas diferentes.
En el ejemplo anterior tenemos la condicin compuesta: ((usuario=1) AND (Dias>5)) OR (Usuario=2).
Podemos variar el orden de aparicin de las columnas arrastrando la fila correspondiente de la rejilla hasta el lugar deseado.
Tambin podemos Elimnar filas de la rejilla para eliminar columnas del resultado, lo conseguimos seleccionando la fila
haciendo clic sobre su extremo izquierda y cuando aparece toda la fila remarcada pulsamos Supr o desde el men
contextual de la fila.
Podemos definir consultas ms complejas como por ejemplo consultas de resumen, pulsando sobre el botn Agrupar por de
la barra de herramientas, se aade a la rejilla una nueva columna Agrupar por con las siguientes opciones:
42
En l vemos la instruccin SQL generada, tambin podemos redactar directamente la sentencia SQL en el panel y ver los
cambios equivalentes en los distintos paneles. Para ver estos cambios debemos de ejecutar o Comprobar la sintaxis para
que se actualicen los dems paneles.
Por defecto el generador aade a la consulta una clusula TOP (100) PERCENT que indica que se visualizarn el 100% de
las filas. Esta clusula no la hemos definido nosotros sino que la aade automticamente el generador.
Una vez tenemos la vista definida la guardamos y podremos hacer con ella casi todo lo que podemos hacer con una tabla.
De hecho si nos fijamos en el Explorador de objetos, en la carpeta Vistas:
Vemos que la estructura es muy similar a la estrutura de una tabla. Y que podemos modificar su definicin y ejecutarla, igual
que con las tablas:
Abrir vista para ejecutarla y ver los datos como si fuese una tabla real.
43
El DDL, es la parte del SQL dedicada a la definicin de la base de datos, consta de sentencias para definir la estructura
de la base de datos, permiten crear la base de datos, crear, modificar o eliminar la estructura de las tablas, crear ndices,
definir reglas de validacin de datos, relaciones entre las tablas, etc. Permite definir gran parte del nivel interno de la base de
datos. Por este motivo estas sentencias sern utilizadas normalmente por el administrador de la base de datos.
El DCL (Data Control Language) se compone de instrucciones que permiten:
Ejercer un control sobre los datos tal como la asignacin de privilegios de acceso a los datos (GRANT/REVOKE).
Una transaccin se puede definir como un conjunto de acciones que se tienen que realizar todas o ninguna para preservar la
integridad de la base de datos.
Por ejemplo supongamos que tenemos una base de datos para las reservas de avin. Cuando un usuario pide reservar una
plaza en un determinado vuelo, el sistema tiene que comprobar que queden plazas libres, si quedan plazas reservar la que
44
quiera el usuario generando un nuevo billete y marcando la plaza como ocupada. Aqu tenemos un proceso que consta de
dos operaciones de actualizacin de la base de datos (crear una nueva fila en la tabla de billetes y actualizar la plaza
reservada en el vuelo, ponindola como ocupada) estas dos operaciones se tienen que ejecutar o todas o ninguna, si
despus de crear el billete no se actualiza la plaza porque se cae el sistema, por ejemplo, la base de datos quedara en un
estado inconsistente ya que la plaza constara como libre cuando realmente habra un billete emitido para esta plaza. En
este caso el sistema tiene el mecanismo de transacciones para evitar este error. Las operaciones se incluyen las dos en una
misma transaccin y as el sistema sabe que las tiene que ejecutar las dos, si por lo que sea no se pueden ejecutar las dos,
se encarga de deshacer los cambios que se hubiesen producido para no ejecutar ninguna.
Las instrucciones que gestionan las autorizaciones sern utilizadas normalmente por el administrador mientras que las otras,
referentes a proceso de transacciones sern utilizadas tambin por los programadores.
No todos los sistemas disponen de ellas.
El DML se compone de las instrucciones para el manejo de los datos, para insertar nuevos datos, modificar datos
existentes, para eliminar datos y la ms utilizada, para recuperar datos de la base de datos. Veremos que una sola
instruccin de recuperacin de datos es tan potente que permite recuperar datos de varias tablas a la vez, realizar clculos
sobre estos datos y obtener resmenes.
El DML interacta con el nivel externo de la base de datos por lo que sus instrucciones son muy parecidas, por no decir casi
idnticas, de un sistema a otro, el usuario slo indica lo que quiere recuperar no cmo se tiene que recuperar, no influye el
cmo estn almacenados los datos.
Es el lenguaje que utilizan los programadores y los usuarios de la base de datos.
A lo largo del curso se explicarn cada una de las formas de explotacin de la base de datos. Dependiendo de tu perfil
profesional (programador o administrador) o de tu inters personal te resultar ms til un bloque u otro.
Tipos de datos.
Definicin de variables.
Gestin de excepciones.
Funciones predefinidas.
45
Crear aplicaciones ejecutables, sino elementos que en algn momento llegarn al servidor de datos y sern
ejecutados.
Debido a estas restricciones se emplea generalmente para crear procedimientos almacenados, triggers y funciones de
usuario.
Puede ser utilizado como cualquier SQL como lenguaje embebido en aplicaciones desarrolladas en otros lenguajes de
programacin como Visual Basic, C, Java, etc. Y por supuesto los lenguajes incluidos en la plataforma .NET.
Tambin lo podremos ejecutar directamente de manera interactiva, por ejemplo desde el editor de consultas de SSMS (SQL
Server Management Studio) el entorno de gestin que ya conocemos. Esta es la forma en que lo utilizaremos nosotros.
seguido de una serie de clusulas (unas obligatorias, otras opcionales) que completan la frase, y proporcionan ms
detalles acerca de lo que se quiere hacer.
Si sabemos algo de ingls nos ser ms fcil interpretar a la primera lo que quiere decir la instruccin, y de lo contrario,
como el nmero de palabras que se emplean es muy reducido, enseguida nos las aprenderemos.
Por ejemplo en el DDL (acciones sobre la definicin de la base de datos), tenemos 3 verbos bsicos:
CREATE (Crear)
DROP (Eliminar)
ALTER (Modificar)
46
47
En una sentencia utilizaremos palabras reservadas (las fijas del lenguaje), y nombres de objetos y variables
(identificadores).
Las palabras reservadas no se pueden utilizar para otro propsito, por ejemplo una tabla no se puede llamar FROM, y los
nombres (los identificadores) siguen las reglas detalladas en el punto siguiente.
Nombres cualificados. En ocasiones deberemos utilizar nombres cualificados, por ejemplo cuando se escribe un nombre
de tabla, SQL presupone que se est refiriendo a una de las tablas de la base de datos activa, si queremos hacer referencia
a una tabla de otra base de datos utilizamos su nombre cualificado nombrebasedatos.nombredeesquema.nombretabla,
utilizamos el punto para separar el nombre del objeto y el nombre de su contenedor.
O por ejemplo si en una consulta cuyo origen son dos tablas, queremos hacer referencia a un campo y ese nombre de
campo es un nombre de campo en las dos tablas, pues utilizaremos su nombre cualificado nombretabla.nombrecampo.
El valor NULL.
Puesto que una base de datos es un modelo de una situacin del mundo real, ciertos datos pueden inevitablemente faltar,
ser desconocidos o no ser aplicables, esto se debe de indicar de alguna manera especial para no confundirlo con un valor
conocido pero que sea cero por ejemplo, SQL tiene para tal efecto el valor NULL que indica precisamente la ausencia de
valor.
Por ejemplo: no es lo mismo que el alumno no tenga nota a que tenga la nota cero, esto afectara tambin a todos los
clculos que se pueden realizar sobre la columna nota.
El nombre debe tener entre 1 y 128 caracteres, excepto para algunos tipos de objetos en los que el nmero es ms
limitado.
Una letra, como aparece definida por el estndar Unicode 3.2. La definicin Unicode de letras incluye los
caracteres latinos de la "a" a la "z" y de la "A" a la "Z".
Ciertos smbolos al principio de un identificador tienen un significado especial en SQL Server. Un identificador que
empieza con el signo de arroba indica un parmetro o una variable local. Un identificador que empieza con el signo
48
de nmero indica una tabla o procedimiento temporal. Un identificador que empieza con un signo de nmero doble
(##) indica un objeto temporal global.
Algunas funciones de Transact-SQL tienen nombres que empiezan con un doble signo de arroba (@@). Para evitar
confusiones con estas funciones, se recomienda no utilizar nombres que empiecen con @@.
Si queremos utilizar un nombre que no siga estas reglas, normalmente para poder incluir espacios en blanco, lo tenemos
que escribir encerrado entre corchetes [ ] (tambin se pueden utilizar las comillas pero recomendamos utilizar los corchetes).
Si quieres conocer todos los tipos de datos disponibles en SQLServer 2005, visita el siguiente avanzado .
Las constantes numricas se escriben mediante una cadena de nmeros, con la consideracin de que el separador
decimal es un punto, no una coma, y que si se trata de un valor monetario deberemos incluir la moneda al inicio de
la constante. Por ejemplo: 85.90 y 85.90, el primero sera un valor decimal y el segundo un valor money. De forma
predeterminada, los valores sern positivos. Para indicar lo contrario escribimos el signo - al principio.
Las constantes de fecha y hora van entre comillas simples y con un formato de fecha y hora adecuado. Por ejemplo:
'03/10/90'.
Y las constantes en cadenas de caracteres van entre comillas simples. Por ejemplo: 'Juan Garca Lpez'.
Para indicar valores negativos y positivos aadimos el prefijo + o - segn sea el valor positivo o negativo. Sin prefijo se
entiende que el valor es positivo.
Si quieres ver cmo definir constantes para otros tipos de datos, visita el siguiente avanzado .
49
Dos expresiones pueden combinarse mediante un operador si ambas tienen tipos de datos admitidos por el operador y se
cumple al menos una de estas condiciones:
El tipo de datos de menor prioridad se puede convertir implcitamente al tipo de datos de mayor prioridad.
La funcin CAST puede convertir explcitamente el tipo de datos con menor prioridad al tipo de datos con mayor
prioridad o a un tipo de datos intermedio que pueda convertirse implcitamente al tipo de datos con la mayor
prioridad.
Tipos de operadores:
- Operadores numricos:
suma
resta
multiplicacin
divisin
mdulo
- Operadores bit a bit: realizan manipulaciones de bits entre dos expresiones de cualquiera de los tipos de datos de la
categora del tipo de datos entero.
AND
&
OR
OR exclusivo
50
- Operadores de comparacin:
Igual a
Mayor que
>
Menor que
<
>=
<=
Distinto de
<>
No es igual a
!=
No menor que
!<
No mayor que
!>
- Operadores lgicos:
Aqu slo los nombraremos ya que en el tema de consultas simples los veremos en detalle.
ALL
IN
AND
LIKE
ANY
NOT
BETWEEN
OR
EXISTS
SOME
- Operadores de cadenas:
Concatenacin
Resultados de la expresin
- Si se combinan dos expresiones mediante operadores de comparacin o lgicos, el tipo de datos resultante es booleano y
el valor es uno de los siguientes: TRUE, FALSE o UNKNOWN.
51
- Cuando dos expresiones se combinan mediante operadores aritmticos, bit a bit o de cadena, el operador determina el tipo
de datos resultante.
Las expresiones complejas formadas por varios smbolos y operadores se evalan como un resultado formado por un solo
valor. El tipo de datos, intercalacin, precisin y valor de la expresin resultante se determina al combinar las expresiones
componentes de dos en dos, hasta que se alcanza un resultado final. La prioridad de los operadores de la expresin define
la secuencia en que se combinan las expresiones.
2.8. Funciones
SQL Server 2005 proporciona numerosas funciones integradas y permite crear funciones definidas por el usuario.
Existen diferentes tipos de funciones:
Funciones de conjuntos de filas: devuelven un objeto que se puede utilizar, en instrucciones Transact-SQL, en lugar
de una referencia a una tabla.
Funciones de agregado (tambin llamadas funciones de columna): Operan sobre una coleccin de valores y
devuelven un solo valor de resumen. Por ejemplo, la funcin de suma sobre la columna importe para conocer el
importe total: SUM(importe)
Funciones de categora: Devuelven un valor de categora para cada fila de un conjunto de filas, por ejemplo
devuelve el nmero de la fila, el ranking de la fila en una determinada ordenacin, etc.
Funciones escalares: Operan sobre un valor y despus devuelven otro valor. Son las funciones que estamos
acostumbrados a utilizar. Las funciones escalares se clasifican segn el tipo de datos de sus operandos
Las variables
En Transact-SQL podemos definir variables, que sern de un tipo de datos determinado, como tipos de datos podemos
utilizar los propios de la base de datos SQL-SERVER, pero tambin podemos utilizar tipos propios del lenguaje que no
pueden ser utilizados en DDL. El tipo Cursor y el tipo Table son dos de estos tipos.
Las variables se definen utilizando la instruccin DECLARE con el siguiente formato:
DECLARE @nbvariable tipo
El nombre de la variable debe empezar por el smbolo @, este smbolo hace que SQL interprete el nombre como un nombre
de variable y no un nombre de objeto de la base de datos.
Por ejemplo: DECLARE @empleados INT
Con esto hemos definido la variable @empleados de tipo entero.
Para asignar un valor a una variable, la asignacin se realiza con la palabra SELECT y el signo igual con el formato:
SELECT @nbvariable = valor
El valor puede ser cualquier valor constante, otro nombre de variable, una expresin vlida o algo ms potente, parte de una
sentencia SELECT de SQL.
52
Por ejemplo:
SELECT @empleados = 0;
SELECT @empleados = @otra * 100;
SELECT @EMPLEADOS = COUNT(numemp) FROM empleados;
El valor almacenado en la variable se puede visualizar mediante la orden PRINT. o SELECT
PRINT @nbvariable o SELECT @nbvariable
El valor almacenado en la variable se visualizar en la pestaa de resultados. Tambin se puede usar para escribir
mensajes:
PRINT 'Este es el mensaje'
Otros elementos del lenguaje
Comentarios. Como en cualquier otro lenguaje de programacin, debemos utilizar comentarios destinados a facilitar la
legibilidad del cdigo. En SQL se insertan comentarios con los signos:
/* */
Varias lneas
--
/*
Esto
es
un
comentario
en varias lneas */
-- Esto es un comentario en una nica lnea.
53
54
Debido a la complejidad de la sentencia (en la sintaxis anterior no se han detallado algunos elementos), la iremos viendo
poco a poco, empezaremos por ver consultas bsicas para luego ir aadiendo ms clusulas.
Empezaremos por ver las consultas ms simples, basadas en una sola tabla y nos limitaremos a la siguiente sintaxis:
SELECT [ALL|DISTINCT]
[TOP expresion [PERCENT] [WITH TIES]]
<lista_seleccion>
FROM <origen>
[WHERE <condicion_busqueda> ]
[ORDER BY {expression_columna|posicion_columna [ASC|DESC]} [ ,...n ]]
3.2. Origen de datos FROM
De la sintaxis anterior, el elemento <origen> indica de dnde se va a extraer la informacin y se indica en la clusula FROM,
es la nica clusula obligatoria. En este tema veremos un origen de datos basado en una sola tabla.
La sintaxis ser la siguiente:
<origen>::=
nb_tabla | nb_vista [[ AS ] alias_tabla ]
nb_tabla representa un nombre de tabla.
nb_vista un nombre de vista.
Tanto para las tablas como para las vistas, podemos hacer referencia a tablas que estn en otras bases de datos (siempre
que tengamos los permisos adecuados), en este caso tenemos que cualificar el nombre de la tabla, indicando delante el
nombre de la base de datos (Lgica) y el nombre del esquema al que pertenece la tabla dentro de la base de datos.
Por ejemplo: MiBase.dbo.MiTabla se refiere a la tabla MiTabla que se encuentra en el esquema dbo de la base de datos
MiBase.
Cuando no se definen esquemas, SQL-Server crea uno por defecto en cada base de datos denominado dbo.
Opcionalmente podemos definir un nombre de alias.
Un nombre de alias (alias_tabla) es un nombre alternativo que se le da a la tabla dentro de la consulta.
Si se define un nombre de alias, dentro de la consulta, ser el nombre a utilizar para referirnos a la tabla, el nombre original
de la tabla ya no tendr validez.
Se utilizan los nombres de alias para simplificar los nombres de tablas a veces largos y tambin cuando queremos combinar
una tabla consigo misma; ya volveremos sobre los alias de tabla cuando veamos consultas multitabla.
La palabra AS no aade ninguna operatividad, est ms por esttica.
Podemos escribir:
55
SELECT ...
FROM tabla1
SELECT ...
FROM tabla1 t1
SELECT ...
FROM tabla1 AS t1 Es equivalente a la sentencia anterior.
Si la tabla o la vista estn en otra base de datos del mismo equipo que est ejecutando la instancia de SQL Server, se utiliza
el nombre cualificado con el formato nbBaseDatos.nbEsquema.nbTabla.
Si la tabla o la vista estn fuera del servidor local en un servidor vinculado, se utiliza un nombre de cuatro partes con el
formato nbservidor.catalogo.nbEsquema.nbTabla. Volveremos ms adelante sobre las conexiones remotas.
una constante
56
Una subconsulta escalar, que es otra instruccin SELECT que devuelve un nico valor y se evala para cada fila del
origen de datos (esto no lo veremos de momento).
La palabra clave *.
oficina
contrato
Antonio Viguer
12
1986-10-20
Alvaro Jaumes
21
1986-12-10
Juan Rovira
12
1987-03-01
Jos Gonzlez
12
1987-05-19
Vicente Pantalla
13
1988-02-12
Luis Antonio
11
1988-06-14
Jorge Gutirrez
22
1988-11-14
57
Ana Bustamante
21
1989-10-12
Mara Sunta
11
1999-10-12
Juan Victor
NULL
1990-01-13
idproducto
descripcion
precio
aci
41001
arandela
0,58
aci
41002
bisagra
0,80
aci
41003
art t3
1,12
aci
41004
art t4
1,23
aci
4100x
junta
0,26
aci
4100y
extractor
28,88
aci
4100z
mont
26,25
bic
41003
manivela
6,52
bic
41089
rodamiento
2,25
58
Ejemplo:
SELECT numclie,nombre AS nombrecliente
FROM clientes;
El resultado ser :
Numclie
nombrecliente
2101
2102
Alvaro Rodrguez
2103
Jaime Llorens
en vez de:
Numclie
nombre
2101
2102
Alvaro Rodrguez
2103
Jaime Llorens
La palabra AS es opcional.
SELECT numclie,nombre nombrecliente
FROM clientes;
Sera equivalente a la consulta anterior
Si queremos incluir espacios en blanco en el nombre lo debemos encerrar entre corchetes.
SELECT numclie,nombre AS [nombre cliente]
FROM clientes;
Nota importante: Este nombre de alias se podr utilizar en la lista de seleccin y en la clusula ORDER BY pero no en la
clusula WHERE.
3.6. Funciones
Existen funciones que podemos utilizar en la lista de seleccin, e incluso en otras clusulas que veremos ms adelante,
como el WHERE. Las principales funciones son las siguientes:
Funciones de fecha:
59
Funcin
Descripcin
GETDATE
GETUTCDATE
DATEPART
DAY
MONTH
YEAR
DATENAME
DATEADD
DATEDIFF
Las funciones que ms se van a utilizar durante el curso estarn marcadas de la siguiente forma. Prstales especial
atencin.
Funciones de fecha
GETDATE
La funcin GETDATE devuelve la fecha actual en formato datetime.
GETDATE()
Ejemplo:
SELECT GETDATE() AS Ahora;
Una variante es la funcin GETUTCDATE()
60
GETUTCDATE
Devuelve la hora UTC (hora universal coordinada u hora del meridiano de Greenwich) actual. La hora UTC actual se deriva
de la hora local actual y la configuracin de zona horaria del sistema operativo del equipo en el que se ejecuta la instancia
de Microsoft SQL Server.
DATEPART
Devuelve un entero que representa la parte de la fecha especificada expresada en la unidad indicada.
DATEPART (unidad,fecha)
unidad
Abreviaturas Significado
year
yy, yyyy
ao
quarter
qq, q
cuatrimestre
month
mm, m
mes
dayofyear dy, y
n da del ao
day
dd, d
da
week
wk, ww
semana
weekday
dw, w
da de la semana
hour
hh
hora
minute
mi, n
minuto
second
ss, s
segundo
millisecond ms
milisegundo
Week (wk, ww) indica el nmero de semana del ao, refleja los cambios realizados en SET DATEFIRST (que indica el
primer da de la semana). El 1 de enero de cualquier ao define el nmero de inicio para week, por ejemplo: DATEPART(wk,
'1 Ene 2009') = 1.
Weekday (dw) devuelve un nmero que corresponde al da de la semana, por ejemplo: Lunes = 1, Sbado = 6. El nmero
generado con la unidad weekday depende del valor establecido por SET DATEFIRST.
61
Fecha
Es una expresin que devuelve un valor datetime o smalldatetime, o una cadena de caracteres con formato de fecha. El tipo
de datos datetime slo sirve para fechas a partir del 1 de enero de 1753.
Ejemplos
SELECT DATEPART(dw, '20/10/2008') devuelve 1 (es lunes).
SELECT 'dd',DATEPART(dd, '20/10/2008') devuelve 20
SELECT 'dy',DATEPART(dy, '20/10/2008') devuelve 294
DAY
Devuelve un entero que representa el da de la fecha especificada.
DAY(fecha)
Esta funcin es equivalente a DATEPART(dd, fecha).
MONTH
Devuelve un entero que representa el mes de la fecha especificada.
MONTH(fecha)
Esta funcin es equivalente a DATEPART(mm, fecha).
YEAR
Devuelve un entero que representa el ao de la fecha especificada.
YEAR(fecha)
Esta funcin es equivalente a DATEPART(yy, fecha).
DATENAME
Devuelve una cadena de caracteres que representa el valor de la unidad especificada de una fecha especificada.
DATENAME(unidad, fecha)
Unidad puede tomar los mismos valores que en la funcin DATEPART
Cuando la unidad corresponde a mes o da de la semana, devuelve el valor en letras.
Ejemplos:
SELECT 'dd',DATENAME(dd, '20/10/2008')
devuelve 20
devuelve Octubre
devuelve 2008
devuelve Lunes
DATEADD
Devuelve un valor datetime nuevo que resulta de sumar un intervalo de tiempo a una fecha especificada.
62
Abreviaturas Significado
year
yy, yyyy
ao
quarter
qq, q
cuatrimestre
month
mm, m
mes
dayofyear dy, y
n da del ao
day
dd, d
da
week
wk, ww
semana
weekday
dw, w
da de la semana
hour
hh
hora
minute
mi, n
minuto
second
ss, s
segundo
millisecond ms
milisegundo
DATEDIFF
Devuelve el nmero de intervalos que hay entre las dos fechas especificadas.
63
@@DATEFIRST
Devuelve el primer da de la semana establecido con SET DATEFIRST.
SET DATEFIRST
Establece el primer da de la semana en un nmero del 1 al 7.
SET DATEFIRST nmero
Se puede utilizar la funcin @@DATEFIRST para ver el valor actual de SET DATEFIRST.
La opcin SET DATEFIRST se establece en tiempo de ejecucin.
Nmero es un entero que indica el primer da de la semana. Puede ser uno de los siguientes valores.
nmero Primer da de la semana
1
Lunes
Martes
Mircoles
Jueves
Viernes
Sbado
Domingo
64
Funciones de cadena:
Funcin
ASCII
Descripcin
Devuelve el valor de cdigo ASCII del carcter situado ms a la izquierda de una expresin de
caracteres.
CHAR
NCHAR
UNICODE
LEN
Devuelve el total de caracteres de una cadena, excluidos los espacios en blanco finales.
LTRIM
RTRIM
LEFT
RIGHT
SUBSTRING
LOWER
UPPER
REPLACE
STUFF
QUOTENAME
SPACE
STR
65
REPLICATE
REVERSE
PATINDEX
Otras funciones:
Funcin
Descripcin
ROUND
CAST y CONVERT
CASE
ISNULL
COALESCE
Funciones de cadena
ASCII
Devuelve el valor de cdigo ASCII del carcter situado ms a la izquierda de una expresin de caracteres.
ASCII(expresion_cadena)
expresion_cadena Es una expresin de tipo char o varchar.
La funcin devuelve un valor int.
Ejemplo:
ASCII('abc') devuelve 97, lo mismo que ASCII('a').
CHAR
Devuelve el carcter segn el cdigo ASCII correspondiente a un nmero entero.
CHAR(numero)
Numero es un nmero entero entre 0 y 255 de lo contrario la funcin devuelve NULL.
Se suele utilizar para insertar caracteres de control en cadenas alfanumricas.
66
char(9)
Avance de lnea
char(10)
Retorno de carro
char(13)
Ejemplo:
ASCII('abc') devuelve a.
NCHAR
Devuelve el carcter Unicode correspondiente al cdigo entero dado, tal como se define en el estndar Unicode.
NCHAR(numero)
Numero es un nmero entero entre 0 y 65535 de lo contrario la funcin devuelve NULL.
Ejemplo:
NCHAR(400) devuelve
UNICODE
Devuelve el valor entero, segn la definicin del estndar Unicode, del primer carcter de la expresin de entrada.
UNICODE(expresion_cadena)
expresion_cadena Es una expresin de tipo Nchar o Nvarchar.
La funcin devuelve un valor int.
Ejemplo:
UNICODE(N'') devuelve
LEN
Devuelve el nmero de caracteres de la expresin de cadena especificada, excluidos los espacios en blanco finales.
LEN(Expresion_cadena)
Expresion_cadena es una expresin de cadena
El valor devuelto es de tipo bigint si Expresion_cadena tiene el tipo de datos varchar(max), nvarchar(max) o varbinary(max);
en caso contrario, int.
Ejemplo:
LEN('abcdef ') devuelve 7
LTRIM
Devuelve una cadena tras quitar todos los espacios iniciales en blanco.
67
LTRIM(Expresion_cadena)
Expresion_cadena es una expresin de cadena, debe ser un tipo de datos implcitamente convertible a varchar excepto
text, ntext e image.
El valor devuelto es de tipo varchar o nvarchar.
Ejemplo:
LTRIM('
RTRIM
Devuelve una cadena tras quitar todos los espacios finales en blanco.
RTRIM(Expresion_cadena)
Expresion_cadena es una expresin de cadena, debe ser un tipo de datos implcitamente convertible a varchar excepto
text, ntext e image.
El valor devuelto es de tipo varchar o nvarchar.
Ejemplo:
RTRIM('
ab cdef
') devuelve
ab cdef.
LEFT
Devuelve la parte izquierda de una cadena de caracteres con el nmero de caracteres especificado.
LEFT(Expresion_cadena, longitud)
Expresion_cadena es una expresin de cadena
Longitud: es el nmero de caracteres a devolver. Puede ser de tipo bigint, si es negativo la funcin devuelve un error.
El valor devuelto es de tipo varchar o nvarchar.
Ejemplo:
LEFT('abcdef ', 3) devuelve abc
RIGHT
Devuelve la parte derecha de una cadena de caracteres con el nmero de caracteres especificado.
RIGHT(Expresion_cadena, longitud)
Expresion_cadena es una expresin de cadena
Longitud: es el nmero de caracteres a devolver. Puede ser de tipo bigint, si es negativo la funcin devuelve un error.
El valor devuelto es de tipo varchar o nvarchar.
Ejemplo:
RIGHT('abcdef ', 3) devuelve def
68
SUBSTRING
Devuelve parte de una expresin de caracteres, binaria, de texto o de imagen.
SUBSTRING ( expresion ,inicio , longitud )
expresion
Es una cadena de caracteres, una cadena binaria, texto, imagen, una columna o una expresin que incluye una columna. No
se puede utilizar expresiones que incluyan funciones de agregado.
inicio
Es un entero que especifica dnde comienza la subcadena. start puede ser de tipo bigint.
longitud
Es un entero positivo (puede ser de tipo bigint ) que especifica cuntos caracteres o bytes de la expression se van a
devolver. Si longitud es negativo, se devuelve un error.
Segn el tipo de datos de Expresion los datos devueltos son de tipo:
Expresion
Valor devuelto
char/varchar/text
varchar
nchar/nvarchar/ntext
nvarchar
binary/varbinary/image varbinary
Los valores (inicio y longitud) que utilizan los tipos de datos ntext, char o varchar deben especificarse en nmero de
caracteres. Los desplazamientos que utilizan los tipos de datos text, image, binary o varbinary deben especificarse en
nmero de bytes.
Ejemplo:
SUBSTRING('abcdef',3,2) devuelve cd
LOWER
Devuelve una cadena despus de convertir en minsculas los caracteres en maysculas.
LOWER(Expresion_cadena)
Expresion_cadena es una expresin de cadena, debe ser un tipo de datos implcitamente convertible a varchar.
El valor devuelto es de tipo varchar o nvarchar.
Ejemplo:
LOWER('aBcdEf ', 3) devuelve abcdef
UPPER
Devuelve una cadena despus de convertir en maysculas los datos de caracteres en minsculas.
69
UPPER(Expresion_cadena)
Expresion_cadena es una expresin de cadena, debe ser un tipo de datos implcitamente convertible a varchar.
El valor devuelto es de tipo varchar o nvarchar.
Ejemplo:
UPPER('aBcdEf ', 3) devuelve ABCDEF
REPLACE
Reemplaza todas las apariciones de un valor de cadena especificado por otro valor de cadena.
REPLACE(cadena_original, cadena_a_quitar, cadena_a_poner)
Las cadenas pueden ser de tipo carcter o binario. Se pueden combinar con COLLATE.
Devuelve nvarchar si una de las cadenas es de tipo nvarchar, en caso contrario devuelve varchar.
Ejemplo:
REPLACE('Esto es una cuestin','es','xx') devuelve xxto xx una cuxxtin
STUFF
Elimina el nmero de caracteres especificado e inserta otro conjunto de caracteres en el punto de inicio indicado.
STUFF (expresin_origen, inicio , longitud , expresin_sustituta)
Si longitud es mayor que la longitud de expresin_origen, se elimina hasta el ltimo carcter de expresin_origen.
Tanto expresin_origen como expresin_sustituta pueden ser tanto de caracteres como binarios.
Ejemplo:
STUFF('abcdef', 2, 3, 'ijklmn') devuelve aijklmnef
QUOTENAME
Devuelve una cadena Unicode con los delimitadores agregados para convertirla en un identificador delimitado vlido de
Microsoft SQL Server 2005.
QUOTENAME ( 'cadena' [ , 'caracter' ] )
70
SPACE
Devuelve una cadena de espacios repetidos.
SPACE(nmero)
Nmero es un entero positivo que indica el nmero de espacios en blanco a devolver, si es negativo la funcin devuelve una
Cadena null.
Para incluir espacios en datos Unicode o para devolver ms de 8.000 espacios en blanco, utilice REPLICATE en lugar de
SPACE.
Ejemplo:
PRINT RTRIM('Ana
STR
Devuelve una cadena de caracteres a partir de datos numricos.
STR ( nmero [ , longitud [ , decimales ] ] )
Nmero es el nmero a convertir debe ser de tipo numrico.
Longitud es la longitud de la cadena devuelta incluye todos los caracteres, dgitos, punto decimal, signo y espacios. EL valor
predeterminado es 10.
Decimales es el nmero de cifras a la derecha del separador decimal. El valor de decimales debe ser menor o igual que 16.
Si es mayor que 16, el resultado se trunca en el decimosexto lugar a la derecha del separador decimal. El valor
predeterminado es cero.
La funcin redondea automticamente los valores.
Cuando la el valor excede de la longitud especificada la funcin devuelve **.
DECLARE @n numeric(5,3);
DECLARE @x float;
SELECT @n=3.67;
SELECT @x=3.45;
PRINT 'A'+STR(@n,8,2)+'B'
71
PRINT 'F'+STR(@x,8,2)+'G'
PRINT 'a'+STR(@n,8)+'b'
PRINT 'f'+STR(@x,8)+'g'
Da como salida:
A
3.67B
3.45G
4b
3g
REPLICATE
Repite una expresin de caracteres un nmero especificado de veces.
REPLICATE(expresion_cadena, longitud)
expresion_cadena Es una expresin de un tipo de datos que puede convertirse implcitamente a varchar. Tambin puede
ser una constante, una variable o una columna de datos binarios.
Longitud es un nmero entero positivo (puede ser de tipo bigint). Si es negativo, se devuelve una cadena NULL.
Ejemplo:
REPLICATE('abc',5) devuelve abcabcabcabcabc
REVERSE
Devuelve una expresin de caracteres invertida.
REVERSE(expresion_cadena)
expresion_cadena Es una expresin de un tipo de datos que puede convertirse implcitamente a varchar. Tambin puede
ser una constante, una variable o una columna de datos binarios.
Ejemplo:
REVERSE('abcdef') devuelve fedcba
CHARINDEX
Devuelve la posicin inicial de la expresin especificada en una cadena de caracteres.
CHARINDEX( cadena_a_buscar , cadena_origen [ , inicio ] )
cadena_a_buscar y cadena_origen son de tipo de datos carcter.
Inicio indica pa posicin a partir de la cual se empieza a buscar. Puede ser de tipo bigint. Si no se especifica o si es cero o
negativo, la bsqueda empieza en el primer carcter de cadena_origen.
Ejemplo:
CHARINDEX('fg', 'abcdefghyfg') devuelve 6
72
PATINDEX
Devuelve la posicin inicial de la primera repeticin de un patrn en la expresin especificada, o ceros si el patrn no se
encuentra, en todos los tipos de datos de texto y caracteres.
PATINDEX ( '%patrn%' , expresion )
Patrn es una cadena literal. Se pueden incluir caracteres comodn, aunque el carcter % debe preceder y seguir a patrn
(excepto cuando se busca el primer o el ltimo carcter). Es una expresin de la categora de tipo de datos de cadena de
caracteres.
Expression es de la categora de tipo de datos de cadena de caracteres. Se puede combinar con COLLATE.
La funcin devuelve bigint si expresion es de los tipos de datos varchar o nvarchar, en caso contrario, int.
Si expresin es una columna, la consulta devolver todas las filas del origen de la consulta (despus de ejecutar el WHERE)
e indicar valores distintos de cero para las filas en las que se haya encontrado el patrn y cero para el resto.
Ejemplo:
PRINT PATINDEX('%cd%','aasecdgtcd') devuelve 5
PRINT PATINDEX('cd%','aasecdgtcd')
PRINT PATINDEX('%cd','aasecdgtcd')
ROUND
Devuelve un valor numrico, redondeado a la longitud o precisin especificadas y del mismo tipo.
ROUND ( expresion_numerica , longitud [ ,funcion ] )
expresion_numerica
Es una expresin de la categora de tipo de datos numrico exacto o numrico aproximado, excepto el tipo de datos bit.
longitud
Es la precisin con la que se redondea expresion_numerica. Debe ser una expresin de tipo tinyint, smallint o int. Si
longitud es un nmero positivo, se redondea al nmero de posiciones decimales que especifica longitud. Si longitud es un
nmero
negativo,
se
redondea
la
izquierda
del
separador
decimal,
segn
se
especifica
en
longitud.
funcion
Es el tipo de operacin que se realiza. function debe ser de tipo tinyint, smallint o int. Si function se omite o tiene el valor 0
(predeterminado), se redondea. Si se especifica un valor distinto de 0, se trunca.
Ejemplos:
ROUND(1265.45627, 2)
devuelve
1265.46000
ROUND(1265.45627, 3)
devuelve
1265.45600
ROUND(1265.45627, 2,1)
devuelve
1265.45000 trunca
ROUND(1265.45627, -3)
devuelve
1000.00000
ROUND(1265.45627, -2)
devuelve
1300.00000
73
CAST y CONVERT
Convierten una expresin de un tipo de datos en otro de forma explcita. CAST y CONVERT proporcionan funciones
similares.
CAST ( expresion AS tipo_dato [ (longitud) ])
si
no
se
ha
especificado
el
parmetro
longitud,
el
valor
predeterminado
es
30
caracteres.
estilo
Es el estilo del formato de fecha usado para convertir datos de tipo datetime o smalldatetime en datos de caracteres (con
tipo de datos nchar, nvarchar, char, varchar, nchar o nvarchar), o para convertir datos de caracteres de formatos de fecha
y hora conocidos en datos de tipo datetime o smalldatetime; o bien, el formato de cadena usado para convertir datos de
tipo float, real, money o smallmoney en datos de caracteres (con tipo de datos nchar, nvarchar, char, varchar, nchar o
nvarchar). Cuando estilo es NULL, el resultado devuelto tambin es NULL.
En las conversiones money a carcter los estilos utilizados son:
Valor
Resultado
Sin separadores de millar cada tres dgitos a la izquierda del separador decimal y dos dgitos a la
Separadores de millar cada tres dgitos a la izquierda del separador decimal y dos dgitos a la derecha
del separador decimal; por ejemplo, 3.510,92.
Sin separadores de millar cada tres dgitos a la izquierda del separador decimal y cuatro dgitos a la
derecha del separador decimal; por ejemplo, 4235,9819.
En las conversiones de tipo fecha a tipo alfanumrico, por ejemplo los estilos 3 y 103 permiten convertir la fecha con el estilo
dd/mm/aa y dd/mm/aaaa respectivamente.
Ejemplo:
DECLARE @fecha AS datetime;
SELECT @fecha= GETDATE();
PRINT @fecha;
devuelve 27/10/08
74
CASE
Evala una lista de condiciones y devuelve una de las varias expresiones de resultado posibles.
La funcin CASE sencilla compara una expresin con un conjunto de expresiones sencillas para determinar el
resultado.
La funcin CASE buscada evala un conjunto de expresiones booleanas para determinar el resultado.
Evala expresion_entrada y, en el orden especificado, la expresin expresion_entrada = valor para cada clusula
WHEN.
Si expresion_entrada = valor no se evala como TRUE, SQL Server 2005 Database Engine (Motor de base de datos
de SQL Server 2005) devuelve resultado_sino si se especifica una clusula ELSE, o bien un valor NULL si no se
especifica ninguna clusula ELSE.
75
Ejemplo:
CASE estado_civil
WHEN c THEN casado/a
ELSE otro
END
Si queremos evaluar si el campo es nulo no podemos aadir un WHEN NULL THEN nulo porque la condicin estado_civil =
NULL no es TRUE cuando el campo es nulo, en este caso habra que utilizar la segunda forma de la funcin CASE y utilizar
el operador is null.
Funcin CASE buscada:
CASE
WHEN condicion THEN resultado
[ ...n ]
[
ELSE resultado_sino
]
END
Condicion
es
la
condicin
que
se
evala
si
el
resultado
es
TRUE
la
funcin
devuelve
resultado.
Devuelve resultado de la primera condicion que se evala como TRUE. SI ninguna condicin se evala como TRUE la
funcin devuelve NULL.
Ejemplo:
CASE
WHEN estado_civil IS NULL THEN nulo
WHEN estado_civil = c THEN casado/a
WHEN estado_civil = s THEN soltero/o
WHEN estado_civil = v THEN viudo/a
ELSE otro
END
ISNULL
Reemplaza el valor NULL con el valor de reemplazo especificado.
ISNULL ( expresion_entrada , valor )
expresion_entrada es la expresin que indica donde se va a comprobar la existencia de NULL.
Valor es el valor por el cual se reemplaza NULL.
76
Ejemplo:
ISNULL(precio, 0)
Si en precio hay un valor no nulo la funcin devuelve ese valor, si precio contiene NULL entonces la funcin devuelve 0.
COALESCE
Devuelve la primera expresin distinta de NULL entre sus argumentos.
COALESCE ( expresion [ ,...n ] )
Si todos los argumentos son NULL, la funcin devuelve NULL.
Por ejemplo, tenemos dos campos fijo y movil, en uno tenemos el telfono fijo del cliente y en el otro tenemos el telfono
mvil y queremos obtener el telfono fijo si tiene y sino el mvil, lo pondramos as:
COALESCE(fijo, movil)
3.7. Columnas calculadas
Adems de las columnas que provienen directamente de la tabla origen, una consulta SQL puede incluir columnas
calculadas cuyos valores se evalan a partir de una expresin.
La expresin puede contener cualquier operador vlido (+, -, *, /, &), cualquier funcin vlida, nombres de columnas del
origen de datos, nombres de parmetros o constantes y para combinar varias operaciones se pueden utilizar los parntesis.
Ejemplos de columnas calculadas:
Listar la ciudad, regin y el supervit de cada oficina. Consideraremos el supervit como el volumen de ventas que se
encuentran por encima o por debajo del objetivo de la oficina.
SELECT ciudad, region, (ventas-objetivo) AS superavit
FROM oficinas;
El resultado ser:
ciudad
region
superavit
Valencia
este
11800,00
Alicante
este
-6500,00
Castellon
este
1800,00
Badajoz
oeste
11100,00
A Corua
oeste
-11400,00
Madrid
centro
NULL
77
Madrid
centro
-10000,00
Pamplona
norte
NULL
Valencia
este
-90000,00
De cada producto queremos saber el id de fabricante, id de producto, su descripcin y el valor de sus existencias.
SELECT idfab,idproducto,descripcion,(existencias*precio) AS valoracion
FROM productos;
El resultado sera:
Idfab
idproducto
descripcion
valoracion
aci
41001
arandela
160,66
aci
41002
bisagra
133,60
aci
41003
art t3
231,84
aci
41004
art t4
170,97
aci
4100x
junta
9,62
aci
4100y
extractor
722,00
aci
4100z
mont
735,00
bic
41003
manivela
19,56
bic
41089
rodamiento
175,50
78
Mes de contrato
Ao de contrato
Antonio Viguer
10
1986
Alvaro Jaumes
12
1986
Juan Rovira
1987
Listar las ventas en cada oficina con el formato: 22 tiene ventas de 186,042.00
SELECT oficina, 'tiene ventas de ' AS [ ], ventas
FROM oficinas;
El resultado sera:
oficina
ventas
11
tiene ventas de
69300,00
12
tiene ventas de
73500,00
13
tiene ventas de
36800,00
21
tiene ventas de
83600,00
22
tiene ventas de
18600,00
23
tiene ventas de
NULL
24
tiene ventas de
15000,00
26
tiene ventas de
NULL
28
tiene ventas de
0,00
El incluir una constante como columna en la lista de seleccin puede parecer intil (se repetir el mismo valor en todas las
filas) pero veremos ms adelante que tiene utilidad en ciertos casos.
Tambin podemos utilizar la sintaxis:
79
alias_columna = <expresion>
Ejemplo:
SELECT oficina, superavit = ventas-objetivo
Esto tiene el mismo efecto que
SELECT oficina, ventas-objetivo AS superavit
3.8. Utilizacin del asterisco *
Si queremos visualizar todas las columnas del origen de datos, en lugar de indicar todas las columnas una a una se puede
utilizar el carcter de sustitucin *.
Mostrar todos los datos de la tabla oficinas.
SELECT *
FROM oficinas;
Obtener todos los datos y el supervit de cada oficina.
SELECT *, (ventas-objetivo) AS superavit
FROM oficinas;
Tambin podemos cualificar el * con un nombre de tabla, de vista o un alias de tabla:
SELECT oficinas.*
FROM oficinas;
oficinas.* se interpreta como: todas las columnas de la tabla oficinas.
Esta forma se utiliza normalmente cuando el origen est basado en varias tablas y queremos indicar todas las columnas no
del origen completo sino de una tabla concreta.
80
Si la columna de ordenacin es de tipo fecha, las filas se ordenarn de ms antigua a ms reciente o futura.
Ejemplos:
Mostrar las ventas de cada oficina, ordenadas por orden alfabtico de regin y dentro de cada regin por ciudad.
SELECT oficina, region, ciudad, ventas
FROM oficinas
ORDER BY region, ciudad;
Da como resultado:
Oficina
region
ciudad
ventas
24
centro
Aranjuez
15000,00
23
centro
Madrid
NULL
12
este
Alicante
73500,00
13
este
Castelln
36800,00
11
este
Valencia
69300,00
28
este
Valencia
0,00
26
norte
Pamplona
NULL
81
22
oeste
A Corua
18600,00
21
oeste
Badajoz
83600,00
Listar las oficinas de manera que las oficinas de mayores ventas aparezcan en primer lugar.
SELECT ciudad, region, ventas
FROM oficinas
ORDER BY ventas DESC;
ciudad
region
ventas
Badajoz
oeste
83600,00
Alicante
este
73500,00
Valencia
este
69300,00
Castellon
este
36800,00
A Corua
oeste
18600,00
Aranjuez
centro
15000,00
Valencia
este
0,00
Pamplona
norte
NULL
Madrid
centro
NULL
Listar las oficinas clasificadas en orden descendente de rendimiento de ventas, de modo que las de mayor rendimiento
aparezcan las primeras.
SELECT ciudad, region, ventas-objetivo
FROM oficinas
ORDER BY 3 DESC;
Lo mismo que el anterior pero agrupadas por regin.
SELECT region, ciudad, (ventas-objetivo) AS superavit
FROM oficinas
82
ciudad
superavit
centro
Aranjuez
-10000,00
centro
Madrid
NULL
este
Valencia
11800,00
este
Castelln
1800,00
este
Alicante
-6500,00
este
Valencia
-90000,00
norte
Pamplona
NULL
oeste
Badajoz
11100,00
oeste
A Corua
-11400,00
En este caso hemos utilizado el alias de columna para hacer referencia a la columna calculada y tambin se puede observar
que las filas aparecen ordenadas por regin ascendente (no hemos incluido nada despus del nombre de la columna) y
dentro de cada regin por supervit y descendente.
83
106
104
105
108
108
108
108
NULL
NULL
Si un mismo empleado dirige varias oficinas (por ejemplo el 108), su cdigo aparece repetido en el resultado. Para evitarlo
modificamos la consulta:
SELECT DISTINCT dir
FROM oficinas;
dir
NULL
104
105
106
108
Han desaparecido los valores duplicados.
Los que se eliminan son valores duplicados de filas del resultado, por ejemplo:
SELECT DISTINCT dir, region
FROM oficinas;
84
dir
region
NULL
este
NULL
norte
104
este
105
este
106
este
108
centro
108
oeste
Ahora el 108 aparece dos veces porque las dos filas donde aparece no son iguales (porque tienen distinta regin).
NOTA: La clusula DISTINCT hace que la consulta tarde algo ms en ejecutarse debido al proceso adicional de buscar y
eliminar las repeticiones, por lo que se aconseja utilizarla nicamente cuando sea imprescindible.
3.12. La clusula TOP
[TOP <expresin> [PERCENT] [WITH TIES]]
La clusula TOP indica que en el resultado no deben aparecer todas las filas resultantes sino un cierto nmero de registros,
las n primeras. Si la consulta incluye la clusula ORDER BY, se realiza la ordenacin antes de extraer los n primeros
registros.
La expresin representa ese nmero n y debe devolver un nmero entero sin signo.
Por ejemplo tenemos la siguiente tabla:
SELECT * FROM productos:
85
ORDER BY ventas;
Si existen ms registros con las mismas ventas que el ltimo valor de la lista, stos no saldrn en el resultado de la
consulta.
En el ejemplo el registro con cod = 2 no sale en el resultado y tiene las mismas ventas que cod = 3.
Si queremos que salgan aadimos la clusula WITH TIES. La clusula WITH TIES slo se puede emplear si la SELECT
incluye un ORDER BY, de lo contrario dar error.
Si aadimos la clusula WITH TIES:
SELECT TOP 3 WITH TIES *
FROM productos
ORDER BY ventas
Obtenemos:
Se incluyen en el resultado todos los registros que tienen ventas iguales al ltimo registro.
Otro ejemplo:
86
87
3.14. Predicados
En SQL tenemos 7 tipos de predicados, condiciones bsicas de bsqueda:
Comparacin estndar
Si contiene (CONTAINS)
FREETEXT
Comparacin estndar.
Compara el valor de una expresin con el valor de otra. Para la comparacin se pueden emplear = , <> , !=, < , <= , !<,
> , >= ,!>
Sintaxis:
<expresion> {=|<>|!=|>|>=|!>|<|<=|!<} <expresion>
<expresion> Puede ser:
Un nombre de columna,
una constante,
una variable,
cualquier combinacin de nombres de columna, constantes y funciones conectados mediante uno o varios
operadores o una subconsulta.
Ejemplo:
Listar los "buenos" vendedores (los que han rebasado su cuota).
SELECT numemp, nombre, ventas, cuota
FROM empleados
WHERE ventas > cuota
88
numemp
nombre
ventas
cuota
101
Antonio Viguer
30500,00
30000,00
102
Alvaro Jaumes
47400,00
35000,00
103
Juan Rovira
28600,00
27500,00
105
Vicente Pantalla
36800,00
35000,00
106
Luis Antonio
29900,00
27500,00
108
Ana Bustamante
36100,00
35000,00
109
Mara Sunta
39200,00
3000,00
Las columnas que aparecen en el WHERE no tienen por qu aparecer en la lista de seleccin, esta instruccin es igual de
vlida:
SELECT numemp, nombre
FROM empleados
WHERE ventas > cuota;
Hallar vendedores contratados antes de 1988.
SELECT numemp, nombre, contrato
FROM empleados
WHERE contrato < '01/01/1988';
numemp
nombre
contrato
101
Antonio Viguer
1986-10-20
102
Alvaro Jaumes
1986-12-10
103
Juan Rovira
1987-03-01
104
Jos Gonzlez
1987-05-19
89
nombre
ventas
101
Antonio Viguer
30500,00
102
Alvaro Jaumes
47400,00
103
Juan Rovira
28600,00
105
Vicente Pantalla
36800,00
106
Luis Antonio
29900,00
108
Ana Bustamante
36100,00
90
109
Mara Sunta
39200,00
numemp
nombre
11
106
Luis Antonio
22
107
Jorge Gutirrez
11
109
Mara Sunta
Para practicar puedes realizar este Ejercicio Pertenencia a un conjunto con IN.
Test de valor nulo IS NULL
<expression> IS [NOT] NULL
Una condicin de bsqueda puede ser TRUE, FALSE o NULL/UNKNOW, este ltimo caso se produce cuando algn campo
que interviene en la condicin tiene valor NULL.
A veces es til comprobar explcitamente los valores NULL en una condicin de bsqueda ya que estas filas puede que
queramos darles un tratamiento especial, para ello tenemos el predicado IS NULL.
91
Este test produce un valor TRUE o FALSE, por lo que se podr combinar con otras condiciones. El valor NULL no es en s
un valor por eso no lo podemos utilizar en una igualdad.
SELECT numemp,nombre
FROM empleados
WHERE oficina = NULL;
Esta instruccin no da error pero no obtiene lo que en principio parece que quiere obtener. No obtenemos los empleados
cuya oficina sea un valor nulo (es decir los empleados que no tienen oficina), no obtenemos nada, en cambio los
obtendremos utilizando el test de valor nulo:
SELECT numemp,nombre, oficina
FROM empleados
WHERE oficina IS NULL;
Resultado:
numemp
nombre
oficina
110
Juan Victor
NULL
nombre
oficina
101
Antonio Viguer
12
102
Alvaro Jaumes
21
103
Juan Rovira
12
104
Jos Gonzlez
12
105
Vicente Pantalla
13
106
Luis Antonio
11
92
107
Jorge Gutirrez
22
108
Ana Bustamante
21
109
Mara Sunta
11
SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE An%;
numemp
nombre
101
Antonio Viguer
108
Ana Bustamante
nombre
104
Jos Gonzlez
107
Jos Gonzlez
93
SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE %on%;
numemp
nombre
101
Antonio Viguer
104
Jos Gonzlez
106
Luis Antonio
SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE '__a%';
numemp
nombre
103
Juan Rovira
108
Ana Bustamante
110
Juan Victor
Obtiene los nombres cuya tercera letra sea una a (en el patrn tenemos dos caracteres subrayado).
[ ] sirve para indicar un carcter cualquiera perteneciente al conjunto indicando.
El conjunto se indica enumerando los caracteres o indicando un intervalo.
SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE '[a-d]%';
Obtiene los nombres que empiezan por cualquier letra de la a a la d.
Es equivalente a escribir:
SELECT numemp,nombre
94
FROM empleados
WHERE nombre LIKE '[abcd]%';
[^] significa cualquier carcter individual que no se encuentre en el conjunto.
SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE '[^abcd]%';
Y
SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE '[^a-d]%';
Obtienen los nombres que no empiecen por a, b, c ni d.
Es importante tener en cuenta que dentro del patrn el espacio en blanco es considerado como un carcter ms, si
colocamos dos espacios en el patrn, se buscarn dos espacios en el campo.
Si queremos incluir en el patrn uno de los caracteres comodines y que no sea interpretado como un comodn, sino como un
carcter normal, lo tenemos que encerrar entre corchetes o utilizar un carcter de escape.
[ESCAPE 'car_escape']
La clusula ESCAPE es opcional y permite definir un carcter de escape.
Un carcter de escape es un carcter que se coloca delante de un carcter comodn para indicar que el comodn no debe
interpretarse como tal, sino como un carcter normal.
Por ejemplo queremos buscar los nombres compuestos que incluyen un subrayado. En este caso tenemos que poner el
carcter _ como un carcter normal no como un comodn, as que lo escribiremos as:
SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE '%[_]%';
O bien,
SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE '%!_%' ESCAPE '!';
95
Cuando la condicin incluye varios operadores lgicos, el orden de prioridad de estos operadores es:
Como siempre, se pueden utilizar parntesis para alterar esta prioridad en una condicin de bsqueda.
El orden de evaluacin de los operadores lgicos puede variar dependiendo de las opciones elegidas por el optimizador de
consultas.
Los operadores lgicos pueden devolver tres valores distintos: TRUE, FALSE, NULL (UNKNOWN).
Tablas de verdad de los operadores:
AND Combina dos condiciones y se evala como TRUE cuando ambas condiciones son TRUE.
AND
NULL
FALSE NULL
OR Combina dos condiciones y se evala como TRUE cuando alguna de las condiciones es TRUE.
OR
TRUE NULL
NULL
96
dir
11
106
12
104
13
105
97
26
NULL
28
NULL
La unin UNION
La diferencia EXCEPT
La interseccin INTERSECT
En todo el tema cuando hablemos de tablas nos referiremos tanto a las tablas que fsicamente estn almacenadas en la
base de datos como a las tablas temporales y a las resultantes de una consulta o vista.
4.2. La unin de tablas UNION
La unin de tablas consiste en coger dos tablas y obtener una tabla con las filas de las dos tablas, en el resultado
aparecern las filas de una tabla y, a continuacin, las filas de la otra tabla.
Para poder realizar la operacin, las dos tablas tienen que tener el mismo esquema (mismo nmero de columnas y tipos
compatibles) y la tabla resultante hereda los encabezados de la primera tabla.
La sintaxis es la siguiente:
{< consulta >|(< consulta >)}
UNION [ALL]
{< consulta >|(< consulta >)}
[{UNION [ALL] {< consulta >|(< consulta >)}}[ ...n ] ]
[ORDER BY {expression_columna|posicion_columna [ASC|DESC]}
98
[ ,...n ]]
<
consulta
>
representa
la
especificacin
de
la
consulta
que
nos
devolver
la
tabla
combinar.
Puede ser cualquier especificacin de consulta con la limitacin de que no admite la clusula ORDER BY, los alias de
campo se pueden definir pero slo tienen efecto cuando se indican en la primera consulta ya que el resultado toma los
nombres de columna de esta.
Ejemplo: Suponemos que tenemos una tabla Valencia con las nuevas oficinas de Valencia y otra tabla Madrid con las
nuevas oficinas de Madrid y queremos obtener una tabla con las nuevas oficinas de las dos ciudades:
SELECT oficina as OFI, ciudad FROM Valencia
UNION ALL
SELECT oficina, ciudad FROM Madrid;
El resultado sera:
OFI
ciudad
11
Valencia
28
Valencia
23
Madrid
El resultado coge los nombres de columna de la primera consulta y aparecen primero las filas de la primera consulta y
despus las de la segunda.
Si queremos que el resultado aparezca ordenado podemos incluir la clusula ORDER BY, pero despus de la ltima
especificacin de consulta, y expresion_columna ser cualquier columna vlida de la primera consulta.
SELECT oficina as OFI, ciudad FROM Valencia
UNION
SELECT oficina, ciudad FROM Madrid
ORDER BY ofi;
OFI
ciudad
11
Valencia
23
Madrid
28
Valencia
99
Ahora las filas aparecen ordenadas por el nmero de oficina y hemos utilizado el nombre de columna de la primera consulta.
Cuando
aparezcan
en
el
resultado
varias
filas
iguales,
el
sistema
por
defecto
elimina
las
repeticiones.
Si se especifica ALL, el sistema devuelve todas las filas resultante de la unin incluidas las repetidas
El empleo de ALL tambin hace que la consulta se ejecute ms rpidamente ya que el sistema no tiene que eliminar las
repeticiones.
Se pueden combinar varias tablas con el operador UNION. Por ejemplo supongamos que tenemos otra tabla Pamplona con
las oficinas nuevas de Pamplona:
SELECT oficina, ciudad FROM Valencia
UNION
SELECT oficina, ciudad FROM Madrid
UNION
SELECT oficina, ciudad FROM Pamplona;
Combinamos las tres tablas.
Otro ejemplo:
Obtener todos los productos cuyo precio exceda de 20 o que se haya vendido ms de 300 euros del producto en algn
pedido.
SELECT idfab, idproducto
FROM productos
WHERE precio > 20
UNION
SELECT fab, producto
FROM pedidos
WHERE importe > 300;
en
la
tabla
resultante
las
filas
de
la
primera
consulta
que
no
aparecen
en
la
segunda.
100
T2
Cod
Codigo
1
2
2
3
4
4
5
5
6
101
{ <consulta>|(<consulta>)}
INTERSECT
{<especificacion_consulta>|(<especificacion_consulta>)}
[{INTERSECT {<consulta>|(<consulta>)}} [ ...n ] ]
[ORDER BY {expression_columna|posicion_columna [ASC|DESC]}
[ ,...n ]]
Retomando el ejemplo anterior:
SELECT cod FROM T1
INTERSECT
SELECT cod FROM T2;
Devuelve:
Cod
2
4
5
Ejemplo: Obtener todos los productos que valen ms de 20 euros y que adems se haya vendido en un pedido ms de 300
euros de ese producto.
SELECT idfab, idproducto
FROM productos
WHERE precio > 20
INTERSECT
SELECT fab, producto
FROM pedidos
WHERE importe > 300;
102
nueva tabla fusionando las filas de una con las filas de la otra, concatenando los esquemas de ambas tablas. Consiste en
formar parejas de filas.
La sentencia SELECT permite realizar esta composicin, incluyendo dos o ms tablas en la clusula FROM.
Es hora de ampliar la clusula FROM que vimos en el tema anterior.
Empezaremos por estudiar la operacin a partir de la cual estn definidas las dems operaciones de composicin de tabla,
el producto cartesiano.
con
la
segunda oficina
y as hasta combinar
todos
los
empleados
con
todas
las
oficinas.
Si ejecutamos:
SELECT *
FROM empleados CROSS JOIN oficinas;
Obtenemos lo mismo.
Este tipo de operacin no es la que se utiliza ms a menudo, lo ms frecuente sera combinar cada empleado con los datos
de SU oficina. Lo podramos obtener aadiendo a la consulta un WHERE para filtrar los registros correctos:
SELECT *
FROM empleados, oficinas
103
WHERE empleados.oficina=oficinas.oficina;
Aqu nos ha aparecido la necesidad de cualificar los campos ya que el nombre oficina es un campo de empleados y de
oficinas por lo que si no lo cualificamos, el sistema nos da error.
Hemos utilizado en la lista de seleccin *, esto nos recupera todas las columnas de las dos tablas.
SELECT empleados.*,ciudad, region
FROM empleados, oficinas
WHERE empleados.oficina=oficinas.oficina;
Recupera todas las columnas de empleados y las columnas ciudad y regin de oficinas.
Tambin podemos combinar una tabla consigo misma, pero en este caso hay que definir un alias de tabla, en al menos una,
sino el sistema da error ya que no puede nombrar los campos.
SELECT *
FROM oficinas, oficinas as ofi2;
No insistiremos ms sobre el producto cartesiano porque no es la operacin ms utilizada, ya que normalmente cuando
queramos componer dos tablas lo haremos con una condicin de seleccin basada en campos de combinacin y para este
caso es ms eficiente el JOIN que veremos a continuacin.
4.7. La composicin interna INNER JOIN
Una composicin interna es aquella en la que los valores de las columnas que se estn combinando se comparan mediante
un operador de comparacin.
Es otra forma, mejor, de expresar un producto cartesiano con una condicin.
Es la operacin que ms emplearemos ya que lo ms frecuente es querer juntar los registros de una tabla relacionada con
los registros correspondientes en la tabla de referencia (aadir a cada factura los datos de su cliente, aadir a cada lnea de
pedido los datos de su producto, etc..,).
FROM
<tabla_origen> INNER JOIN <tabla_origen> ON <condicion_combi>
tabla_origen tiene el mismo significado que en el producto cartesiano.
condicion_combi es cualquier condicin que permite seleccionar las parejas de filas que aparecen en el resultado.
Normalmente ser una condicin de igualdad.
SELECT *
FROM empleados INNER JOIN oficinas
ON empleados.oficina=oficinas.oficina;
Obtiene los empleados combinados con los datos de su oficina.
104
SELECT *
FROM pedidos INNER JOIN productos
ON producto = idproducto AND fab = idfab;
Obtiene los pedidos combinados con los productos correspondientes.
Normalmente la condicin de combinacin ser una igualdad pero se puede utilizar cualquier operador de comparacin (<>,
>).
Es fcil ver la utilidad de esta instruccin y de hecho se utilizar muy a menudo, pero hay algn caso que no resuelve. En las
consultas anteriores, no aparecen las filas que no tienen fila correspondiente en la otra tabla.
SELECT numemp,nombre,empleados.oficina, ciudad
FROM empleados INNER JOIN oficinas
ON empleados.oficina=oficinas.oficina;
numemp
nombre
oficina
ciudad
101
Antonio Viguer
12
Alicante
102
Alvaro Jaumes
21
Badajoz
103
Juan Rovira
12
Alicante
104
Jos Gonzlez
12
Alicante
105
Vicente Pantalla
13
Castelln
106
Luis Antonio
11
Valencia
107
Jorge Gutirrez
22
A Corua
108
Ana Bustamante
21
Badajoz
109
Mara Sunta
11
Valencia
No aparecen los empleados que no tienen oficina, ni las oficinas que no tienen empleados, porque para que salga la fila,
debe de existir una fila de la otra tabla que cumpla la condicin.
Para resolver este problema debemos utilizar otro tipo de composicin, la composicin externa.
4.8. La Composicin externa LEFT, RIGHT y FULL OUTER JOIN
La composicin externa se escribe de manera similar al INNER JOIN indicando una condicin de combinacin pero en el
resultado se aaden filas que no cumplen la condicin de combinacin.
105
Sintaxis
FROM
<tabla_origen> {LEFT|RIGHT|FULL} [OUTER] JOIN <tabla_origen>
ON <condicion_combi>
La palabra OUTER es opcional y no aade ninguna funcin.
Las palabras LEFT, RIGHT y FULL indican la tabla de la cual se van a aadir las filas sin correspondencia.
SELECT numemp,nombre,empleados.oficina, ciudad
FROM empleados LEFT JOIN oficinas
ON empleados.oficina=oficinas.oficina;
numemp
nombre
oficina
ciudad
101
Antonio Viguer
12
Alicante
102
Alvaro Jaumes
21
Badajoz
103
Juan Rovira
12
Alicante
104
Jos Gonzlez
12
Alicante
105
Vicente Pantalla
13
Castelln
106
Luis Antonio
11
Valencia
107
Jorge Gutirrez
22
A Corua
108
Ana Bustamante
21
Badajoz
109
Mara Sunta
11
Valencia
110
Juan Victor
NULL
NULL
106
nombre
oficina
ciudad
oficina
106
Luis Antonio
11
Valencia
11
109
Mara Sunta
11
Valencia
11
101
Antonio Viguer
12
Alicante
12
103
Juan Rovira
12
Alicante
12
104
Jos Gonzlez
12
Alicante
12
105
Vicente Pantalla
13
Castelln
13
102
Alvaro Jaumes
21
Badajoz
21
108
Ana Bustamante
21
Badajoz
21
107
Jorge Gutirrez
22
A Corua
22
NULL
NULL
NULL
Madrid
23
NULL
NULL
NULL
Aranjuez
24
NULL
NULL
NULL
Pamplona
26
NULL
NULL
NULL
Valencia
28
107
numemp
nombre
oficina
ciudad
oficina
101
Antonio Viguer
12
Alicante
12
102
Alvaro Jaumes
21
Badajoz
21
103
Juan Rovira
12
Alicante
12
104
Jos Gonzlez
12
Alicante
12
105
Vicente Pantalla
13
Castelln
13
106
Luis Antonio
11
Valencia
11
107
Jorge Gutirrez
22
A Corua
22
108
Ana Bustamante
21
Badajoz
21
109
Mara Sunta
11
Valencia
11
110
Juan Victor
NULL
NULL
NULL
NULL
NULL
NULL
Madrid
23
NULL
NULL
NULL
Aranjuez
24
NULL
NULL
NULL
Pamplona
26
NULL
NULL
NULL
Valencia
28
Aparecen tanto los empleados sin oficina como las oficinas sin empleados.
SELECT numemp,nombre,empleados.oficina, ciudad, oficinas.oficina
FROM empleados FULL OUTER JOIN oficinas
ON empleados.oficina=oficinas.oficina;
Es equivalente, la palabra OUTER como hemos dicho no aade ninguna funcionalidad y se utiliza si se quiere por
cuestiones de estilo.
NOTA: Cuando necesitamos obtener filas con datos de dos tablas con una condicin de combinacin utilizaremos un JOIN,
os aconsejo empezar por escribir el JOIN con la condicin que sea necesaria para combinar las filas, y luego plantearos si la
composicin debe de ser interna o externa. Para este segundo paso sta sera la norma a seguir:
108
Si pueden haber filas de la primera tabla que no estn relacionadas con filas de la segunda tabla y nos interesa que
salgan en el resultado, entonces cambiamos a LEFT JOIN.
Si pueden haber filas de la segunda tabla que no estn relacionadas con filas de la primera tabla y nos interesa que
salgan en el resultado, entonces cambiamos a RIGHT JOIN.
109
La diferencia entre una consulta de resumen y una consulta de las que hemos visto hasta ahora es que en las consultas
normales las filas del resultado se obtienen directamente de las filas del origen de datos y cada dato que aparece en el
resultado tiene su dato correspondiente en el origen de la consulta mientras que las filas generadas por las consultas de
resumen no representan datos del origen sino un total calculado sobre estos datos. Esta diferencia har que las consultas de
resumen tengan algunas limitaciones que veremos a lo largo del tema.
Un ejemplo sera:
A la izquierda tenemos una consulta simple que nos saca las oficinas con sus ventas ordenadas por regin, y a la derecha
una consulta de resumen que obtiene la suma de las ventas de las oficinas de cada regin
5.2. Las funciones de agregado
Una funcin de agregado SQL acepta un grupo de datos (normalmente una columna de datos) como argumento, y produce
un nico dato que resume el grupo. Por ejemplo la funcin AVG() acepta una columna de datos numricos y devuelve la
media aritmtica (average) de los valores contenidos en la columna.
El mero hecho de utilizar una funcin de agregado en una consulta, convierte sta en una consulta de resumen.
Todas las funciones de agregado tienen una estructura muy parecida:
Funcin ([ALL|DISTINCT] expression)
El grupo de valores sobre el que acta la funcin lo determina el resultado de la expresin que ser un nombre de columna o
una expresin basada en una columna o varias del origen de datos. En la expresin nunca puede aparecer una funcin de
agregado ni una subconsulta.
La palabra ALL indica que se tiene que tomar en cuenta todos los valores de la columna. Es el valor por defecto.
La palabra DISTINCT hace que se consideren todas las repeticiones del mismo valor como uno slo (considera valores
distintos).
Todas las funciones de agregado se aplican a las filas del origen de datos una vez ejecutada la clusula WHERE (si la
hubiera).
Si exceptuamos la funcin COUNT, todas las funciones de agregado ignoran los valores NULL.
110
Una funcin de agregado puede aparecer en la lista de seleccin en cualquier lugar en el que puede aparecer un nombre de
columna. Puede, por ejemplo, formar parte de una expresin pero no se pueden anidar funciones de agregado.
Tampoco se pueden mezclar funciones de columna con nombres de columna ordinarios. Hay excepciones a esta regla pero
cuando definimos agrupaciones y subconsultas que veremos ms adelante.
111
Las dos nos devuelven el nmero de empleados que tienen una oficina asignada pero la primera es mejor porque se calcula
ms rpidamente.
112
la
varianza
estadstica
de
la
poblacin
para
todos
los
valores
de
la
expresin
especificada.
Slo se puede utilizar con columnas numricas. Los valores NULL se pasan por alto.
113
114
GROUP BY oficina;
Resultado:
oficina Nmero de empleados
NULL
11
12
13
21
22
Hay empleados sin oficinas (con oficina a nulo), estos forman un grupo con el valor NULL en oficina, en este caso hay dos
empleados as.
Podemos indicar varias columnas de agrupacin.
Ejemplo:
SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo]
FROM pedidos
WHERE YEAR(fechapedido) = 1997
GROUP BY rep, clie
ORDER BY rep, clie;
Resultado:
rep clie
Nmero
Importe
de pedidos mximo
101 2113 1
225,00
102 2106 2
21,30
102 2120 1
37,50
115
103 2111 2
21,00
105 2103 4
275,00
105 2111 1
37,45
106 2101 1
14,58
107 2109 1
313,50
107 2124 2
24,30
108 2112 1
29,25
108 2114 1
71,00
108 2118 3
14,20
De cada representante obtenemos el nmero de pedidos y el importe mximo vendido a cada cliente, de las ventas de 1997.
La clusula ORDER BY se ha incluido para que las filas aparezcan ordenadas y quede ms claro.
Hemos dicho que los resmenes se calculan sobre todas las filas del origen despus de haber ejecutado el WHERE, pues
ALL permite obtener un resumen de las filas que no cumplen el WHERE.
ALL Incluye todos los grupos y conjuntos de resultados, incluso aquellos en los que no hay filas que cumplan la condicin de
bsqueda especificada en la clusula WHERE. Cuando se especifica ALL, se devuelven valores NULL para las columnas de
resumen de los grupos que no cumplen la condicin de bsqueda. No se puede especificar ALL con los operadores CUBE y
ROLLUP.
GROUP BY ALL no se admite en consultas que tienen acceso a tablas remotas si tambin hay una clusula WHERE en la
consulta.
Por ejemplo, vamos a modificar la consulta anterior:
SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo]
FROM pedidos
WHERE YEAR(fechapedido) = 1997
GROUP BY ALL rep, clie
ORDER BY rep, clie;
Resultado:
rep clie Nmero
Importe
116
de pedidos mximo
101 2102 0
NULL
101 2108 0
NULL
101 2113 1
225,00
102 2106 2
21,30
102 2120 1
37,50
103 2111 2
21,00
105 2103 4
275,00
105 2111 1
37,45
106 2101 1
14,58
106 2117 0
NULL
107 2109 1
313,50
107 2124 2
24,30
108 2112 1
29,25
108 2114 1
71,00
108 2118 3
14,20
Cul ha sido el efecto de aadir ALL? Se han aadido filas para las filas del origen que no cumplen la condicin del WHERE
pero sin que intervengan en el clculo de las funciones de agregado.
Por ejemplo el representante 101 tiene pedidos con el cliente 2102 pero estos pedidos no son del ao 1997, por eso aparece
la primera fila (no estaba en el resultado de la otra consulta) pero con 0 y NULL como resultados de las funciones de
agregado.
ROLLUP especifica que, adems de las filas que normalmente proporciona GROUP BY, se incluyen filas de resumen en el
conjunto de resultados. Los grupos se resumen en un orden jerrquico, desde el nivel inferior del grupo hasta el superior. La
jerarqua del grupo se determina por el orden en que se especifican las columnas de agrupamiento. Cambiar el orden de las
columnas de agrupamiento puede afectar al nmero de filas generadas en el conjunto de resultados.
117
Por ejemplo:
SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo]
FROM pedidos
WHERE YEAR(fechapedido) = 1997
GROUP BY rep, clie WITH ROLLUP;
Resultado:
Nmero
Importe
rep
clie
101
2113 1
225,00
101
NULL 1
225,00
102
2106 1
21,30
102
2120 1
37,50
102
NULL 3
37,50
103
2111 2
21,00
103
NULL 2
21,00
105
2103 4
275,00
105
2111 1
37,45
105
NULL 5
275,00
106
2101 1
14,28
106
NULL 1
14,28
107
2109 1
313,50
107
2124 2
24,30
107
NULL 3
313,50
de pedidos mximo
118
108
2112 1
29,25
108
2114 1
71,00
108
2118 3
14,20
108
NULL 5
71,00
...
...
...
...
NULL NULL 23
450,00
Efecto: Se han aadido automticamente subtotales por cada nivel de agrupamiento y una lnea de totales generales al final.
En este caso no hemos incluido ORDER BY porque las filas salen ya ordenadas.
CUBE especifica que, adems de las filas que normalmente proporciona GROUP BY, deben incluirse filas de resumen en el
conjunto de resultados. Se devuelve una fila de resumen GROUP BY por cada posible combinacin de grupo y subgrupo del
conjunto de resultados. En el resultado se muestra una fila de resumen GROUP BY como NULL, pero se utiliza para indicar
todos los valores.
Por ejemplo:
SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo]
FROM pedidos
WHERE YEAR(fechapedido) = 1997
GROUP BY rep, clie WITH CUBE;
Resultado:
Nmero
Importe
rep
clie
101
2113 1
225,00
101
NULL 1
225,00
102
2106 1
21,30
102
2120 1
37,50
102
NULL 3
37,50
de pedidos mximo
119
103
2111 2
21,00
103
NULL 2
21,00
105
2103 4
275,00
105
2111 1
37,45
105
NULL 5
275,00
106
2101 1
14,28
106
NULL 1
14,28
107
2109 1
313,50
107
2124 2
24,30
107
NULL 3
313,50
108
2112 1
29,25
108
2114 1
71,00
108
2118 3
14,20
108
NULL 5
71,00
...
...
...
...
NULL NULL 23
450,00
NULL 2101 1
14,58
NULL 2103 4
275,00
NULL 2106 2
21,30
NULL 2107 1
6,32
NULL 2108 1
56,25
120
NULL 2109 1
313,50
NULL 2111 3
37,45
NULL 2112 2
450,00
NULL 2113 1
225,00
NULL 2114 1
71,00
NULL 2118 3
14,20
NULL 2120 1
37,50
NULL 2124 2
24,30
Efecto: Obtenemos adems de los resultados obtenidos con ROLLUP (los totales por cada representante), los totales por el
otro criterio (los totales por cada cliente).
El nmero de filas de resumen del conjunto de resultados se determina mediante el nmero de columnas que contiene la
clusula GROUP BY. Cada operando (columna) de la clusula GROUP BY se enlaza segn el agrupamiento NULL y se
aplica el agrupamiento al resto de los operandos (columnas). CUBE devuelve todas las combinaciones posibles de grupo y
subgrupo.
Tanto si utilizamos CUBE como ROLLUP, nos ser til la funcin de agregado GROUPING.
Si cogemos por ejemplo la primera fila remarcada (101 NULL ) el valor NULL, no sabemos si se refiere a una fila de
subtotal o a que el representante 101 ha realizado un pedido sin nmero de cliente. Para poder salvar este problema se
utiliza la funcin de agregado GROUPING.
SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo], GROUPING(clie) AS
[Fila resumen]
FROM pedidos
WHERE YEAR(fechapedido) = 1997
GROUP BY rep, clie WITH ROLLUP;
rep clie
Nmero
Importe Fila
101 2113 1
225,00
101 NULL 1
225,00
121
102 2106 2
21,30
102 2120 1
37,50
102 NULL 3
37,50
103 2111 2
21,00
Las filas que corresponden a subtotales aparecen con un 1 y las normales con un cero.
Ahora que estamos ms familiarizados con las columnas de agrupamiento debemos comentar una regla a no olvidar:
EN LA LISTA DE SELECCIN DE UNA CONSULTA DE RESUMEN UN NOMBRE DE COLUMNA NO PUEDE APARECER
FUERA DE UNA FUNCIN DE AGREGADO SI NO ES UNA COLUMNA DE AGRUPACIN.
5.15. Seleccin sobre grupos de filas, la clusula HAVING
Cuando queremos incluir una clusula de seleccin sobre las filas del origen, utilizamos la clusula WHERE, pero cuando
estamos definiendo una consulta de resumen, no podemos utilizar esta clusula para seleccionar filas del resultado ya que
cada una de stas representa un grupo de filas de la tabla original. Para seleccionar filas del resumen tenemos la clusula
HAVING.
22
122
Esta SELECT es la misma que la del primer ejemplo del apartado sobre la clusula GROUP BY, la diferencia es que le
hemos aadido la clusula HAVING, que hace que del resultado slo se visualicen los grupos que cumplan la condicin. Es
decir slo aparecen las oficinas que tienen menos de 2 empleados.
Siempre que en una condicin de seleccin haya una funcin de columna, la condicin deber incluirse en la clusula
HAVING, adems, como HAVING filtra filas del resultado, slo puede contener expresiones (nombres de columnas,
expresiones, funciones) que tambin pueden aparecer en la lista de seleccin, por lo que tambin se aplica la misma regla
a no olvidar:
EN LA CLUSULA HAVING UN NOMBRE DE COLUMNA NO PUEDE APARECER FUERA DE UNA FUNCIN DE
AGREGADO SI NO ES UNA COLUMNA DE AGRUPACIN.
Las expresiones que pongamos en HAVING no tienen porqu aparecer en la lista de seleccin, por ejemplo en la SELECT
anterior se poda haber escrito:
HAVING SUM(ventas)=10000
123
Por cada fila de la tabla de empleados (de la consulta externa) se calcula la subconsulta y se evala la condicin, por lo que
utilizar una subconsulta puede en algunos casos ralentizar la consulta, en contrapartida se necesita menos memoria que
una composicin de tablas.
Muchas de las instrucciones Transact-SQL que incluyen subconsultas se pueden formular tambin utilizando composiciones
de tablas. Otras preguntas se pueden formular slo con subconsultas.
En Transact-SQL, normalmente no hay una regla fija en cuanto a diferencias de rendimiento entre una instruccin que
incluya una subconsulta y una versin semnticamente equivalente que no la incluya.
Podremos utilizar una subconsulta siempre y cuando no se quiera que aparezcan en el resultado columnas de la
subconsulta ya que si una tabla aparece en la subconsulta y no en la consulta externa, las columnas de esa tabla no se
pueden incluir en la salida (la lista de seleccin de la consulta externa).
Tenemos tres tipos de subconsultas:
Las que devuelven un solo valor, aparecen en la lista de seleccin de la consulta externa o con un operador de
comparacin sin modificar.
Las que generan una columna de valores, aparecen con el operador IN o con un operador de comparacin
modificado con ANY, SOME o ALL.
Las que pueden generar cualquier nmero de columnas y filas, son utilizadas en pruebas de existencia
especificadas con EXISTS.
124
FROM pedidos
WHERE rep = numemp);
125
La subconsulta devuelve una sola columna y como mucho una fila ya que es una consulta de resumen sin clusula GROUP
BY.
101
Antonio Viguer
45
12
30000,00 30500,00
103
Juan Rovira
29
23
27500,00 28600,00
104
Jos Gonzlez
33
23
dir ventas
1987-05-19 106
20000,00 14300,00
105
Vicente Pantalla 37
13
35000,00 36800,00
106
Luis Antonio
11
dir general
52
contrato
jefe
cuota
ventas
SELECT empleados.* FROM Empleados INNER JOIN oficinas ON empleados.oficina = oficinas.oficina WHERE region =
'Este';
126
Esta sentencia es equivalente. En el resultado no queremos ver ninguna columna de la tabla oficinas, el JOIN lo tenemos
slo para la pregunta, en este caso pues se puede sustituir por una subconsulta.
Si combinamos el operador IN con NOT obtenemos el operador NOT IN.
<expresion> NOT IN subconsulta
Devuelve TRUE si el valor de la expresin no est en la lista de valores devueltos por la subconsulta.
SELECT * FROM empleados WHERE oficina NOT IN (SELECT oficina FROM oficinas WHERE region = 'Este');
Devuelve los empleados cuya oficina no est en la lista generada por la subconsulta, es decir empleados que trabajan en
oficinas que no son del Este.
OJO con NOT IN.
Hay que tener especial cuidado con los valores nulos cuando utilizamos el operador NOT IN porque el resultado obtenido no
siempre ser el deseado por ejemplo:
* En la consulta anterior no salen los empleados que no tienen oficina ya que para esos empleados la columna oficina
contiene NULL por lo que no se cumple el NOT IN.
* Si la subconsulta no devuelve ninguna fila, la condicin se cumplir para todas las filas de la consulta externa, en este caso
todos los empleados.
* Si la subconsulta devuelve algn valor NULL, la condicin NOT IN es NULL lo que nos puede ocasionar algn problema.
Por ejemplo, queremos obtener las oficinas que no estn asignadas a ningn empleado.
SELECT *
FROM Oficinas
FROM empleados);
Esta consulta no devuelve ninguna fila cuando s debera ya que hay oficinas que nos estn asignadas a ningn empleado.
El problema est en que la columna oficina de la tabla empleados admite nulos por lo que la subconsulta devuelve valores
nulos en todos los empleados que no estn asignados a ninguna oficina. Estos valores nulos hacen que no se cumpla el
NOT IN. La solucin pasa por eliminar estos valores molestos:
SELECT *
FROM Oficinas
127
FROM empleados
FROM empleados
FROM pedidos
FROM empleados
128
FROM pedidos
dar
NULL.
FROM empleados
129
Con el modificador ALL, para que se cumpla la condicin, la comparacin se debe cumplir con cada uno de los valores
devueltos
por
la
subconsulta.
FROM empleados
130
FROM empleados
FROM pedidos
131
Obtenemos los empleados que tengan un pedido del fabricante ACI. Por cada empleado, se calcula la subconsulta
(obteniendo los pedidos de ese empleado y con fabricante ACI), si existe alguna fila, el empleado sale en el resultado, si no,
no sale.
Cuando se utiliza el operador EXISTS es muy importante aadir una referencia externa, no es obligatorio pero en la mayora
de los casos ser necesario. Vemoslo con ese mismo ejemplo, si quitamos la referencia externa:
SELECT *
FROM empleados
FROM pedidos
FROM empleados
FROM pedidos
132
con
instrucciones
de
Transact-SQL.
Seguimos en el DML porque las instrucciones que veremos actan sobre los datos de la base de datos no sobre su
definicin y tenemos tres tipos de operaciones posibles:
SELECT ...
INTO nb_NuevaTabla
FROM ...
nb_NuevaTabla es el nombre de la tabla que se va a crear, si en la base de datos ya hay una tabla con ese nombre, el
sistema genera un error y no se ejecuta la sentencia.
En la nueva tabla las columnas tendrn el mismo tipo y tamao que las columnas del resultado de la SELECT, se llamarn
con el nombre de alias de la columna o en su defecto con el nombre de la columna, pero no se transfiere ninguna otra
propiedad del campo o de la tabla como por ejemplo las claves e ndices.
Si retomamos el ejemplo del punto anterior:
FROM oficinas
133
INTO trabajo
FROM oficinas
orden
INSERT
(o
tambin
denominada
INSERT
INTO).
[(lista_columnas)]
|tabla_derivada
134
|DEFAULT VALUES
[;]
<destino> ::=
[nbBaseDatos.nbEsquema. | nbEsquema.]nbTablaVista
}
Con esta instruccin podemos insertar una fila de valores determinados o un conjunto de filas derivadas de otra consulta.
7.1. Introduccin
Hasta ahora hemos trabajado con tablas que tenan datos introducidos y cuando nos ha hecho falta hemos aadido nuevos
datos en las mismas y hemos modificado algn dato directamente desde el entorno de SSMS, en este tema veremos cmo
hacerlo
con
instrucciones
de
Transact-SQL.
Seguimos en el DML porque las instrucciones que veremos actan sobre los datos de la base de datos no sobre su
definicin y tenemos tres tipos de operaciones posibles:
SELECT ...
INTO nb_NuevaTabla
135
FROM ...
nb_NuevaTabla es el nombre de la tabla que se va a crear, si en la base de datos ya hay una tabla con ese nombre, el
sistema genera un error y no se ejecuta la sentencia.
En la nueva tabla las columnas tendrn el mismo tipo y tamao que las columnas del resultado de la SELECT, se llamarn
con el nombre de alias de la columna o en su defecto con el nombre de la columna, pero no se transfiere ninguna otra
propiedad del campo o de la tabla como por ejemplo las claves e ndices.
Si retomamos el ejemplo del punto anterior:
FROM oficinas
INTO trabajo
FROM oficinas
136
La insercin de nuevos datos en una tabla, se realiza aadiendo filas enteras a la tabla, la sentencia SQL que lo permite es
la
orden
INSERT
(o
tambin
denominada
INSERT
INTO).
[(lista_columnas)]
|tabla_derivada
|DEFAULT VALUES
[;]
<destino> ::=
[nbBaseDatos.nbEsquema. | nbEsquema.]nbTablaVista
137
Con esta instruccin podemos insertar una fila de valores determinados o un conjunto de filas derivadas de otra consulta.
7.4. Insertar una fila de valores
Para insertar una fila de valores utilizamos la sintaxis:
de
indicar
que
queremos
insertar,
debemos
indicar
dnde,
mediante
<destino>.
<destino> es el nombre de la tabla donde queremos insertar, puede ser un nombre de tabla o un nombre de vista.
Si utilizamos una vista, y sta tiene un origen basado en varias tablas, en su lista de seleccin debern aparecer columnas
de
una
Con
la
sola
clusula
tabla
VALUES
(no
podemos
indicamos
entre
insertar
parntesis
datos
los
en
valores
varias
a
insertar,
tablas
la
vez).
separados
por
comas.
mediante la palabra reservada DEFAULT que indica valor por defecto en este caso la columna se rellenar con el
valor predeterminado de la columna, si la columna no tiene DEFAULT se sustituir por el valor nulo NULL.
Delante de VALUES, de forma opcional podemos indicar una lista de columnas entre parntesis. Las columnas son
columnas
del
destino.
Cuando indicamos nombres de columnas, esas columnas sern las que reciban los valores a insertar, la asignacin de
valores se realiza por posicin, la primera columna recibe el primer valor, la segunda columna el segundo, y as
sucesivamente.
En la lista, las columnas pueden estar en cualquier orden y tambin se pueden omitir algunas columnas.
Una columna que no aparezca en la lista de columnas se rellenar de acuerdo a su definicin:
Cuando no se indica una lista de columnas el sistema asume por defecto todas las columnas de la tabla y en el mismo orden
que aparecen en la definicin de la tabla, en este caso, los valores se tienen que especificar en el mismo orden que las
columnas en la definicin de la tabla, y se tiene que especificar un valor por cada columna ya que los valores se rellenan por
posicin, la primera columna recibe el primer valor, la segunda columna el segundo, y as sucesivamente.
138
En cualquier caso, el nmero de valores debe coincidir con el nmero de columnas y los tipos de dato de los valores deben
ser compatibles con las columnas.
Aunque pueda parecer ms engorroso escribir la lista de columnas, es un hbito recomendable, hace que la sentencia sea
ms fcil de leer y mantener (cuando leemos la sentencia sabemos en qu columnas asignamos los valores sin necesidad
de consultar la definicin de la tabla) y evita que se tenga que cambiar la sentencia si se modifica el esquema de la tabla (si
el orden de las columnas dentro de la tabla cambia).
Los registros se agregan al final de la tabla.
Cuando se insertan nuevas filas en una tabla, el sistema comprobar que la nueva fila no infrinja ninguna regla de
integridad, por ejemplo no podremos asignar a una columna PRIMARY KEY un valor nulo o que ya exista en la tabla, a una
columna UNIQUE un valor que ya exista en la tabla, a una columna NOT NULL un valor NULL, a una clave ajena (FOREIGN
KEY)
un
valor
que
no
exista
en
la
tabla
de
referencia.
De producirse alguna de las situaciones anterior, la instruccin genera un mensaje de error y la fila no se inserta.
Ejemplos.
En este caso hemos indicado slo dos columnas y dos valores, las dems columnas se rellenan con el valor por defecto si lo
tiene (DEFAULT) o con NULL. Si alguna columna no nombrada no admite nulos ni tiene clusula DEFAULT definida, la
instruccin dar error.
tabla_derivada [;]
139
FROM oficinas
FROM oficinas
FROM oficinas
140
[;]
Hace
que
la
Hay
que
Puede
generar
nueva
tener
filas
fila
en
contenga
cuenta
duplicadas
en
los
una
la
tabla
valores
serie
si
los
predeterminados
de
aspectos
valores
que
se
definidos
al
generan
para
utilizar
son
cada
esta
siempre
columna.
instruccin:
los
mismos.
Si la tabla tiene una clave principal, esta tendr que estar basada en una columna con la propiedad IDENTITY para que se
generen
valores
diferentes
automticamente.
Si una columna est definida como NOT NULL tendr que incluir un DEFAULT o ser una columna calculada con una
expresin compatible.
7.7. Modificar datos almacenados - UPDATE
La sentencia UPDATE modifica los valores de una o ms columnas en las filas seleccionadas de una nica tabla.
Para modificar los datos de una tabla es necesario disponer del privilegio UPDATE sobre dicha tabla.
UPDATE
<destino>
} [ ,...n ]
141
[ FROM{ <origen> }]
[ WHERE <condicion> ]
[;]
<destino> ::=
[nbBaseDatos.[nbEsquema.]| nbEsquema.]nbTablaVista
Con
<destino>
indicamos
la
tabla
que
se
va
actualizar.
La clusula SET especifica qu columnas van a modificarse y con qu valor, el valor se puede expresar mediante una
expresin, la palabra DEFAULT que equivale al valor predeterminado de la columna, o el valor nulo NULL.
Las
columnas
de
identidad
no
se
pueden
actualizar.
Expresin en cada asignacin debe generar un valor del tipo de dato apropiado para la columna indicada. La expresin
debe ser calculable basada en los valores de la fila actualmente en actualizacin. Si para el clculo se utiliza una columna
que tambin se modifica, el valor que se utilizar es el de antes de la modificacin, lo mismo para la condicin del WHERE.
Expresin tambin puede ser una subconsulta siempre y cuanto devuelva un nico valor y cumpla las condiciones
anteriormente expuestas.
Por ejemplo:
Actualiza
todas
las
filas
de
la
tabla
oficinas
dejando
el
campo
ventas
con
el
valor
cero.
Si el campo ventas est definido con un valor predeterminado 0, la sentencia anterior equivale a:
142
En una misma sentencia podemos actualizar varias columnas, slo tenemos que indicar las distintas asignaciones
separadas por comas:
Especifica
el
nmero
porcentaje
de
filas
aleatorias
que
se
van
modificar.
expression debe generar un valor numrico e indica el nmero de filas a modificar empezando por el principio. Como en la
SELECT, si aadimos la palabra PERCENT, el nmero representado por expresin se refiere al porcentaje de filas a
modificar sobre el total. La clusula TOP funciona casi igual que en la SELECT pero en este caso, las filas no se ordenan, y
la expresin debe ir entre parntesis.
Por ejemplo:
SET ventas = 0;
Actualiza el 10% de filas de la tabla oficinas.
[ WHERE <condicion> ]
Utilizamos la clusula WHERE para filtrar las filas a actualizar. Se actualizarn todas las filas que cumplan la condicin. Por
ejemplo si queremos actualizar slo las oficinas del Este:
UPDATE oficinas
143
SET ventas = 0
FROM oficinas
ningn
registro.
Cuando una instruccin UPDATE encuentra un error aritmtico (error de desbordamiento, divisin por cero o de dominio)
durante la evaluacin de la expresin, la actualizacin no se lleva a cabo. El resto del lote no se ejecuta y se devuelve un
mensaje de error.
Adems del permiso de UPDATE, se requieren permisos SELECT para la tabla que se actualiza si la instruccin UPDATE
contiene una clusula WHERE o en el caso de que el argumento expression de la clusula SET utilice una columna de la
tabla, y permisos SELECT para la tabla del origen si utilizamos una clusula FROM o un WHERE con subconsulta.
144
DELETE
[ FROM <origen>]
[; ]
<destino> ::=
}
Con esta instruccin podemos eliminar una o varias filas de una tabla.
La palabra FROM (la primera) es opcional (originalmente era obligatorio) y no aade funcionalidad slo sirve para introducir
el
destino.
<destino> es el nombre de la tabla de donde queremos eliminar las filas, puede ser un nombre de tabla o un nombre de vista
(de
momento
basada
en
una
slo
tabla).
La segunda clusula FROM sirve para indicar un origen que permita una condicin de WHERE sobre una tabla diferente de
destino.
La instruccin bsica sera pues:
DELETE oficinas;
145
Equivalente a:
DELETE oficinas
el
nmero
porcentaje
de
filas
aleatorias
que
se
van
eliminar.
expression debe generar un valor numrico e indica el nmero de filas a eliminar empezando por el principio. Como en la
SELECT, si aadimos la palabra PERCENT, el nmero representado por expresin se refiere al porcentaje de filas a eliminar
sobre el total. La clusula TOP funciona casi igual que en la SELECT pero en este caso, las filas no se ordenan, y la
expresin debe ir entre parntesis.
Por ejemplo:
FROM oficinas;
Elimina el 10% de filas de la tabla oficinas.
Originalmente slo se poda indicar una tabla en la clusula FROM, pero ahora podemos indicar un origen basado en varias
tablas.
Si utilizamos un origen basado en varias tablas, se debe de utilizar una extensin de TRANSACT-SQL que consiste en
escribir dos clusulas FROM, una indica la tabla de donde eliminamos las filas y la otra el origen que utilizamos para
eliminar.
Este caso se produce cuando las filas a eliminar dependen de un valor que est en otra tabla. Por ejemplo queremos
eliminar los empleados de las oficinas del Este. Como la regin de la oficina no est en empleados, habra que aadir al
origen la tabla oficinas para poder formular la condicin del WHERE:
146
ON empleados.oficina = oficinas.oficina
FROM oficinas
TRUNCATE TABLE
147
[nbBaseDatos.[nbEsquema.]| nbEsquema.]nbTabla [; ]
Esta sentencia quita todas las filas de una tabla sin registrar las eliminaciones individuales de filas. Desde un punto de vista
funcional, TRUNCATE TABLE es equivalente a la instruccin DELETE sin una clusula WHERE; no obstante, TRUNCATE
TABLE es ms rpida y utiliza menos recursos de registros de transacciones y de sistema.
En comparacin con la instruccin DELETE, TRUNCATE TABLE ofrece las siguientes ventajas:
Se
utiliza
menos
espacio
del
registro
de
transacciones.
La instruccin DELETE quita una a una las filas y graba una entrada en el registro de transacciones por cada fila
eliminada.
TRUNCATE TABLE quita los datos al cancelar la asignacin de las pginas de datos utilizadas para almacenar los
datos de la tabla y slo graba en el registro de transacciones las cancelaciones de asignacin de pginas.
Por
regla
general,
se
utilizan
menos
bloqueos.
Si se ejecuta la instruccin DELETE con un bloqueo de fila, se bloquea cada fila de la tabla para su eliminacin.
TRUNCATE TABLE siempre bloquea la tabla y la pgina, pero no cada fila.
Las
pginas
cero
se
conservan
en
la
tabla
sin
excepciones.
Despus de ejecutar una instruccin DELETE, la tabla puede seguir conteniendo pginas vacas. Por ejemplo, no se
puede cancelar la asignacin de las pginas vacas de un montn sin un bloqueo de tabla exclusivo como mnimo.
Si en la operacin de eliminacin no se utiliza un bloqueo de tabla, la tabla contiene muchas pginas vacas. En el
caso de los ndices, la operacin de eliminacin puede dejar pginas vacas, aunque la asignacin de estas pginas
se puede cancelar rpidamente mediante un proceso de limpieza en segundo plano.
Si la tabla contiene una columna de identidad, el contador para dicha columna se restablece al valor de inicializacin definido
para ella. Si no se define ningn valor de inicializacin, se utiliza el valor predeterminado 1. Para conservar el contador de
identidad, se utiliza DELETE.
Pero no todo son ventajas, no se puede utilizar TRUNCATE TABLE en las siguientes tablas:
Tablas a las que se hace referencia mediante una restriccin FOREIGN KEY (las tablas que entran como principales
en una relacin).
datos.
La definicin de la estructura de la base de datos incluye tanto la creacin inicial de los diferentes objetos que formarn la
base de datos, como el mantenimiento de esa estructura. Las sentencias del DDL utilizan unos verbos que se repiten para
los distintos objetos. Por ejemplo para crear un objeto nuevo el verbo ser CREATE y a continuacin el tipo de objeto a
crear. CREATE DATABASE es la sentencia para crear una base de datos, CREATE TABLE nos permite crear una nueva
148
tabla, CREATE INDEX crear un nuevo ndice Para eliminar un objeto utilizaremos el verbo DROP (DROP TABLE, DROP
INDEX) y para modificar algo de la definicin de un objeto ya creado utilizamos el verbo ALTER (ALTER TABLE, ALTER
INDEX).
Los objetos que veremos en este tema son:
Bases de datos
Tablas
Vistas
ndices
Como ya hemos comentado, las sentencias DDL estn ms orientadas al administrador de la base de datos, es el que ms
las va a utilizar, el programador tiene que conocer cuestiones relativas a la estructura interna de una base de datos, pero no
tiene que ser experto en ello por lo que el estudio del tema se centrar en las sentencias y sobre todo en las clusulas que
pensamos pueden ser tiles a un programador y no entraremos en mucho detalle en cuanto a la estructura fsica de la base
de datos y en la administracin de la misma.
8.2. Definir una base de datos CREATE DATABASE
Estructura interna
Como ya vimos en el primer tema, las bases de datos de SQL Server 2005 utilizan tres tipos de archivos:
[ ON
[ , <grupo> [ ,...n ] ]
149
[ COLLATE nbintercalacion]
[ WITH <external_access_option> ]
[;]
Como vemos la instruccin mnima es:
CREATE DATABASE nbBasedeDatos
nbBasedeDatos: Es el nombre de la nueva base de datos. Los nombres de base de datos deben ser nicos en una instancia
de SQL Server y cumplir las reglas de los identificadores. Puede tener 128 caracteres como mximo, excepto en un caso
que veremos ms adelante.
Con la clusula ON especificamos los ficheros utilizados para almacenar los archivos de datos.
[ ON
[ , <grupo> [ ,...n ] ]
<esp_fichero> ::=
NAME = nbfichero_logico ,
FILENAME = 'nbfichero_fisico'
[ , SIZE = tamao [ KB | MB | GB | TB ] ]
150
[ , FILEGROWTH = incremento_crecimiento [ KB | MB | GB | TB | % ] ]
)
nbfichero_logico es el nombre que se utiliza para hacer referencia al archivo en todas las instrucciones Transact-SQL. El
nombre de archivo lgico tiene que cumplir las reglas de los identificadores de SQL Server y tiene que ser nico entre los
nombres de archivos lgicos de la base de datos.
nbfichero_fisico es el nombre del archivo fsico que incluye la ruta de acceso al directorio. Debe seguir las reglas para
nombres de archivos del sistema operativo.
Con
la
clusula
SIZE
indicamos
el
tamao
original
del
archivo.
Los archivos de SQL Server 2005 pueden crecer automticamente a partir del tamao originalmente especificado. Con
FILEGROWTH se puede especificar un incremento de crecimiento y cada vez que se llena el archivo, el tamao aumentar
en la cantidad especificada.
Cada archivo tambin puede tener un tamao mximo especificado con MAXSIZE. Si no se especifica un tamao mximo,
el archivo puede crecer hasta utilizar todo el espacio disponible en el disco. Esta caracterstica es especialmente til cuando
SQL Server se utiliza como una base de datos incrustada en una aplicacin para la que el usuario no dispone fcilmente de
acceso a un administrador del sistema. El usuario puede dejar que los archivos crezcan automticamente cuando sea
necesario y evitar as las tareas administrativas de supervisar la cantidad de espacio libre en la base de datos y asignar ms
espacio manualmente.
Si no se especifica un nombre de archivo de datos, SQL Server utiliza el nombre de la base de datos como nbfichero_logico
y nbfichero_fisico.
Si queremos definir varios archivos de datos, despus de la palabra ON escribiremos las definiciones de cada archivo
separadas por comas.
PRIMARY especifica que la lista de archivos asociada define el grupo de archivos principal, y el primer archivo especificado
se
convierte
en
el
archivo
de
datos
principal.
Si no se especifica PRIMARY, el primer archivo enumerado en la instruccin CREATE DATABASE se convierte en el archivo
principal.
Detrs de la lista de archivos del grupo de archivos principal, con <grupo> se puede colocar una lista opcional de
elementos separados por comas que definan los grupos de archivos de usuario y sus archivos.
<grupo> ::=
151
<esp_fichero> [ ,...n ]
}
Nbgrupo es el nombre del grupo y a continuacin indicamos los archivos de datos que pertenecen a ese grupo, los archivos
pertenecientes
al
grupo
se
indican
con
los
del
grupo
principal.
DEFAULT
Cambia el grupo de archivos predeterminado de la base de datos a Nbgrupo. Slo un grupo de archivos de la base de datos
puede ser el grupo de archivos predeterminado.
Con la clusula LOG ON definiremos los archivos utilizados para almacenar el registro de la base de datos (los archivos de
registro).
de
la
clusula
datos
COLLATE
podemos
un
cambiar
la
intercalacin
sufijo.
predeterminada.
La intercalacin define:
La pgina de cdigos usada para almacenar datos de caracteres que no son Unicode.
La sintaxis es la siguiente:
COLLATE <nbintercalacion>
nbinterWindows_ CaseSensitivity_AccentSensitivity
nbinterWindows: Es un nombre de intercalacin de Windows. Visita el siguiente bsico para saber ms sobre las
intercalaciones.
CaseSensitivity: Especifica que s se distingue entre maysculas y minsculas (CS), o no (CI). SQL Server Mobile slo
152
admite
esta
opcin.
AccentSensitivity: Especifica si se distinguen los caracteres acentuados (AS), o no (AI). SQL Server Mobile slo admite la
opcin
AS.
FOR.
Existen otras clusulas a nivel de administracin de la base de datos que no detallaremos aqu como son:
[ WITH <external_access_option> ]
<external_access_option> ::=
DB_CHAINING { ON | OFF }
| TRUSTWORTHY { ON | OFF }
}
Para controlar el acceso externo a la base de datos y desde sta.
ON <esp_fichero> [ ,...n ]
| ATTACH_REBUILD_LOG }
[;]
<service_broker_option> ::=
153
ENABLE_BROKER
| NEW_BROKER
| ERROR_BROKER_CONVERSATIONS
}
Para adjuntar una base de datos.
ON
NAME = nbfichero_logico ,
FILENAME = 'nbfichero_fisico'
) [ ,...n ]
AS SNAPSHOT OF nbBaseDatos_origen
[;]
Para crear una instantnea de base de datos (copia de slo lectura de una base de datos).
154
[DATABASEPASSWORD 'database_password'
[ENCRYPTION {ON|OFF}]
base
de
datos
puede
ser
una
base
de
datos
normal
una
instantnea
de
base
de
datos.
Para poder ejecutar la sentencia el usuario debe tener permiso de CONTROL y se debe de ejecutar en un contexto diferente
del de la base de datos a eliminar, por ejemplo:
use b1
DROP DATABASE b1
Falla porque con el use estamos en el contexto de la base de datos a eliminar.
Como se ve en la sintaxis podemos eliminar varias bases de datos con una sla sentencia DROP DATABASE.
Por ejemplo:
155
una
transaccin
explcita
implcita.
Las instantneas de bases de datos no se pueden modificar, y para modificar las opciones de base de datos asociadas a la
rplica, se utiliza el procedimiento almacenado del sistema sp_replicationdboption.
Sintaxis:
<cambiar_ficheros>
| <cambiar_grupos>
| <opciones>
| COLLATE nbintercalacin
[;]
156
Con esta sentencia resumida vemos que nos permite cambiar la definicin de la base de datos, nos va a permitir cambiar la
definicin de los ficheros que conforman la base de datos, tambin nos permite cambiar la definicin de los grupos, la
definicin de varias opciones, el tipo de intercalacin e incluso cambiar el nombre de la base de datos (con la clusula
MODIFY NAME).
Por ejemplo:
sin
entrar
en
demasiados
detalles
de
administracin.
Como muchas de las palabras ya las hemos explicado con la sentencia CREATE DATABASE, slo insistiremos en lo nuevo.
<cambiar_ficheros>::=
}
Con este grupo de opciones podemos cambiar la definicin de los archivos de datos de la base de datos.
ADD FILE permite aadir un nuevo archivo de datos (o varios) si no se aade nada (o TO FILEGROUP DEFAULT), el
archivo se aadir al grupo principal, si aadimos TO FILEGROUP nbgrupo, se aadir el archivo al grupo indicado.
157
Con
ADD
LOG
Con
REMOVE
FILE
FILE
podemos
nbfichero
aadir
eliminamos
un
nuevo
el
archivo
archivo
con
de
nombre
registro.
nbfichero.
Se elimina la definicin del archivo lgico (nbfichero) y elimina el archivo fsico asociado. El archivo no se puede quitar a
menos que est vaco.
Con MODIFY FILE <esp_fichero> podemos cambiar las especificaciones de alguno de los archivos de la base de datos.
<esp_fichero>::=
NAME = nbarchivo
[ , NEWNAME = nuevo_nbarchivo ]
[ , FILENAME = 'nbarchivo_fisico' ]
[ , SIZE = tamao [ KB | MB | GB | TB ] ]
[ , OFFLINE ]
)
Slo
NAME
se
se
puede
debe
cambiar
especificar
siempre
una
para
propiedad
identificar
<especificacinDeArchivo>
el
archivo
que
se
cada
va
vez.
modificar.
Si se especifica SIZE, el nuevo tamao debe ser mayor que el tamao actual del archivo. Para reducir el tamao de una
base de datos, se utiliza el comando de consola SHRINKDATABASE de Transact_SQL.
Para modificar el nombre lgico de un archivo de datos o de un archivo de registro, especificamos el nombre lgico nuevo
para el archivo en la clusula NEWNAME. Por ejemplo:
158
FILENAME = 'nueva_ruta/nb_fichero_fsico')
La clusula OFFLINE establece el archivo sin conexin e impide el acceso a todos los objetos del grupo de archivos. Muy
importante!, esta opcin slo se debe de utilizar si el archivo est daado y si se puede restaurar. Un archivo establecido en
OFFLINE slo se puede restablecer con conexin mediante la restauracin del archivo a partir de una copia de seguridad.
Para obtener ms informacin acerca de cmo restaurar un solo archivo, consultar en la ayuda la sentencia RESTORE
(Transact-SQL).
UNLIMITED especifica que el tamao del archivo aumenta hasta que el disco est lleno. En SQL Server 2005, un archivo de
registro especificado con un aumento ilimitado tiene un tamao mximo de 2 TB y un archivo de datos tiene un tamao
mximo de 16 TB.
En cuanto a la modificacin de la definicin de grupos, tenemos esta sintaxis:
<cambiar_grupos>::=
159
{ READONLY | READWRITE }
| { READ_ONLY | READ_WRITE }
| DEFAULT
}
Con
ADD
Con
FILEGROUP
REMOVE
nbgrupo
FILEGROUP
aadimos
nbgrupo
un
nuevo
eliminamos
grupo
el
de
archivos
grupo
de
de
la
la
base
base
de
de
datos.
datos.
El grupo de archivos no se puede quitar a menos que est vaco. Para quitar todos los archivos del grupo, primero se
mueven
los
archivos
otro
grupo,
si
los
archivos
estn
vacos,
se
pueden
eliminar
directamente.
No se produce ningn bloqueo en las bases de datos de slo lectura. Esto puede acelerar el rendimiento de las
consultas.
Para
cambiar
El
grupo
este
de
estado,
archivos
se
debe
principal
tener
acceso
no
exclusivo
puede
ser
la
de
base
slo
de
datos.
lectura.
160
Se puede utilizar indistintamente la palabra clave READONLY o READ_ONLY, pero READONLY se quitar en una versin
futura de Microsoft SQL Server por lo que se recomienda READ_ONLY.
READ_WRITE | READWRITE Especifica que el grupo es de lectura y escritura por lo que pueden realizarse actualizaciones
en
los
Para
cambiar
objetos
este
estado
se
del
debe
tener
grupo
acceso
exclusivo
de
a
la
archivos.
base
de
datos.
Se puede utilizar indistintamente la palabra clave READWRITE o READ_ WRITE, pero READWRITE se quitar en una
versin futura de Microsoft SQL Server por lo que se recomienda READ_WRITE.
Nota. El estado de estas opciones se puede determinar mediante el examen de la columna is_read_only de la vista de
catlogo sys.databases o la propiedad Updateability de la funcin DATABASEPROPERTYEX.
Para finalizar tenemos el apartado <opciones> que nos permite definir y/o cambiar muchas opciones de la base de datos.
La lista de opciones es muy larga, como podemos observar a continuacin, y no entraremos en detalles.
<opciones>::=
SET
<optionspec>::=
<db_state_option>
161
| <db_user_access_option>
| <db_update_option> | <external_access_option>
| <cursor_option>
| <auto_option>
| <sql_option>
| <recovery_option>
| <database_mirroring_option>
| <supplemental_logging_option>
| <service_broker_option>
| <date_correlation_optimization_option>
| <parameterization_option>
<db_state_option> ::=
<db_user_access_option> ::=
162
<db_update_option> ::=
{ READ_ONLY | READ_WRITE }
<external_access_option> ::=
DB_CHAINING { ON | OFF }
| TRUSTWORTHY { ON | OFF }
<cursor_option> ::=
{ CURSOR_CLOSE_ON_COMMIT { ON | OFF }
<auto_option> ::=
AUTO_CLOSE { ON | OFF }
| AUTO_CREATE_STATISTICS { ON | OFF }
163
| AUTO_SHRINK { ON | OFF }
| AUTO_UPDATE_STATISTICS { ON | OFF }
| AUTO_UPDATE_STATISTICS_ASYNC { ON | OFF }
<sql_option> ::=
ANSI_NULL_DEFAULT { ON | OFF }
| ANSI_NULLS { ON | OFF }
| ANSI_PADDING { ON | OFF }
| ANSI_WARNINGS { ON | OFF }
| ARITHABORT { ON | OFF }
| CONCAT_NULL_YIELDS_NULL { ON | OFF }
| NUMERIC_ROUNDABORT { ON | OFF }
| QUOTED_IDENTIFIER { ON | OFF }
| RECURSIVE_TRIGGERS { ON | OFF }
164
<recovery_option> ::=
| TORN_PAGE_DETECTION { ON | OFF }
{ <partner_option> | <witness_option> }
<partner_option> ::=
PARTNER { = 'partner_server'
| FAILOVER
| FORCE_SERVICE_ALLOW_DATA_LOSS
| OFF
| RESUME
165
| SUSPEND
| TIMEOUT integer
<witness_option> ::=
WITNESS { = 'witness_server'
| OFF
<supplemental_logging_option> ::=
SUPPLEMENTAL_LOGGING { ON | OFF }
<service_broker_option> ::=
ENABLE_BROKER
| DISABLE_BROKER
166
| NEW_BROKER
| ERROR_BROKER_CONVERSATIONS
<date_correlation_optimization_option> ::=
DATE_CORRELATION_OPTIMIZATION { ON | OFF }
<parameterization_option> ::=
<termination> ::=
| ROLLBACK IMMEDIATE
167
| NO_WAIT
}
Se pueden ver ms detalles de estas opciones en la ayuda de SQL SERVER buscando ALTER DABATABASE
8.5. Crear una tabla CREATE TABLE
Para
crear
una
nueva
tabla
se
emplea
la
sentencia
CREATE
TABLE.
Se necesita el permiso CREATE TABLE en la base de datos y el permiso ALTER en el esquema en que se crea la tabla.
Si las columnas de la instruccin CREATE TABLE se definen como un tipo definido por el usuario CLR, se necesita la
propiedad
del
tipo
el
permiso
REFERENCES.
Si las columnas de la instruccin CREATE TABLE tienen una coleccin de esquemas XML asociada, se necesita la
propiedad de la coleccin de esquemas XML o el permiso REFERENCES.
Empezaremos por una sintaxis reducida:
CREATE TABLE
[ nbBaseDatos.[nbEsquema].| nbEsquema.]nbTabla
[ <restriccion_tabla> ] [ ,...n ] )
[;]
nbBaseDatos Es el nombre de la base de datos en la que se crea la tabla. Debe ser el nombre de una base de datos
existente. Si no se especifica nbBaseDatos, se utiliza de manera predeterminada la base de datos actual. El inicio de sesin
de la conexin actual debe estar asociado a un Id. de usuario existente en la base de datos especificada por nbBaseDatos, y
ese
Id.
nbEsquema
de
Es
el
usuario
nombre
debe
del
tener
esquema
al
permisos
que
CREATE
pertenece
la
TABLE.
nueva
tabla.
nbTabla Es el nombre de la nueva tabla. Los nombres de tablas deben seguir las reglas de los identificadores.
nbTabla puede contener un mximo de 128 caracteres excepto para los nombres de tablas temporales locales (nombres
precedidos
por
un
nico
signo
de
nmero
(#))
que
no
pueden
superar
los
116
caracteres.
Despus de indicar el nombre de la tabla, entre parntesis definimos, separadas por una coma, cada una de las columnas
de la tabla y al final las restricciones a nivel de tabla si las hay.
Definir columnas fsicas
168
nbCol <tipo_dato>
[ COLLATE nbIntercalacion ]
[ ROWGUIDCOL ]
[ <restriccion_columna> [ ...n ] ]
Como mnimo debemos indicar el nombre de la columna nbCol y su tipo de datos.
Los nombres de columnas deben seguir las reglas de los identificadores y deben ser nicos en la tabla. nbCol puede
contener de 1 a 128 caracteres. nbCol se puede omitir en las columnas creadas con un tipo de datos timestamp, en tal
caso, si no se especifica nbCol, el nombre de la columna timestamp ser de manera predeterminada timestamp.
En cuanto al tipo de dato, esta es la sintaxis:
<tipo_dato> ::=
[nbEsquema_tipo. ] nbtipo
169
nbEsquema_tipo.
nbtipo
nbtipo Especifica el tipo de datos de la columna y nbEsquema_tipo el esquema al que pertenece el tipo. El tipo de datos
puede ser uno de los siguientes:
Un tipo de datos del sistema de SQL Server 2005 como los que ya conocemos.
Un tipo de alias basado en un tipo de datos del sistema de SQL Server. Los tipos de datos de alias se crean con la
instruccin CREATE TYPE para poder utilizarlos en una definicin de tabla. La asignacin NULL o NOT NULL de un
tipo de datos de alias puede anularse durante la instruccin CREATE TABLE. No obstante, la especificacin de
longitud no se puede cambiar; la longitud del tipo de datos de alias no se puede especificar en una instruccin
CREATE TABLE.
Un tipo definido por el usuario CLR. Los tipos definidos por el usuario CLR se crean con la instruccin CREATE
TYPE para poder utilizarlos en una definicin de tabla.
Si no se especifica el parmetro nbEsquema_tipo, el SQL Server Database Engine (Motor de base de datos de SQL Server)
hace referencia a nbtipo en el siguiente orden:
hora,
cadenas
binarias,
etc.
SQL Server proporciona un conjunto de tipos de datos del sistema que define todos los tipos de datos que pueden utilizarse
con SQL Server. Tambin podemos definir nuestros propios tipos de datos en Transact-SQL o Microsoft .NET Framework.
Los tipos de datos de alias estn basados en los tipos de datos proporcionados por el sistema. Para obtener ms
informacin acerca de los tipos de datos de alias, vea Trabajar con tipos de datos de alias. Los tipos definidos por el usuario
obtienen sus caractersticas de los mtodos y los operadores de una clase que se crean mediante uno de los lenguajes de
programacin compatibles con .NET Framework. Para obtener ms informacin, vea Trabajar con tipos definidos por el
usuario
para
CLR.
170
Cuando dos expresiones que tienen tipos de datos, intercalaciones, precisin, escala o longitud diferentes son combinadas
por un operador, las caractersticas del resultado vienen determinadas por lo siguiente:
El tipo de datos del resultado viene determinado por la aplicacin de las reglas de precedencia de tipos de datos a
los tipos de datos de las expresiones de entrada. Para obtener ms informacin, vea Prioridad de tipo de datos
(Transact-SQL).
La intercalacin del resultado viene determinada por las reglas de precedencia de intercalacin cuando el tipo de
datos del resultado es char, varchar, text, nchar, nvarchar o ntext. Para obtener ms informacin, vea Prioridad
de intercalacin (Transact-SQL).
La precisin, escala y longitud del resultado dependen de la precisin, escala y longitud de las expresiones de
entrada. Para obtener ms informacin, vea Precisin, escala y longitud (Transact-SQL).
SQL Server 2005 proporciona sinnimos de tipos de datos para la compatibilidad con SQL-92. Para obtener ms
informacin, vea Sinnimos de tipos de datos (Transact-SQL).
Categoras de tipos de datos
Los tipos de datos de SQL Server 2005 se organizan en las siguientes categoras:
Numricos exactos
Cadenas de caracteres
En SQL Server 2005, segn las caractersticas de almacenamiento, algunos tipos de datos estn designados como
pertenecientes a los siguientes grupos:
Tipos de datos de objetos grandes: text, ntext, image, varchar(max), nvarchar(max), varbinary(max) y xml
Nota: sp_help devuelve -1 como la longitud del valor de gran tamao y de los tipos de datos xml.
Numricos exactos
bigint
decimal
int
numeric
smallint money
tinyint
smallmoney
171
bit
Numricos aproximados
float real
Fecha y hora
datetime smalldatetime
Cadenas de caracteres
char
text
varchar
Cadenas de caracteres Unicode
nchar
ntext
nvarchar
Cadenas binarias
binary
image
varbinary
Otros tipos de datos
cursor
timestamp
sql_variant uniqueidentifier
table
xml
172
Binary varying
varbinary
char varying
varchar
character
char
character
char(1)
character(n)
char(n)
character varying(n)
varchar(n)
Dec
decimal
Double precision
float
real
float
integer
int
national character(n)
nchar(n)
national char(n)
nchar(n)
nvarchar(n)
national text
ntext
rowversion
timestamp
Los sinnimos de tipos de datos pueden utilizarse en lugar del nombre del tipo de datos base correspondiente en las
instrucciones del lenguaje de definicin de datos (DDL), como CREATE TABLE, CREATE PROCEDURE o DECLARE
@variable. Sin embargo, los sinnimos no tienen visibilidad despus de crear el objeto. Una vez creado el objeto, se le
asigna el tipo de datos base asociado al sinnimo. No hay ningn registro de que el sinnimo se haya especificado en la
instruccin
que
ha
creado
el
objeto.
A todos los objetos que proceden del objeto original, como las columnas del conjunto de resultados o las expresiones, se les
asigna el tipo de datos base. Todas las funciones de metadatos subsiguientes ejecutadas en el objeto original y cualquier
objeto derivado informarn del tipo de datos base y no del sinnimo. Este comportamiento se produce con las operaciones
173
de metadatos como sp_help y otros procedimientos almacenados del sistema, las vistas del esquema de informacin o las
diferentes operaciones de metadatos de la API de acceso a datos que informan de los tipos de datos de las columnas de
tablas
conjuntos
de
resultados.
Por ejemplo, puede crear una tabla si especifica national character varying:
CREATE TABLE ExampleTable (PriKey int PRIMARY KEY, VarCharCol national character varying(10))
VarCharCol se asigna a un tipo de datos nvarchar(10) y todas las funciones de metadatos posteriores informan de la
columna como columna nvarchar(10). Las funciones de metadatos nunca informarn de ellos como columna national
character varying(10).
Precisin, escala y longitud (Transact-SQL)
La precisin es el nmero de dgitos de un nmero. La escala es el nmero de dgitos situados a la derecha de la coma
decimal de un nmero. Por ejemplo, el nmero 123,45 tiene una precisin de 5 y una escala de 2.
En SQL Server 2005, la precisin mxima predeterminada de los tipos de datos numeric y decimal es 38. En versiones
anteriores
de
SQL
Server,
el
valor
predeterminado
mximo
es
28.
La longitud de un tipo de datos numrico es el nmero de bytes utilizados para almacenar el nmero. La longitud para una
cadena de caracteres o tipo de datos Unicode es el nmero de caracteres. La longitud para los tipos de datos binary,
varbinary y image es el nmero de bytes. Por ejemplo, un tipo de datos int que puede contener 10 dgitos se almacena en
4 bytes y no acepta coma decimal. El tipo de datos int tiene una precisin de 10, una longitud de 4 y una escala de 0.
Cuando se concatenan dos expresiones char, varchar, binary o varbinary, la longitud de la expresin resultante es la
suma
de
las
longitudes
de
las
dos
expresiones
de
origen
8.000
caracteres,
lo
que
sea
menor.
Cuando se concatenan dos expresiones nchar o nvarchar, la longitud de la expresin resultante es la suma de las
longitudes
de
las
dos
expresiones
de
origen
4.000
caracteres,
lo
que
sea
menor.
Cuando se comparan dos expresiones del mismo tipo de datos pero de distintas longitudes mediante UNION, EXCEPT o
INTERSECT,
la
longitud
resultante
es
la
longitud
mxima
de
las
dos
expresiones.
La precisin y la escala de los tipos de datos numricos, excepto decimal, son fijas. Si un operador aritmtico tiene dos
expresiones del mismo tipo, el resultado tiene el mismo tipo de datos con la precisin y la escala definidas para ese tipo de
datos. Si un operador tiene dos expresiones con tipos de datos numricos diferentes, las reglas de prioridad de tipos de
datos definen el tipo de datos del resultado. El resultado tiene la precisin y la escala definidas para el tipo de datos que le
corresponde.
Esta tabla define cmo se calculan la precisin y la escala del resultado de la operacin cuando ste es de tipo decimal. El
resultado
Ambas
es
decimal
cuando
expresiones
se
cumple
son
alguna
de
las
de
siguientes
condiciones:
tipo
Una expresin es decimal y la otra es de un tipo de datos con una prioridad menor que
decimal.
decimal.
Las expresiones de operando se denotan como expresin e1, con precisin p1 y escala s1, y expresin e2, con precisin p2
y escala s2. La precisin y la escala de cualquier expresin que no sea decimal es la precisin y la escala definidas para el
tipo de datos de la expresin.
Operacin
e1 + e2
174
e1 - e2
e1 * e2
p1 + p2 + 1
s1 + s2
e1 / e2
p1 - s1 + s2 + mx(6, s1 + p2 + 1)
mx(6, s1 + p2 + 1)
mx(s1, s2)
* La precisin y la escala del resultado tienen un valor mximo absoluto igual a 38. Cuando la precisin de un resultado es
mayor que 38, la escala correspondiente se reduce para evitar que la parte entera del resultado se trunque.
Prioridad de tipo de datos (Transact-SQL)
Cuando un operador combina dos expresiones de tipos de datos distintos, las reglas de prioridad de tipo de datos
especifican que el tipo de datos con la prioridad ms baja se convierta al tipo de datos con la prioridad ms alta. Si la
conversin no es una conversin implcita admitida, se devuelve un error. Cuando ambas expresiones de operandos tienen
el mismo tipo de datos, el resultado de la operacin tiene ese tipo de datos.
SQL Server 2005 utiliza el siguiente orden de prioridad para los tipos de datos:
sql_variant
xml
datetime
smalldatetime
float
real
decimal
money
smallmoney
bigint
int
smallint
tinyint
bit
ntext
text
175
image
timestamp
uniqueidentifier
nvarchar
nchar
varchar
char
varbinary
Una vez indicado el tipo de datos de la columna podemos opcionalmente completar su definicin con una serie de
clusulas.
[ COLLATE nbIntercalacion ]
Con la clusula COLLATE podemos definir el tipo de intercalacin que se utilizar para la columna (Ver CREATE
TABLE).
usuario
CLR).
Para mantener la compatibilidad con las versiones anteriores de SQL Server, se puede asignar un nombre de
restriccin a DEFAULT con [ CONSTRAINT nbRestriccion ]. Los nombres de restriccin deben ser nicos en el
esquema al que pertenece la tabla.
176
IDENTITY indica que la nueva columna es una columna de identidad. Cuando se agrega una nueva fila a la tabla, el
Motor de base de datos proporciona un valor incremental nico para la columna. Las columnas de identidad se
utilizan
normalmente
como
claves
principales.
La propiedad IDENTITY se puede asignar a las columnas tinyint, smallint, int, bigint, decimal(p,0) o
numeric(p,0). Slo se puede crear una columna de identidad para cada tabla. Las restricciones DEFAULT y los
valores predeterminados enlazados no se pueden utilizar en las columnas de identidad. En este caso, deben
especificarse el valor de inicializacin y el incremento, o ninguno de esto valores. Si no se especifica ninguno, el
valor
predeterminado
semilla
es
el
valor
que
se
es
utiliza
para
la
primera
fila
(1,1).
cargada
en
la
tabla.
Incremento es el valor incremental que se agrega al valor de identidad de la fila cargada anterior.
De forma general, si se especifica la clusula NOT FOR REPLICATION para una restriccin, dicha restriccin no se
impone cuando los agentes de rplica realizan operaciones de insercin, actualizacin o eliminacin. Si se
especifica esta clusula, junto con IDENTITY, los valores no se incrementan en las columnas de identidad cuando
los agentes de rplica realizan inserciones.
[ ROWGUIDCOL ]
ROWGUIDCOL indica que la nueva columna es una columna de GUID de filas. Slo se puede designar una
columna uniqueidentifier por tabla como columna ROWGUIDCOL. La propiedad ROWGUIDCOL se puede asignar
nicamente
una
columna
uniqueidentifier.
Las columnas de tipos de datos definidos por el usuario no se pueden designar con ROWGUIDCOL.
La propiedad ROWGUIDCOL no impone la unicidad de los valores almacenados en la columna. ROWGUIDCOL
tampoco genera automticamente valores para nuevas filas insertadas en la tabla, por lo que se debe de utilizar la
funcin NEWID en las instrucciones INSERT o utilizar la funcin NEWID como el valor predeterminado de la
columna
para
generar
valores
nicos
en
cada
fila.
Por ltimo nos quedan las restricciones de clave que aparecen en la sintaxis como:
[ <restriccion_columna> [ ...n ] ]
[ CONSTRAINT nbRestriccion]
177
[ ON { partition_scheme_name ( partition_column_name )
| filegroup | "default" } ]
| [ FOREIGN KEY ]
agrupado,
la
clave
principal
se
crear
sin
ndice
agrupado.
Una clave primaria no puede contener valores nulos, por lo que todas las columnas definidas en una restriccin
PRIMARY KEY se deben definir como NOT NULL. Si cuando definimos la columna, no se indica nada, la columna
se
establecer
NOT
NULL.
Si la clave principal se define en una columna de tipo definido por el usuario CLR, la implementacin del tipo debe
admitir
el
orden
binario.
UNIQUE indica que la columna no admite valores duplicados, por lo que se crea un ndice nico. Una tabla puede
tener varios ndices nicos.
de
ndices
de
la
tabla
exceda
de
249
ndices
no
agrupados
ndice
agrupado.
178
Si se define una restriccin UNIQUE en una columna de tipo definido por el usuario CLR, la implementacin del tipo
debe
admitir
el
orden
binario
basado
en
el
operador.
PAD_INDEX = { ON | OFF }
| FILLFACTOR = factorRelleno
| IGNORE_DUP_KEY = { ON | OFF }
| STATISTICS_NORECOMPUTE = { ON | OFF }
| ALLOW_ROW_LOCKS = { ON | OFF}
| ALLOW_PAGE_LOCKS ={ ON | OFF}
}
Son clusulas que nos permiten definir con ms detalle el ndice pero que no veremos aqu por entrar demasiado en
cuestiones internas.
La clusula CHECK.
es
una
expresin
lgica
que
devuelve
TRUE
FALSE.
Si queremos definir una restriccin CHECK sobre una columna calculada, esta se deber definir como PERSISTED.
Una columna puede tener cualquier nmero de restricciones CHECK y la condicin puede incluir varias expresiones
lgicas combinadas con AND y OR. Varias restricciones CHECK para una columna se validan en el orden en que se
crean.
La condicin de bsqueda debe evaluarse como una expresin booleana y no puede hacer referencia a otra tabla.
Una restriccin CHECK en el nivel de columna slo puede hacer referencia a la columna restringida y una restriccin
179
CHECK
en
el
nivel
de
tabla
slo
puede
hacer
referencia
columnas
de
la
misma
tabla.
Las restricciones CHECK no se pueden definir en las columnas text, ntext o image.
Por ejemplo queremos que la columna Precio de la tabla que estamos definiendo no pueda contener valores
negativos:
Por ltimo a nivel de columna podemos definir una restriccin de clave ajena:
[ FOREIGN KEY ]
un
registro
en
la
tabla
de
referencia
(la
tabla
padre).
La palabra FOREIGN KEY no es obligatoria cuando estamos a nivel de columna, el utilizarla o no tiene el mismo
efecto.
Nbesquema es el nombre del esquema al que pertenece la tabla padre y nbTablaPadre es el nombre de la tabla
padre.
Col_padre es la columna de la tabla padre que se relaciona con la columna que estamos definiendo. Esta columna
debe
tener
el
mismo
tipo
de
datos
que
la
columna
en
la
que
se
define
la
restriccin.
La col_padre debe tener en la tabla padre una restriccin de PRIMARY KEY o UNIQUE, si no se indica una columna
padre
(columna
de
referencia)
se
utiliza
la
clave
primaria
de
la
tabla
padre.
Las reglas de integridad referencial obligan a que si se especifica un valor distinto de NULL en una columna con una
restriccin FOREIGN KEY, ese valor debe existir en la columna referenciada de la tabla padre; de lo contrario, se
devolver
un
error
de
infraccin
de
clave
externa.
Las restricciones FOREIGN KEY slo pueden hacer referencia a las tablas de la misma base de datos en el mismo
servidor. La integridad referencial entre bases de datos debe implementarse a travs de desencadenadores.
Las restricciones FOREIGN KEY pueden hacer referencia a otras columnas de la misma tabla. Esto se denomina
autorreferencia.
180
UNIQUE.
Por ltimo nos queda completar las reglas de integridad referencial en cuanto a qu hacer cuando se eliminan o
modifican valores que intervienen en una relacin referencial.
es
NO
ACTION.
NO ACTION El Motor de base de datos genera un error y no es posible eliminar la fila de la tabla primaria (el
padre).
CASCADE Si se borra una fila de la tabla primaria, se eliminan automticamente todas las filas correspondientes de
la tabla que estamos definiendo, en otras palabras, si se elimina un padre, se eliminan todos sus hijos.
SET NULL Si se borra una fila de la tabla primaria, todas las filas correspondientes de la tabla que estamos
definiendo tomarn el valor NULL en el campo clave ajena. En otras palabras, si se elimina un padre, sus hijos se
quedan
Para
sin
ejecutar
esta
restriccin,
la
columna
padre.
clave
ajena
debe
admitir
valores
NULL.
SET DEFAULT Es como la anterior pero en vez del valor NULL toman el valor que tienen predeterminado. Si no hay
ningn valor predeterminado establecido de forma explcita, tomarn el valor NULL. Hay que tener en cuenta que el
valor predeterminado debe de existir en la tabla primaria.
Veamos
estas
opciones
con
un
ejemplo:
Tenemos una tabla Proveedores y una tabla artculos, en la tabla artculos nos guardamos el cdigo del proveedor
del artculo, por lo tanto definiremos la tabla artculos de la siguiente forma:
Denominacion VARCHAR(30),
181
.,
)
El campo Proveedor es clave ajena y hace referencia a un cdigo de proveedor de la tabla Proveedores.
Aqu no hemos aadido ninguna clusula ON DELETE por lo que se toma NO ACTION.
.,
)
Estas dos sentencias son equivalentes e indican que si se intenta borrar de la tabla Proveedores un proveedor
asignado a un artculo, el sistema da un error y no deja eliminar el proveedor.
.,
)
Se eliminar el proveedor y todos los artculos asignados a l.
.,
)
Se eliminar el proveedor de la tabla Proveedores y en la tabla Artculos, todas las filas que tenan ese nmero de
proveedor pasarn a tener el valor nulo en el campo proveedor.
Las
opciones
son
las
mismas
que
para
ON
DELETE.
NO ACTION El Motor de base de datos genera un error y no es posible modificar la fila de la tabla primaria (el
padre).
CASCADE Si se modifica un valor de la columna padre en la tabla primaria, se modificarn automticamente todas
182
las filas correspondientes de la tabla que estamos definiendo, en otras palabras, si se modifica el identificativo de un
padre,
se
actualizan
todos
sus
hijos.
SET NULL Si se modifica un valor de la columna padre en la tabla primaria, todas las filas correspondientes de la
tabla que estamos definiendo tomarn el valor NULL en el campo clave ajena. En otras palabras, si se modifica el
identificativo
Para
ejecutar
de
un
esta
padre,
restriccin,
la
sus
hijos
columna
clave
se
ajena
quedan
debe
admitir
sin
padre.
valores
NULL.
SET DEFAULT Es como la anterior pero en vez del valor NULL toman el valor que tienen predeterminado. Si no hay
ningn valor predeterminado establecido de forma explcita, tomarn el valor NULL. Hay que tener en cuenta que el
valor predeterminado debe de existir en la tabla primaria.
.,
)
Si cambiamos el cdigo del proveedor 3 a 3000 y hay artculos asignados al proveedor 3, el sistema da un error y
no deja modificar el proveedor.
.,
)
Se modifica el proveedor y todos los artculos asignados a l pasan a tener el valor 3000 en el campo Proveedor.
.,
)
Se modifica el proveedor y todos los artculos asignados a l pasan a tener el valor NULL en el campo Proveedor.
definicin
la
restriccin
restricciones
que
queramos.
Tambin existen restricciones de tabla, son restricciones que se definen despus de definir todas las columnas de la tabla y
que pueden afectar a una o varias columnas de la tabla. Como veremos la sintaxis para definir una restriccin de tabla es
muy parecida a la sintaxis de la misma restriccin de columna, lo que vara es que ahora tenemos que indicar las columnas
183
afectadas
por
la
restriccin.
[ CONSTRAINT nbRestriccion]
(nbCol[ASC|DESC][ ,...n ] )
[ ON { partition_scheme_name (partition_column_name)
| filegroup | "default" } ]
[(col_padre)[,...n] )]
184
}
Como las clusulas son las mismas que para las restricciones de columna, no repetiremos la explicacin de cada clusula,
lo
que
veremos
es
un
ejemplo
la
explicacin
de
ese
ejemplo.
Volviendo al ejemplo anterior de la tabla de Personas, podemos definir la misma utilizando restricciones de tabla:
codigo int,
dni int,
madre int,
padre int,
dniTutor int,
UNIQUE (dni),
185
El Motor de la base de datos entendera que queremos definir dos claves primarias y eso es imposible. En este caso habra
que utilizar una restriccin de tabla:
Codproducto int,
Codproveedor int,
186
pedido INT,
nlin INT,
codprod INT,
codprov INT,
cantidad INT,
UNIQUE (pedido,codprod,codprov));
La combinacin (codprod,codprov) forma una clave ajena que hace referencia a la tabla Productos, en este caso como la
clave principal de la tabla Productos est compuesta por los dos campos, la clave ajena tiene que tener el mismo nmero de
campo
del
mismo
tipo.
Con la restriccin UNIQUE indicamos que la combinacin formada por un nmero de pedido un cdigo de producto y cdigo
de proveedor no se puede repetir, esto hace que no se puedan insertar en un mismo pedido dos lneas del mismo
producto. No se puede duplicar la combinacin pero s las columnas individualmente (pueden haber varias filas con el
mismo nmero de pedido, varias filas con el mismo cdigo de producto y varias filas con el mismo codigo de proveedor.
Aqu termina la explicacin de la sintaxis bsica de las instrucciones CREATE TABLE. Nos queda hablar de las columnas
calculadas y de las tablas temporales, otras clusulas de la instruccin se pueden consultar en la ayuda de la instruccin
SQL CREATE TABLE.
Definir columnas calculadas.
Una columna calculada es una columna cuyo valor no se introduce, sino que se obtiene como resultado de un clculo.
187
nbCol AS expresion
[ PERSISTED
[NOT NULL]
[ <restriccion_columna> [...n ] ]
]
expresion es la expresin que define el valor de una columna calculada y est basada en otras columnas de la tabla.
Por ejemplo, una columna calculada puede ser definida as:
contener
tipos
de
datos
de
alias.
Una columna calculada es, por defecto, una columna virtual no almacenada fsicamente en la tabla. PERSISTED indica que
la columna calculada se almacena en la tabla y automticamente se actualizan los valores almacenados en ella cuando se
actualizan
las
columnas
de
las
que
depende.
Para que la columna pueda ser definida con PERSISTED la expresin que la calcula debe ser determinista. Una expresin
es determinista a menos que utilice una funcin no determinista.
Una columna calculada se puede utilizar en la lista de seleccin, clusula WHERE, clusula ORDER BY u otras ubicaciones
en que se puedan utilizar expresiones regulares, con las siguientes excepciones:
Una columna calculada no puede utilizarse como definicin de restriccin DEFAULT o FOREIGN KEY ni como NOT
NULL.
Una columna calculada no puede ser el destino de una instruccin INSERT o UPDATE. No tiene sentido querer
asignar un determinado
tablas
temporales
globales
son
visibles
para
todas
las
sesiones.
Para indicar que la tabla que queremos crear es temporal aadimos a su nombre el prefijo # (#nbTabla) para tablas
188
temporales
locales
el
prefijo
##
(##nbTabla)
tablas
temporales
globales.
Por ejemplo:
mediante
DROP
TABLE:
Una tabla temporal local creada en un procedimiento almacenado se quita automticamente cuando se completa el
procedimiento almacenado. Cualquiera de los procedimientos almacenados anidados ejecutados por el procedimiento
almacenado que cre la tabla, puede hacer referencia a la tabla. El proceso que llam al procedimiento almacenado que
cre
Las
la
tablas
tabla
temporales
no
se
puede
quitan
hacer
referencia
automticamente
al
final
a
de
la
la
tabla.
sesin
actual.
Las tablas temporales globales se quitan automticamente cuando la sesin que cre la tabla finaliza y las tareas restantes
han dejado de hacer referencia a ellas. La asociacin entre una tarea y una tabla se mantiene slo durante la vida de una
nica instruccin Transact-SQL. Esto significa que la tabla temporal global se quita al finalizar la ltima instruccin TransactSQL
que
estuviera
haciendo
referencia
activamente
la
tabla
cuando
finaliz
la
sesin
que
la
cre.
Una tabla temporal local creada en un procedimiento almacenado o desencadenador, puede tener el mismo nombre que una
tabla temporal creada antes de que se llame al procedimiento almacenado o al desencadenador. No obstante, si una
consulta hace referencia a una tabla temporal y hay dos tablas temporales con el mismo nombre, no est definido en cul de
las dos tablas debe resolverse la consulta. Los procedimientos almacenados anidados pueden crear tambin tablas
temporales con el mismo nombre que la tabla temporal creada por el procedimiento almacenado que la llam. Sin embargo,
en el caso de las modificaciones que se van a resolver en la tabla creada en el procedimiento anidado, la tabla debe tener la
misma estructura, con los mismos nombres de columnas, que la tabla creada en el procedimiento que realiza la llamada.
Esto se muestra en el ejemplo siguiente.
Con tablas temporales globales o locales, la sintaxis CREATE TABLE admite la definicin de restricciones, excepto las
restricciones FOREIGN KEY. Si se especifica una restriccin FOREIGN KEY en una tabla temporal, la instruccin devuelve
un mensaje de advertencia que indica que la restriccin se ha omitido. La tabla se crea sin las restricciones FOREIGN KEY.
En las restricciones FOREIGN KEY no se puede hacer referencia a tablas temporales.
189
Se recomienda utilizar variables de tabla en lugar de tablas temporales. Las tablas temporales son tiles cuando es
necesario crear en ellas ndices de forma explcita o bien cuando los valores de tabla deben ser visibles en varios
procedimientos almacenados o funciones. En general, las variables de tabla contribuyen a que el procesamiento de las
consultas sea ms eficaz.
8.6. Eliminar una tabla DROP TABLE
Para eliminar una tabla de una base de datos tenemos la sentencia DROP TABLE. Con ella quitamos una o varias
definiciones de tabla y todos los datos, ndices, desencadenadores, restricciones y especificaciones de permisos que tengan
esas
tablas.
Las vistas o procedimientos almacenados que hagan referencia a la tabla quitada se deben quitar explcitamente con DROP
VIEW
DROP
PROCEDURE.
Su sintaxis es:
<tipo_dato>
190
[ COLLATE nbIntercalacion ]
<definicion_columna>
| <definicion_colCalc>
| <restriccion_tabla>
} [ ,...n ]
| DROP
[CONSTRAINT] nbRestriccion
|COLUMN nbColumna
} [,...n ]
191
[;]
Aunque la sintaxis parece un poco complicada, realmente no lo es. La sentencia nos permite variar la definicin de una tabla
ya creada, en qu consiste esta variacin: modificar la definicin de columnas ya existentes (ALTER COLUMN), aadir ms
columnas o restricciones (ADD), eliminar columnas y restricciones (DROP), habilitar/deshabilitar restricciones (CHECK
CONSTRAINT)
habilitar/deshabilitar
triggers.
Como muchas de las clusulas las hemos estudiado con CREATE TABBLE, slo incidiremos en lo nuevo.
Para modificar una columna escribiremos la clusula ALTER COLUMN seguida del nombre de la columna que queremos
modificar y la nueva definicin, podemos cambiar su tipo de datos indicando uno nuevo, hacer que la columna acepte o no
valores
nulos
(NULL|NOTNULL),
cambiar
la
intercalacin
(COLLATE).
Con ADD ROWGUIDCOL hacemos que la columna sea GUID de filas y DROP ROWGUIDCOL hacemos que ya no lo sea.
Si la columna es una columna calculada podemos cambiar su condicin de columna almacenada con ADD/DROP
PERSISTED.
Ejemplo:
que
la
columna
direccion
de
la
tabla
Clientes,
ahora
admita
40
caracteres
alfanumricos.
Cuando cambiamos el tipo de una columna hay que tener en cuenta que el nuevo tipo debe ser compatible con el antiguo
para
que
no
se
pierdan
los
datos
almacenados.
Adems la columna no se puede modificar si es ROWGUIDCOL, calculada o si se utiliza en una columna calculada, si se
utiliza en un ndice (a menos que la columna sea del tipo de datos varchar, nvarchar o varbinary, el tipo de datos no se
cambie y el nuevo tamao sea igual al tamao anterior o mayor que ste), si se utiliza en estadsticas, en una restriccin
PRIMARY KEY, FOREIGN KEY, CHECK o UNIQUE. Sin embargo, se permite el cambio de longitud de una columna de
longitud variable en una restriccin CHECK o UNIQUE.
Para aadir una nueva columna o restriccin utilizamos la clusula ADD seguida de la definicin de lo que queremos aadir,
para eso seguimos la misma sintaxis que para definir las columnas y restricciones de tabla del CREATE TABLE.
Por ejemplo:
192
las
Una
restriccin
PRIMARY
siguientes
KEY
no
puede
quitarse
si
existe
limitaciones:
un
ndice
XML
en
la
tabla.
Una columna no puede quitarse si se utiliza en un ndice, en una restriccin CHECK, FOREIGN KEY, UNIQUE o PRIMARY
KEY,
DEFAULT.
Ejemplo:
ALTER
TABLE
Clientes
DROP
COLUMN
email;
TABLE
Clientes
DROP
CONSTRAINT
pk ;
Elimina de la tabla Clientes la restriccin de PRIMARY KEY, la columna sigue en la tabla pero ya no es clave principal.
Para finalizar, las dos ltimas clusulas nos permiten indicar si se tienen que comprobar o no determinadas restricciones y
habilitar
CHECK
DISABLE
y
CONSTRAINT
TRIGGER
ALL
activa
ALL
deshabilitar
la
comprobacin
deshabilita
todos
de
todas
los
las
triggers.
restricciones
triggers
definidas
definidos
sobre
sobre
la
la
tabla.
tabla.
Cuando deshabilitamos un trigger, ste sigue definido, pero no entra en accin cuando se produce el evento que debera
activarlo. En cualquier momento lo podremos habilitar con otra instruccin ALTER TABLE.
8.8. Crear una vista CREATE VIEW
Una vista es una tabla virtual que representa los datos de una o ms tablas de una forma alternativa. Para crear una nueva
vista se emplea la sentencia CREATE VIEW, debe ser la primera instruccin en un lote de consultas.
Una vista slo se puede crear en la base de datos actual.
Para ejecutar CREATE VIEW, se necesita, como mnimo, el permiso CREATE VIEW en la base de datos y el permiso
ALTER
en
el
esquema
en
el
que
se
est
creando
la
vista.
Sintaxis:
[ (columna [ ,...n ] ) ]
AS ( sentencia_select ) [ ; ]
193
la
vista
que
se
ha
creado.
Una vista no tiene por qu ser un simple subconjunto de filas y de columnas de una tabla determinada. Es posible crear una
vista que utilice ms de una tabla u otras vistas mediante una clusula SELECT de cualquier complejidad.
Tambin se pueden utilizar funciones y varias instrucciones SELECT separadas por UNION o UNION ALL.
Una vista puede tener como mximo 1.024 columnas.
Ejemplos:
AS
SELECT oficinas.oficina AS ofi, ciudad, dir, region, objetivo, oficinas.ventas AS ventas_ofi, empleados.*
ON oficinas.oficina = empleados.oficina;
Crea
una
vista
con
los
datos
de
todos
los
empleados
de
sus
oficinas.
En este caso hemos tenido que definir alias de campo porque en el origen de la sentencia SELECT existe duplicidad de
nombres.
AS
194
UNION ALL
195
Para
eliminar
una
vista
de
una
base
de
datos
tenemos
la
sentencia
DROP
TABLE.
Sintaxis:
por
esa
misma
columna.
Funciona de forma parecida al ndice de un libro donde tenemos el ttulo del captulo y la pgina donde empieza dicho
captulo, en un ndice definido sobre una determinada columna tenemos el contenido de la columna y la posicin de la fila
que contiene dicho valor dentro de la tabla.
La definicin de los ndices de la base de datos es tarea del administrador de la base de datos, los administradores ms
experimentados pueden disear un buen conjunto de ndices, pero esta tarea es muy compleja, consume mucho tiempo y
est sujeta a errores, incluso con cargas de trabajo y bases de datos con un grado de complejidad no excesivo.
8.11. Tipos de ndices
ndice simple y compuesto.
Un ndice simple est definido sobre una sla columna de la tabla mientras que un ndice compuesto est formado por varias
columnas
de
la
misma
tabla
(tabla
sobre
la
cual
est
definido
el
ndice.
Cuando se define un ndice sobre una columna, los registros que se recuperen utilizando el ndice aparecern ordenados
por el campo indexado. Si se define un ndice compuesto por las columnas col1 y col2, las filas que se recuperen utilizando
dicho ndice aparecern ordenadas por los valores de col1 y todas las filas que tengan el mismo valor de col1 se ordenarn
196
a su vez por los valores contenidos en col2, funcin igual que la clusula ORDER BY vista en el tema de consultas simples.
Por ejemplo si definimos un ndice compuesto basado en las columnas (provincia, localidad), las filas que se recuperen
utilizando este ndice aparecern ordenadas por provincia y dentro de la misma provincia por localidad.
ndice agrupado y no agrupado,
El trmino ndice agrupado no se debe confundir con ndice compuesto, el significado es totalmente diferente.
Un ndice agrupado (CLUSTERED) es un ndice en el que el orden lgico de los valores de clave determina el orden fsico
de las filas correspondientes de la tabla. El nivel inferior, u hoja, de un ndice agrupado contiene las filas de datos en s de la
tabla.
Una
tabla
vista
permite
un
solo
ndice
agrupado
al
mismo
tiempo.
Los ndices no agrupados existentes en las tablas se vuelven a generar al crear un ndice agrupado, por lo que es
conveniente
crear
el
ndice
agrupado
antes
de
crear
los
ndices
no
agrupados.
Un ndice no agrupado especifica la ordenacin lgica de la tabla. Con un ndice no agrupado, el orden fsico de las filas de
datos es independiente del orden indizado.
ndice nico
ndice nico es aquel en el que no se permite que dos filas tengan el mismo valor en la columna de clave del ndice. Es decir
que no permite valores duplicados.
8.12. Ventajas e inconvenientes de los ndices
Ventajas
La utilizacin de ndices puede mejorar el rendimiento de las consultas, ya que los datos necesarios para satisfacer las
necesidades de la consulta existen en el propio ndice. Es decir, slo se necesitan las pginas de ndice y no las pginas de
datos de la tabla o el ndice agrupado para recuperar los datos solicitados; por tanto, se reduce la E/S global en el disco. Por
ejemplo, una consulta de las columnas a y b de una tabla que dispone de un ndice compuesto creado en las columnas a, b
y c puede recuperar los datos especificados del propio ndice.
Los ndices en vistas pueden mejorar de forma significativa el rendimiento si la vista contiene agregaciones, combinaciones
de tabla o una mezcla de agregaciones y combinaciones.
Inconvenientes
Las
tablas
utilizadas
para
almacenar
los
ndices
ocupan
espacio.
Los ndices consumen recursos ya que cada vez que se realiza una operacin de actualizacin, insercin o borrado en la
tabla indexada, se tienen que actualizar todas las tablas de ndice definidas sobre ella (en la actualizacin slo es necesaria
la
actualizacin
de
los
ndices
definidos
sobre
las
columnas
que
se
actualizan).
Hay que evitar crear demasiados ndices en tablas que se actualizan con mucha frecuencia y procurar definirlos con
el menor nmero de columnas posible.
Es conveniente utilizar un nmero mayor de ndices para mejorar el rendimiento de consultas en tablas con pocas
necesidades de actualizacin, pero con grandes volmenes de datos. Un gran nmero de ndices contribuye a
197
mejorar el rendimiento de las consultas que no modifican datos, como las instrucciones SELECT, ya que el
optimizador de consultas dispone de ms ndices entre los que elegir para determinar el mtodo de acceso ms
rpido.
La indizacin de tablas pequeas puede no ser una solucin ptima, porque puede provocar que el optimizador de
consultas tarde ms tiempo en realizar la bsqueda de los datos a travs del ndice que en realizar un simple
recorrido de la tabla. De este modo, es posible que los ndices de tablas pequeas no se utilicen nunca; sin
embargo, sigue siendo necesario su mantenimiento a medida que cambian los datos de la tabla.
Se recomienda utilizar una longitud corta en la clave de los ndices agrupados. Los ndices agrupados tambin
mejoran si se crean en columnas nicas o que no admitan valores NULL.
Un ndice nico en lugar de un ndice no nico con la misma combinacin de columnas proporciona informacin
adicional al optimizador de consultas y, por tanto, resulta ms til.
Hay que tener en cuenta el orden de las columnas si el ndice va a contener varias columnas. La columna que se
utiliza en la clusula WHERE en una condicin de bsqueda igual a (=), mayor que (>), menor que (<) o BETWEEN,
o que participa en una combinacin, debe situarse en primer lugar. Las dems columnas deben ordenarse
basndose en su nivel de diferenciacin, es decir, de ms distintas a menos distintas.
[;]
<objeto> ::=
[nbBaseDatos.[nbEsquema].| nbEsquema.]nbTablaVista
}
Esta es la sintaxis simplicada de la instruccin CREATE INDEX que permite crear un ndice en una tabla sobre una o varias
columnas.
198
nbBaseDatos
nbEsquema
nbTablaVista
Es
Es
Es
el
el
el
nombre_indice
nombre
nombre
nombre
Es
de
el
la
de
del
esquema
tabla
vista
nombre
la
al
sobre
del
base
que
la
ndice
pertenece
que
se
quiere
que
de
datos.
la
tabla/vista.
crear
estamos
el
ndice.
creando.
Columna Es el nombre de la columna que forma parte del ndice. Se pueden definir ndices compuestos escribiendo entre
parntesis
los
nombres
de
las
columnas
separados
por
comas.
ASC los valores de la columna se ordenarn de forma ASCendente o DESCendente. Por defecto se asume ASC.
UNIQUE
permite
definir
CLUSTERED
un
el
ndice
nico
(no
admite
ndice
ser
valores
repetidos).
agrupado.
Crea un ndice nico sobre la columna col de la tabla Clientes en la base de datos actual, la columna col no podr contener
valores duplicados.
8.14. Eliminar un ndice DROP INDEX
199
Para
eliminar
un
ndice
tenemos
la
sentencia
DROP
INDEX.
La instruccin DROP INDEX no es aplicable a los ndices creados mediante la definicin de restricciones PRIMARY KEY y
UNIQUE. Para quitar la restriccin y el ndice correspondiente, se tiene que ejecutar un ALTER TABLE con la clusula
DROP CONSTRAINT.
Sintaxis simplificada:
<indice>::=
nbindice ON [nbBaseDatos.[nbEsquema].|nbEsquema.]nbTablaVista
}
nbBaseDatos
Es
nbEsquema
nbTablaVista
Es
Es
el
el
el
nombre
nombre
nombre
de
la
de
del
esquema
tabla
vista
la
al
de
base
que
la
que
pertenece
se
quiere
de
datos.
la
tabla/vista.
eliminar
el
ndice.
de
instrucciones.
Las sentencias que ya conocemos son las que en principio forman parte de cualquier lenguaje SQL. Ahora veremos que
TRANSACT-SQL va ms all de un lenguaje SQL cualquiera ya que aunque no permita:
200
Crear aplicaciones ejecutables, sino elementos que en algn momento llegarn al servidor de datos y sern
ejecutados.
Incluye caractersticas propias de cualquier lenguaje de programacin, caractersticas que nos permiten definir la lgica
necesaria para el tratamiento de la informacin:
Tipos de datos.
Definicin de variables.
Gestin de excepciones.
Funciones predefinidas.
Elementos para la visualizacin, que permiten mostrar mensajes definidos por el usuario gracias a la clusula
PRINT.
Estas caractersticas nos van a permitir crear bloques de cdigo orientados a realizar operaciones ms complejas. Estos
bloques no son programas sino procedimientos o funciones que podrn ser llamados en cualquier momento.
En SQL Server 2005 podemos definir tres tipos de bloques de cdigo, los procedimientos almacenados, los
desencadenadores
Nosotros
(o
triggers)
estudiaremos
funciones
definidas
los
por
dos
el
usuario.
primeros.
Empezaremos por los procedimientos almacenados, veremos primero las sentencias para crear y eliminar procedimientos
almacenados, luego estudiaremos las instrucciones Transact-SQL ms propias de un lenguaje de programacin nombradas
en el tema de Introduccin al Transact-SQL como son por ejemplo los bucles y estructuras condicionales. Estas
instrucciones las utilizaremos dentro de procedimientos almacenados pero veremos que tambin nos servirn para definir
otros
bloques
de
cdigo.
Terminaremos esta unidad de programacin estudiando los disparadores o Triggers muy similares a los procedimientos
almacenados que difieren bsicamente en la forma en que entran en funcionamiento.
9.2. Procedimientos almacenados STORE PROCEDURE
Un procedimiento almacenado (STORE PROCEDURE) est formado por un conjunto de instrucciones Transact-SQL que
definen un determinado proceso, puede aceptar parmetros de entrada y devolver un valor o conjunto de resultados. Este
procedimiento se guarda en el servidor y puede ser ejecutado en cualquier momento.
Los procedimientos almacenados se diferencian de las instrucciones SQL ordinarias y de los lotes de instrucciones SQL en
que estn precompilados. La primera vez que se ejecuta un procedimiento, el procesador de consultas de SQL Server lo
analiza y prepara un plan de ejecucin que se almacena en una tabla del sistema. Posteriormente, el procedimiento se
ejecuta segn el plan almacenado. Puesto que ya se ha realizado la mayor parte del trabajo de procesamiento de consultas,
los procedimientos almacenados se ejecutan casi de forma instantnea por lo que el uso de procedimientos almacenados
mejora notablemente la potencia y eficacia del SQL.
SQL Server incorpora procedimientos almacenados del sistema, se encuentran en la base de datos master y se reconocen
por su nombre, todos tienen un nombre que empieza por sp_. Permiten recuperar informacin de las tablas del sistema y
pueden ejecutarse en cualquier base de datos del servidor.
201
Tambin estn los procedimientos de usuario, los crea cualquier usuario que tenga los permisos oportunos.
Se pueden crear tambin procedimiento temporales locales y globales. Un procedimiento temporal local se crea por un
usuario en una conexin determinada y slo se puede utilizar en esa sesin, un procedimiento temporal global lo pueden
utilizar todos los usuarios, cualquier conexin puede ejecutar un procedimiento almacenado temporal global. ste existe
hasta que se cierra la conexin que el usuario utiliz para crearlo, y hasta que se completan todas las versiones del
procedimiento que se estuvieran ejecutando mediante otras conexiones. Una vez cerrada la conexin que se utiliz para
crear el procedimiento, ste ya no se puede volver a ejecutar, slo podrn finalizar las conexiones que hayan empezado a
ejecutar el procedimiento.
Tanto los procedimientos temporales como los no temporales se crean y ejecutan de la misma forma, el nombre que le
pongamos indicar de qu tipo es el procedimiento.
Los procedimientos almacenados se crean mediante la sentencia CREATE PROCEDURE y se ejecutan con EXEC (o
EXECUTE). Para ejecutarlo tambin se puede utilizar el nombre del procedimiento almacenado slo, siempre que sea la
primera palabra del lote. Para eliminar un procedimiento almacenado utilizamos la sentencia DROP PROCEDURE.
9.3. Eliminar procedimientos almacenados
Aunque no sabemos todava crear un procedimiento comentaremos aqu la instruccin para eliminar procedimientos y as
podremos utilizarla en los dems ejercicios.
202
CREATE PROCEDURE
Para crear un procedimiento almacenado como hemos dicho se emplea la instruccin CREATE PROCEDURE:
<bloque_instrucciones> ::=
datos.
Si queremos definir un procedimiento temporal local el nombre deber empezar por una almohadilla (#) y si el procedimiento
es
temporal
global
el
nombre
debe
de
empezar
por
##.
El nombre completo de un procedimiento almacenado o un procedimiento almacenado temporal global, incluidas ##, no
puede superar los 128 caracteres. El nombre completo de un procedimiento almacenado temporal local, incluidas #, no
puede superar los 116 caracteres.
Transact-SQL permite abreviar la palabra reservada PROCEDURE por PROC sin que ello afecte a la funcionalidad de la
instruccin.
203
tener
un
mximo
de
2.100
parmetros.
Los parmetros son locales para el procedimiento; los mismos nombres de parmetro se pueden utilizar en otros
procedimientos. De manera predeterminada, los parmetros slo pueden ocupar el lugar de expresiones constantes; no se
pueden utilizar en lugar de nombres de tabla, nombres de columna o nombres de otros objetos de base de datos.
VARYING Slo se aplica a los parmetros de tipo cursor por lo que se explicar cuando se expliquen los cursores.
OUTPUT
OUT
(son
equivalentes)
Indica que se trata de un parmetro de salida. El valor de esta opcin puede devolverse a la instruccin EXECUTE que
realiza
la
llamada.
El parmetro variable OUTPUT debe definirse al crear el procedimiento y tambin se indicar en la llamada junto a la
variable que recoger el valor devuelto del parmetro. El nombre del parmetro y de la variable no tienen por qu coincidir;
sin embargo, el tipo de datos y la posicin de los parmetros deben coincidir a menos que se indique el nombre del
parmetro en la llamada de la forma @parametro=valor.
Procedimiento bsico
AS
PRINT Hola;
GO
- Indicamos GO para cerrar el lote que crea el procedimiento y empezar otro lote.
Dice_Hola
Con un parmetro de entrada (la palabra que queremos que escriba)
AS
204
PRINT @palabra;
GO
USE Biblio;
GO
AS
GO
la
llamada
podemos
indicar
los
valores
de
los
parmetros
de
varias
formas,
indicando slo el valor de los parmetros (en este caso los tenemos que indicar en el mismo orden en que estn definidos)
como en el ejemplo anterior, o bien indicando el nombre del parmetro:
205
Indicar el nombre del parmetro en la llamada tambin nos permite indicar los valores en cualquier orden, la siguiente
llamada es equivalente a la anterior, hemos invertido el orden y se ejecuta igual:
GO
AS
GO
se
rellenar
con
el
valor
por
defecto
que
indicamos
en
la
definicin.
Lo podemos hacer as porque el parmetro opcional es el ltimo de la lista de parmetros. Cuando el parmetro opcional no
es el ltimo la llamada tiene que ser diferente, tenemos que nombrar los parmetros en la llamada, al menos a partir del
parmetro opcional.
206
GO
AS
GO
error.
Esta forma da error, debemos utilizar la palabra DEFAULT o indicar el nombre de todos los parmetros que van detrs del
opcional.
instruccin
RETURN
que
veremos
en
el
siguiente
apartado.
Para poder recoger el valor devuelto por el procedimiento, en la llamada se tiene que indicar una variable donde guardar ese
valor.
Ejemplo:
Definimos el procedimiento ultimo_contrato que nos devuelte la fecha en que se firm el ltimo contrato en una determinada
oficina. El procedimiento tendr pues dos parmetros, uno de entrada para indicar el nmero de la oficina a considerar y uno
de salida que devolver la fecha del contrato ms reciente de entre los empleados de esa oficina.
USE Gestion
207
GO
AS
GO
Con @fecha DATETIME OUTPUT indicamos que el parmetro @fecha es de salida, el proceso que realice la llamada podr
recoger su valor despus de ejecutar el procedimiento.
En la llamada, para los parmetros de salida, en vez de indicar un valor de entrada se indica un nombre de variable, variable
que recoger el valor devuelto por el procedimiento sin olvidar la palabra OUTPUT:
PRINT @ultima;
RETURN
RETURN ordena salir incondicionalmente de una consulta o procedimiento, se puede utilizar en cualquier punto para salir
del procedimiento y las instrucciones que siguen a RETURN no se ejecutan. Adems los procedimientos almacenados
pueden devolver un valor entero mediante esta orden.
RETURN [expresion_entera]
Expresion_entera
es
el
valor
entero
que
se
devuelve.
A menos que se especifique lo contrario, todos los procedimientos almacenados del sistema devuelven el valor 0. Esto
indica
que
son
correctos
un
valor
distinto
de
cero
indica
que
se
ha
producido
un
error.
Cuando se utiliza con un procedimiento almacenado, RETURN no puede devolver un valor NULL. Si un procedimiento
intenta devolver un valor NULL (por ejemplo, al utilizar RETURN @var si @var es NULL), se genera un mensaje de
208
advertencia
se
devuelve
el
valor
0.
Si queremos recoger el valor de estado devuelto por el procedimiento la llamada debe ser distinta, y seguir el siguiente
modelo:
USE Gestion
GO
AS
GO
Para obtener en la variable @var el resultado devuelto por el procedimiento la llamada sera:
AS
209
GO
Para obtener en la variable @var el resultado devuelto por el procedimiento la llamada sera:
PRINT @var
Nos visualiza el nmero de trabajadores de la oficina nmero 12.
9.5. Instrucciones de control de flujo
Disponemos de diferentes elementos para el control de flujo, como pueden ser RETURN, IF... ELSE, WHILE, BREAK,
CONTINUE, GO TO, EXECUTE, etc. En los siguientes apartados aprenderemos cmo utilizarlos.
9.6. IF ELSE
Proporciona una ejecucin condicional, permite ejecutar o no ciertas instrucciones dependiendo de si se cumple o no una
determinada condicin.
IF condicion
{ sentencia_sql | bloque_sql }
[ ELSE
{ sentencia_sql | bloque_sql } ]
Si la condicin se cumple (da como resultado TRUE) se ejecuta la instruccin SQL o bloque de instrucciones que aparecen
a continuacin de la condicin, si la condicin no se cumple se ejecutan las sentencias que aparecen despus de la palabra
ELSE. El bloque ELSE es opcional.
Ejemplo: Si nos queremos guardar en una consulta todos los ejemplos para probarlos en cualquier momento, es conveniente
antes de los CREATE PROCEDURE colocar un DROP PROCEDURE para que la instruccin CREATE no d error si el
procedimiento ya existe, pero la primera vez la instruccin DROP PROC nos dar error porque el procedimiento todava no
210
existe,
as
que
lo
mejor
es
ejecutar
el
DROP
slo
si
el
procedimiento
existe,
utilizando
la
funcin
object_id(nombre_de_objeto,tipo de objeto) que nos devuelve el id del objeto y NULL si el objeto no existe.
GO
BEGIN
END
WHILE condicion
211
{ sentencia_sql | bloque_sql }
| BREAK
| CONTINUE
Podemos
anidar
bucles,
colocar
un
bucle
WHILE
dentro
de
otro
BREAK Produce la salida del bucle WHILE ms interno. La instruccin BREAK interna sale al siguiente bucle ms externo.
Todas las instrucciones que se encuentren despus del final del bucle interno se ejecutan primero y despus se reinicia el
siguiente
bucle
ms
externo.
CONTINUE Hace que se reinicie el bucle WHILE y omite las instrucciones que haya despus de la palabra clave
CONTINUE.
Por ejemplo, tenemos los siguientes bucles anidados:
WHILE condicion1
-- Bucle 1
Instrucciones_1_1
WHILE condicion2
-- Bucle 2
Intrucciones2_1
If condicion3 BREAK
Instrucciones2_2
IF condicion4 CONTINUE
Instrucciones2_3
Instrucciones1_2
Las
Preguntamos
instrucciones
se
ejecutaran
por
en
este
orden:
condicion1:
212
Si
condicion1
Se
ejecuta
el
Preguntamos
se
ejecuta
cumple:
bloque
Instrucciones1_1
por
Si
Se
se
el
cumple
bloque
Si
condicon2:
de
condicion2:
instrucciones
condicin3
se
Salimos
Se
Y
Si
vuelve
bloque
preguntar
Si
vuelve
no
Se
se
Si
Instrucciones2_3
preguntar
por
no
ejecuta
el
bloque
Se
vuelve
preguntar
condicion1
condicion2
condicion4:
bloque
Se
Si
por
cumple
el
condicion2
Instrucciones2_3
preguntar
se
vuelve
condicion4:
bloque
ejecuta
instrucciones2_2
cumple
el
se
condicion1.
cumple:
bloque
se
por
se
el
Saltamos
2,
Instrucciones1_2
no
ejecuta
Si
bucle
el
condicin3
Se
cumple:
del
ejecuta
se
Instrucciones_2_1.
no
se
condicion2
cumple:
Instrucciones
por
1_2
condicion1
se
cumple:
Hemos terminado
9.8. WAITFOR
Bloquea la ejecucin de un lote, un procedimiento almacenado o una transaccin hasta alcanzar la hora o el intervalo de
tiempo especificado, o hasta que una instruccin especificada modifique o devuelva al menos una fila. Nosotros
estudiaremos los dos primeros casos.
|TIME 'fechaHora_de_ejecucion'}
DELAY permite indicar un perodo de tiempo especificado (hasta un mximo de 24 horas) que debe transcurrir antes de la
ejecucin
de
un
lote,
un
procedimiento
almacenado
una
transaccin.
'tiempo_a_transcurrir' Es el perodo de tiempo que hay que esperar, se puede especificar en uno de los formatos aceptados
para el tipo de datos datetime o como una variable local. No se pueden especificar fechas; por lo tanto, no se permite la
parte
de
fecha
del
valor
datetime.
TIME permite indicar la hora especifica a la que se ejecuta el lote, el procedimiento almacenado o la transaccin.
'fechaHora_de_ejecucion' Es la hora a la que termina la instruccin WAITFOR por tanto a la que empieza la ejecucin de las
instrucciones siguientes a WAITFOR. Se puede especificar en uno de los formatos aceptados para el tipo de datos datetime
213
o como una variable local. No se pueden especificar fechas; por lo tanto, no se permite la parte de fecha del valor datetime.
Cada instruccin WAITFOR tiene un subproceso asociado. Si se especifica un gran nmero de instrucciones WAITFOR en
el mismo servidor, se pueden acumular muchos subprocesos a la espera de que se ejecuten estas instrucciones. SQL
Server supervisa el nmero de subprocesos asociados con las instrucciones WAITFOR y selecciona aleatoriamente algunos
de estos subprocesos para salir si el servidor empieza a experimentar la falta de subprocesos.
Ejemplo:
PRINT CONVERT(CHAR(8),Getdate(),108);
el
flujo
de
ejecucin
lo
dirige
una
etiqueta.
----
Etiq:
----
214
---Es una instruccin a evitar porque puede llevar a redactar programas no estructurados.
9.10. TRY... CATCH
Definicin
La estructura TRYCATCH implementa un mecanismo de control de errores para Transact-SQL, permite incluir un grupo de
instrucciones Transact-SQL en un bloque TRY. Si se produce un error en el bloque TRY, el control se transfiere a otro grupo
de instrucciones que est incluido en un bloque CATCH.
BEGIN TRY
{sentencia_sql|bloque_sql}
END TRY
BEGIN CATCH
[{sentencia_sql|bloque_sql}]
END CATCH [ ; ]
Una construccin TRYCATCH no puede abarcar varios bloques de instrucciones Transact-SQL (varios bloques
BEGINEND de instrucciones Transact-SQL) ni una construccin IFELSE.
Si no hay errores en el cdigo incluido en un bloque TRY, cuando la ltima instruccin de este bloque ha terminado de
ejecutarse, el control se transfiere a la instruccin inmediatamente posterior a la instruccin END CATCH asociada. Si hay
un error en el cdigo incluido en el bloque TRY, el control se transfiere a la primera instruccin del bloque CATCH asociado.
Si la instruccin END CATCH es la ltima instruccin de un procedimiento almacenado o desencadenador, el control se
devuelve
Las
la
instruccin
que
construcciones
llam
al
procedimiento
TRYCATCH
almacenado
se
activ
el
pueden
desencadenador.
anidar.
Las construcciones TRYCATCH capturan los errores no controlados de los procedimientos almacenados o
desencadenadores ejecutados por el cdigo del bloque TRY. Alternativamente, los procedimientos almacenados o
desencadenadores pueden contener sus propias construcciones TRYCATCH para controlar los errores generados por su
cdigo. Por ejemplo, cuando un bloque TRY ejecuta un procedimiento almacenado y se produce un error en ste, el error se
puede controlar de las formas siguientes:
215
Si el procedimiento almacenado contiene una construccin TRYCATCH, el error transfiere el control al bloque
CATCH del procedimiento almacenado. Cuando finaliza el cdigo del bloque CATCH, el control se devuelve a la
instruccin inmediatamente posterior a la instruccin EXECUTE que llam al procedimiento almacenado.
No se pueden utilizar instrucciones GOTO para entrar en un bloque TRY o CATCH pero se puede utilizar para saltar a una
etiqueta
dentro
del
mismo
bloque
TRY
CATCH,
bien
para
salir
de
un
bloque
TRY
CATCH.
ERROR_MESSAGE() devuelve el texto completo del mensaje de error. Este texto incluye los valores suministrados
para los parmetros reemplazables, como longitudes, nombres de objetos u horas.
Estas funciones devuelven NULL si se las llama desde fuera del mbito del bloque CATCH. Con ellas se puede recuperar
informacin sobre los errores desde cualquier lugar dentro del mbito del bloque CATCH. Por ejemplo, en la siguiente
secuencia de comandos se muestra un procedimiento almacenado que contiene funciones de control de errores. Se llama al
procedimiento almacenado en el bloque CATCH de una construccin TRYCATCH y se devuelve informacin sobre el
error.
Ejemplo, vamos a definir un procedimiento para calcular el precio unitario a partir de un importe y una cantidad:
GO
-- Creamos el procedimiento
216
AS
BEGIN TRY
SELECT @precio=@importe/@cant;
END TRY
BEGIN CATCH
END CATCH;
GO
-- Lo utilizamos
217
base
de
datos.
TRYCATCH no detecta:
Errores que tienen gravedad 20 o superior que detienen el procesamiento de las tareas de SQL Server Database
Engine en la sesin. Si se produce un error con una gravedad 20 o superior y no se interrumpe la conexin con la
base de datos, TRYCATCH controlar el error.
Un bloque CATCH no controla los siguientes tipos de errores cuando se producen en el mismo nivel de ejecucin
que la construccin TRYCATCH:
Errores que se producen durante la recompilacin de instrucciones, como errores de resolucin de nombres de
objeto que se producen despus de la compilacin debido a una resolucin de nombres diferida.
Estos errores se devuelven al nivel de ejecucin del lote, procedimiento almacenado o desencadenador.
En el ejemplo siguiente se muestra cmo la construccin TRYCATCH no captura un error de resolucin de nombre de
objeto generado por una instruccin SELECT, sino que es el bloque CATCH el que lo captura cuando la misma instruccin
SELECT se ejecuta dentro de un procedimiento almacenado (a un nivel inferior).
USE Gestion;
GO
BEGIN TRY
END TRY
BEGIN CATCH
218
END CATCH
Intentamos ejecutar una SELECT de una tabla que no existe en la base de datos. El error no se captura y el control se
transfiere fuera de la construccin TRYCATCH, al siguiente nivel superior, en este caso salta el mensaje de error del
sistema.
Al ejecutar la misma instruccin SELECT dentro de un procedimiento almacenado, el error se producir en un nivel inferior al
bloque TRY y la construccin TRYCATCH controlar el error.
GO
-- Creamos el procedimiento.
AS
GO
-- Utilizamos el procedimiento
BEGIN TRY
EXECUTE TablaInexistente
219
END TRY
BEGIN CATCH
END CATCH;
En este caso como el error se produce dentro del procedimiento, el control del error se devuelve al nivel superior (el que ha
realizado el EXECUTE) por lo que es capturado por el TRY y entra en el bloque CATCH, en vez de que salte el mensaje de
error del sistema saldr el nuestro.
9.11. Desencadenadores o TRIGGERS
Un desencadenador (o Trigger) es una clase especial de procedimiento almacenado que se ejecuta automticamente
cuando
SQL
Segn
se
Server
el
produce
permite
tipo
un
evento
crear
de
varios
evento
en
el
servidor
desencadenadores
que
los
para
de
bases
una
instruccin
desencadena
se
de
datos.
especfica.
clasifican
en:
Desencadenadores
DML
Desencadenadores
DDL
Desencadenadores
LOGON
Los desencadenadores DML se ejecutan cuando un usuario intenta modificar datos mediante un evento de lenguaje de
manipulacin de datos (DML). Los eventos DML son instrucciones INSERT, UPDATE o DELETE de una tabla o vista.
Los desencadenadores DDL se ejecutan en respuesta a una variedad de eventos de lenguaje de definicin de datos (DDL).
Estos eventos corresponden principalmente a instrucciones CREATE, ALTER y DROP de Transact-SQL, y a determinados
procedimientos
almacenados
del
sistema
que
ejecutan
operaciones
de
tipo
DDL.
Los desencadenadores logon se activan en respuesta al evento LOGON que se genera cuando se establece la sesin de un
usuario.
Nosotros limitaremos nuestro estudio a los desencadenadores DML.
9.12. CREATE TRIGGER
Esta instruccin nos permite definir un trigger:
220
al
esquema
de
la
tabla
vista
en
la
que
se
crearon.
NombreTrigger es el nombre que le queremos dar al desencadenador. No puede comenzar con los smbolos # o ##.
Tabla | vista es el nombre de la tabla o vista en la que se ejecuta el desencadenador. Slo se puede hacer referencia a una
vista mediante un desencadenador INSTEAD OF. No es posible definir desencadenadores DML en tablas temporales
locales
globales.
DELETE INSERT UPDATE Especifica las instrucciones de modificacin de datos que activan el desencadenador cuando se
intenta ejecutarlas en esta tabla o vista. Se debe especificar al menos una opcin. En la definicin del desencadenador se
permite
cualquier
combinacin
de
estas
opciones,
en
cualquier
orden.
AFTER indica que el desencadenador slo se activa cuando todas las operaciones especificadas en la instruccin SQL
desencadenadora se han ejecutado correctamente. Adems, todas las acciones referenciales en cascada y las
comprobaciones
de
el
restricciones
AFTER
es
valor
Los
desencadenadores
deben
ser
predeterminado
correctas
cuando
AFTER
no
para
slo
que
se
se
este
desencadenador
especifica
pueden
la
definir
palabra
en
se
ejecute.
clave
las
FOR.
vistas.
INSTEAD OF indica que se ejecuta el desencadenador en vez de la instruccin SQL desencadenadora, por lo que se
suplantan
las
acciones
de
las
instrucciones
desencadenadoras.
Como mximo, se puede definir un desencadenador INSTEAD OF por cada instruccin INSERT, UPDATE o DELETE en
cada tabla o vista. No obstante, en las vistas es posible definir otras vistas que tengan su propio desencadenador INSTEAD
OF.
Los desencadenadores INSTEAD OF no se pueden utilizar en vistas actualizables que usan WITH CHECK OPTION.
Los desencadenadores INSTEAD OF DELETE/UPDATE no se permiten en tablas que tengan una clave ajena definida con
ON
DELETE/UPDATE
CREATE
TRIGGER
debe
ser
la
primera
CASCADE.
instruccin
en
el
proceso
por
lotes.
Un desencadenador se crea solamente en la base de datos actual; sin embargo, puede hacer referencia a objetos que estn
fuera
de
la
base
de
datos
actual.
Si se especifica el nombre del esquema del desencadenador hay que calificar tambin el nombre de la tabla o vista.
En un desencadenador se puede especificar cualquier instruccin SET. La opcin SET seleccionada permanece en efecto
durante la ejecucin del desencadenador
Un desencadenador est diseado para comprobar o cambiar los datos en base a una instruccin de modificacin o
definicin de datos; no debe devolver datos al usuario por lo que se aconseja no incluir en un desencadenador instrucciones
SELECT que devuelven resultados ni las instrucciones que realizan una asignacin variable. Si es preciso que existan
asignaciones de variable en un desencadenador, tenemos que utilizar la instruccin SET NOCOUNT al principio del mismo
para
impedir
la
devolucin
de
cualquier
conjunto
de
resultados.
Los desencadenadores DML usan las tablas lgicas deleted e inserted. Son de estructura similar a la tabla en que se
define el desencadenador, es decir, la tabla en que se intenta la accin del usuario. Las tablas deleted e inserted guardan
los
valores
antiguos
nuevos
de
las
filas
que
la
accin
del
usuario
puede
cambiar.
Si un desencadenador INSTEAD OF definido en una tabla ejecuta una instruccin en la tabla que normalmente volvera a
activarlo, al desencadenador no se lo llama de forma recursiva. En su lugar, la instruccin se procesa como si la tabla no
221
de
restriccin
activa
cualquier
desencadenador
AFTER
INSERT
definido
para
la
tabla.
Si un desencadenador INSTEAD OF definido en una vista ejecuta una instruccin en la vista que normalmente volvera a
activarlo, no se llamar el desencadenador de forma recursiva. En su lugar, la instruccin se resuelve a modo de
modificaciones en las tablas base subyacentes de la vista. En este caso, la definicin de la vista debe cumplir todas las
restricciones
para
una
vista
actualizable.
Aunque una instruccin TRUNCATE TABLE es en realidad un desencadenador DELETE, no puede activar un
desencadenador
porque
Las
instrucciones
siguientes
ALTER
la
operacin
no
Transact-SQL
DATABASE
registra
no
CREATE
estn
las
eliminaciones
permitidas
en
DATABASE
un
de
fila
individuales.
desencadenador
DROP
DML:
DATABASE
Adems, las siguientes instrucciones Transact-SQL no se permiten en el cuerpo de un desencadenador DML cuando ste
se
utiliza
CREATE
en
la
INDEX
tabla
o
ALTER
vista
que
INDEX
es
objeto
DROP
de
la
INDEX
accin
desencadenadora:
DROP
TABLE
Cambiar particiones.
Ejemplo:
USE Gestion8
GO
AS
222
WHERE numemp=inserted.rep;
GO
Cuando se INSERTe un pedido, entrar en funcionamiento el trigger ActualizaVentasEmpleado y se ejecutarn las
instrucciones que aparecen despus de AS, en este caso actualizar (UPDATE) la tabla empleados sumar a las ventas del
empleado (ventas) el importe del pedido insertado (inserted.importe), y slo actualizar el empleado cuyo numemp coincida
con el campo rep del pedido insertado (WHERE numemp=inserted.rep).
VALUES (123456789,getdate(),108,2103,10,100,'Aci',41001)
ALTER TRIGGER
Permite modificar la definicin del desencadenador, no permite cambiar su nombre, para cambiar el nombre de un
desencadenador hay que eliminarlo (DROP TRIGGER) y volver a crearlo (CREATE TRIGGER).
ON {tabla|vista}
223
La
sintaxis
es
similar
la
instruccin
CREATE
TRIGGER.
Ejemplo:
AS
pedido,
el
empleado
correspondiente
no
se
actualizar.
224
VALUES (123456791,getdate(),108,2103,10,300,'Aci',41001)
225
VALUES (123456792,getdate(),108,2103,10,400,'Aci',41001)
226