Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
1.1. Introduccin
SQL Server 2005 es un sistema gestor de bases de datos relacionales de Microsoft
Corporation orientado a sistemas medianos y grandes aunque tambin puede rodar en
ordenadores personales. SQL Server Management Studio (SSMS) es la herramienta de
SQL Server que permite definir y gestionar todas las bases de datos almacenadas en el
servidor SQL Server 2005.
En este tema veremos cmo utilizar el SQL Server Management Studio para manejar
las bases de datos del servidor y organizaremos el texto en los siguientes puntos:
Existen diferentes versiones (ediciones) del producto, por lo que es un producto muy
verstil, que puede cumplir con las exigencias de cualquier empresa, puede ser utilizado
para gestionar bases de datos en un PC en modo local a gestionar todo el sistema de
informacin de grandes empresas pasando por sistemas que requieran menos potencia y
por sistemas mviles.
Para realizar este curso te recomendamos instalar la versin gratuita: Express. Puedes
descargarla desde la pgina web de Microsoft, desde el enlace para iniciar descarga. Si
quieres ver las diferentes ediciones y sus caractersticas principales visita el siguiente
avanzado
Tan slo deberemos seguir el asistente. Los puntos ms importantes a tener en cuenta
son:
Las bases de datos de SQL Server 2005 utilizan tres tipos de archivos:
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.
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
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.
La opcin Adjuntar slo se utiliza la primera vez, cuando todava no tenemos la base
de datos en el disco.
sto es as porque SQL Server sigue en marcha, a pesar de que se cierre el gestor. Ten
en cuenta que el servidor de base de datos normalmente se crea para que sirva
informacin a diferentes programas, por eso sera absurdo que dejara de funcionar
cuando cerramos el programa gestor, que slo se utiliza para realizar modificaciones
sobre la base.
Para poder realizar acciones sobre la base de datos, sta debe estar desconectada.
Para ello, desde el SSMS, desplegamos el men contextual de la base de datos que nos
interese manipular y seleccionaremos la opcin Poner fuera de conexin:
Para volver a conectar la base de datos y seguir trabajando con ella, accederemos al
mismo men contextual pero elegiremos la opcin Poner en conexin:
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.
Algunos tipos no necesitan ms, como por ejemplo el tipo entero (int), y otros se
pueden completar con una longitud, como los tipos alfanumricos:
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.
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.
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.
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:
O simplemente hacemos clic en la zona a la izquierda del nombre y pulsamos la tecla
Supr.
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.
Desde el entorno grfico del SSMS podemos definir claves ajenas entrando en el
diseo de la tabla y desplegando el men contextual del campo que va a ser clave ajena:
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.
La llave indica la tabla principal (padre) y el smbolo infinito seala la tabla que contiene
la clave ajena.
Para ello debemos abrir la zona de trabajo de tipo Query, abriendo una nueva consulta,
seleccionando previamente el servidor y pulsando el botn de la barra
de botones o si queremos realizar la consulta sobre un servidor 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.
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.
Cuando creamos una nueva consulta, sta actuar sobre la base de datos activa en
ese momento. Por defecto la base de datos activa es la predeterminada (master). Si
queremos que la base de datos activa sea por ejemplo la base de datos ventas, hacemos
clic sobre su nombre en el Explorador de objetos, y sta pasar a ser la base de datos
activa. Si ahora creamos una nueva consulta, sta actuar sobre la base de datos ventas.
Si queremos crear una consulta que siempre acte sobre una determinada base de
datos y no nos queremos preocupar de qu base de datos tenemos activa podemos
aadir al principio de la consulta la instruccin USE nombreBaseDatos; esto har que
todas las instrucciones que aparezcan despus, se ejecuten sobre la base de datos
indicada.
Por ejemplo:
USE ventas;
SELECT * FROM pedidos;
Obtiene todos los datos de la tabla pedidos que se encuentra en la base de datos
ventas.
Si no utilizamos USE y almacenamos la consulta, al abrirla otra vez, coger como base de
datos la predeterminada (no la activa) y se volver a ejecutar sobre la base de datos
master.
Color Categora
Rojo Cadena de caracteres
Verde oscuro Comentario
Negro sobre fondo plateado Comando SQLCMD
Fucsia Funcin del sistema
Verde Tabla del sistema
Azul Palabra clave
Verde azulado Nmeros de lnea o parmetro de plantilla
Rojo oscuro Procedimiento almacenado de SQL Server
Gris oscuro Operadores
1.23. Configurar un esquema de colores personalizado
En el men Herramientas > Opciones, desplegando la opcin Entorno, Fuentes y
colores, se puede ver la lista completa de colores y sus categoras, as como configurar
un esquema de colores personalizado:
En la lista Mostrar valores para, seleccionamos el entorno que se ver afectado.
Ahora slo nos queda aprender a redactar sentencias SQL, cosa que se ver en otro
momento, mientras tanto podemos utilizar el Generador de Consulta que incluye SSMS y
que veremos a continuacin en el apartado sobre vistas.
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.
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).
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.
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.
Como ejemplos de sistemas gestores de bases de datos que utilizan SQL podemos
citar DB2, SQL Server, Oracle, MySql, Sybase, PostgreSQL o Access.
Ejercer un control sobre los datos tal como la asignacin de privilegios de acceso a
los datos (GRANT/REVOKE).
La gestin de transacciones (COMMIT/ROLLBACK).
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 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.
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.
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.
TRANSACT-SQL es un lenguaje muy potente que nos permite definir casi cualquier
tarea que queramos efectuar sobre la base de datos. En este tema veremos que
TRANSACT-SQL va ms all de un lenguaje SQL cualquiera ya que 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.
Estructuras de control de flujo.
Gestin de excepciones.
Funciones predefinidas.
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.
Por ejemplo:
Esta instruccin nos permite SELECCIONAR el cdigo y nombre DE los Clientes CUYA
localidad sea Valencia.
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.
CREATE (Crear)
DROP (Eliminar)
ALTER (Modificar)
Permite crear una base de datos llamada mibase, a continuacin escribiremos las
dems clusulas que completarn la accin, en este caso dnde se almacenar la base
de datos, cunto ocupar, etc...
Permite crear una nueva tabla llamada mitabla, entre parntesis completaremos la
accin indicando la definicin de las columnas de la tabla.
Por ejemplo:
En esta sentencia nos aparecen dos clusulas, la clusula FROM que nos permite
indicar de dnde hay que coger los datos y la clusula WHERE que permite indicar una
condicin de seleccin.
Otra caracterstica de una sentencia SQL es que acaba con un punto y coma (;)
originalmente ste era obligatorio y serva para indicar el fin de la instruccin, pero ahora
se puede omitir, aunque se recomienda su uso.
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.
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).
SQL Server proporciona un conjunto de tipos de datos del sistema que define todos los
tipos de datos que pueden utilizarse. Tambin podemos definir nuestros propios tipos de
datos en Transact-SQL o Microsoft .NET Framework.
Los tipos de datos ms utilizados son:
Si quieres conocer todos los tipos de datos disponibles en SQLServer 2005, visita el
siguiente avanzado .
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 .
Tipos de operadores:
- Operadores numricos:
suma +
resta -
multiplicacin *
divisin /
mdulo
%
(resto de una divisin)
AND &
OR |
OR exclusivo ^
- Operadores de comparacin:
Igual a =
Mayor que >
Menor que <
Mayor o igual que >=
Menor o igual 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
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.
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.
Para asignar un valor a una variable, la asignacin se realiza con la palabra SELECT y
el signo igual con el formato:
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.
Por ejemplo:
SELECT @empleados = 0;
/* Esto es un comentario
/* */ Varias lneas en varias lneas */
-- Una nica lnea -- Esto es un comentario en una nica lnea.
USE nbBaseDeDatos
Hace que la base de datos activa pase a ser la base de datos indicada en la instruccin,
las consultas que se ejecuten a continuacin se harn sobre tablas de esa base de datos
si no se indica lo contrario. Es una instruccin til para asegurarnos de que la consulta se
ejecuta sobre la base de datos correcta.
GO
BEGIN...END
3.1. Introduccin
Vamos a empezar por la instruccin que ms se utiliza en SQL, la sentencia SELECT.
La sentencia SELECT es, con diferencia, la ms compleja y potente de las sentencias
SQL, con ella podemos recuperar datos de una o ms tablas, seleccionar ciertos registros
e incluso obtener resmenes de los datos almacenados en la base de datos. Es tan
compleja que la estudiaremos a lo largo de varias unidades didcticas incorporando poco
a poco nuevas funcionalidades.
El resultado de una SELECT es una tabla lgica que alberga las filas resultantes de la
ejecucin de la sentencia.
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 ]]
<origen>::=
nb_tabla | nb_vista [[ AS ] alias_tabla ]
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.
Cuando no se definen esquemas, SQL-Server crea uno por defecto en cada base de
datos denominado dbo.
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.
Podemos escribir:
SELECT ...
FROM tabla1 Sacamos los datos de la tabla tabla1
SELECT ...
FROM tabla1 t1 Sacamos los datos de la tabla tabla1 y le
asignamos un alias de tabla: 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.
<lista_seleccion> ::=
{ *
| {nombre_tabla|nombre_vista|alias_tabla}.*
| { [{nombre_tabla|nombre_vista|alias_tabla}.]
{nb_columna|$IDENTITY|$ROWGUID}
|<expresion>
}[[AS] alias_columna]
| alias_columna = <expresion>
} [ ,...n ]
Separamos la definicin de cada columna por una coma y las columnas del resultado
aparecern en el mismo orden que en la lista de seleccin.
Para cada columna del resultado su tipo de datos, tamao, precisin y escala son los
mismos que los de la expresin que da origen a esa columna.
El resultado sera:
El resultado sera:
El alias de columna se indica mediante la clusula AS. Se escribe el nuevo texto tal cual
sin comillas siguiendo las reglas de los identificadores.
Ejemplo:
El resultado ser :
Numclie nombrecliente
2101 Luis Garca Antn
2102 Alvaro Rodrguez
2103 Jaime Llorens
en vez de:
Numclie nombre
2101 Luis Garca Antn
2102 Alvaro Rodrguez
2103 Jaime Llorens
La palabra AS es opcional.
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:
Ver
Funcin Descripcin
+
GETDATE Devuelve la fecha actual.
GETUTCDATE Devuelve la hora UTC.
DATEPART Devuelve un entero que corresponde a la parte de la fecha solicitada.
DAY Devuelve el da de la fecha indicada.
MONTH Devuelve el mes de la fecha indicada.
YEAR Devuelve el ao de la fecha indicada.
Devuelve una cadena de caracteres que representa el valor de la unidad especificada de
DATENAME
una fecha especificada.
Devuelve un valor datetime nuevo que resulta de sumar un intervalo de tiempo a una
DATEADD
fecha especificada.>
DATEDIFF Devuelve el n de intervalos que hay entre dos fechas.
@@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.
Funciones de cadena:
Funcin Descripcin
Devuelve el valor de cdigo ASCII del carcter situado ms a la izquierda de una expresin
ASCII
de caracteres.
CHAR Devuelve el carcter ASCII del entero indicado.
NCHAR Devuelve el carcter Unicode del entero indicado.
UNICODE Devuelve el entero que se corresponde al carcter Unicode indicado.
LEN Devuelve el total de caracteres de una cadena, excluidos los espacios en blanco finales.
LTRIM Devuelve una cadena tras quitarle los espacios en blanco iniciales.
RTRIM Devuelve una cadena tras quitarle los espacios en blanco finales.
LEFT Devuelve los N ltimos caracteres de una cadena.
RIGHT Devuelve los N primeros caracteres de una cadena.
SUBSTRING Devuelve parte de una expresin.
LOWER Devuelve la cadena convertida a minsculas.
UPPER Devuelve la cadena convertida a maysculas.
REPLACE Reemplaza una determinada cadena.
Elimina el nmero de caracteres especificado e inserta otro conjunto de caracteres en el
STUFF
punto de inicio indicado.
Devuelve una cadena Unicode con los delimitadores agregados para convertirla en un
QUOTENAME
identificador delimitado vlido de Microsoft SQL Server 2005.
SPACE Devuelve una cadena de espacios repetidos.
STR Devuelve una cadena de caracteres a partir de datos numricos.
REPLICATE Repite una cadena N veces.
REVERSE Devuelve una cadena invertida.
CHARINDEX Devuelve la posicin inicial de la expresin especificada en una cadena de caracteres.
Devuelve la posicin inicial de la primera repeticin de un patrn en la expresin
PATINDEX especificada, o ceros si el patrn no se encuentra, en todos los tipos de datos de texto y
caracteres.
Otras funciones:
Funcin Descripcin
El resultado ser:
SELECT idfab,idproducto,descripcion,(existencias*precio) AS
valoracion
FROM productos;
El resultado sera:
El resultado ser:
Listar las ventas en cada oficina con el formato: 22 tiene ventas de 186,042.00
El resultado sera:
oficina ventas
1
SELECT *
FROM oficinas;
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.
Es equivalente a:
Podemos indicar una columna o varias separadas por una coma, la columna de
ordenacin se especifica mediante el nombre de columna en el origen de datos o su
posicin dentro de la lista de seleccin. Si utilizamos el nombre de columna, no hace falta
que la columna aparezca en la lista de seleccin. Si utilizamos la posicin es la posicin
de la columna dentro de la lista de seleccin empezando en 1.
Ejemplos:
Mostrar las ventas de cada oficina, ordenadas por orden alfabtico de regin y dentro
de cada regin por ciudad.
Da como resultado:
Listar las oficinas de manera que las oficinas de mayores ventas aparezcan en primer
lugar.
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.
SELECT dir
FROM oficinas;
dir
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:
FROM oficinas;
dir
NULL
104
105
106
108
Los que se eliminan son valores duplicados de filas del resultado, por ejemplo:
FROM oficinas;
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.
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.
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.
Obtenemos:
Se incluyen en el resultado todos los registros que tienen ventas iguales al ltimo
registro.
Otro ejemplo:
Devuelve las 10 peores oficinas en cuanto a ventas: ordenamos las oficinas por ventas
de menor a mayor y sacamos las 10 primeras.
Devuelve:
WHERE <condicion_bsqueda>
<condicion_bsqueda> ::=
{ [NOT]<predicado>
|(<condicion_bsqueda>)
}
[{AND|OR} [NOT] {<predicado>|(<condicion_bsqueda>)}]
[ ...n ]
En el resultado de la consulta slo aparecern las filas que cumplan que la condicin de
bsqueda sea TRUE, los valores NULL no se incluyen, por lo tanto, en las filas del
resultado. La condicin de bsqueda puede ser una condicin simple o una condicin
compuesta por varias condiciones (predicados) unidas por operadores AND y OR, no hay
lmite en cuanto al nmero de predicados que se pueden incluir. En las condiciones
compuestas se pueden utilizar parntesis para delimitar predicados y se aconseja su uso
cuando se incluyen operadores AND y OR en la misma condicin de bsqueda.
3.14. Predicados
En SQL tenemos 7 tipos de predicados, condiciones bsicas de bsqueda:
Comparacin estndar
Pertenencia a un intervalo (BETWEEN)
Pertenencia a un conjunto (IN)
Test de valor nulo (IS NULL).
Coincidencia con patrn (LIKE)
Si contiene (CONTAINS)
FREETEXT
Comparacin estndar.
Compara el valor de una expresin con el valor de otra. Para la comparacin se pueden
emplear = , <> , !=, < , <= , !<, > , >= ,!>
Sintaxis:
Un nombre de columna,
una constante,
una funcin (inclusive la funcin CASE),
una variable,
una subconsulta escalar o
cualquier combinacin de nombres de columna, constantes y funciones conectados
mediante uno o varios operadores o una subconsulta.
Ejemplo:
Hallar oficinas cuyas ventas estn por debajo del 80% de su objetivo:
SELECT oficina
FROM oficinas
WHERE ventas < (.8 * objetivo);
SELECT oficina
FROM oficinas
WHERE dir = 108;
Examina si el valor de la expresin de test est en el rango delimitado por los valores
resultantes de expresion1 y expresion2, estos valores no tienen porqu estar ordenados
en ANSI/ISO; expresion1 debe ser menor o igual a expresion2.
Ejemplo:
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.
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:
Resultado:
Se utiliza cuando queremos comparar el valor de una columna con un patrn en el que
se utilice caracteres comodines.
SELECT numemp,nombre
FROM empleados
numemp nombre
101 Antonio Viguer
108 Ana Bustamante
SELECT numemp,nombre
FROM empleados
numemp nombre
104 Jos Gonzlez
107 Jos Gonzlez
SELECT numemp,nombre
FROM empleados
numemp nombre
101 Antonio Viguer
104 Jos Gonzlez
106 Luis Antonio
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).
SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE '[a-d]%';
Es equivalente a escribir:
SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE '[abcd]%';
SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE '[^abcd]%';
SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE '[^a-d]%';
[ESCAPE 'car_escape']
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 '!';
Para practicar puedes realizar este Ejercicio Test de correspondencia con LIKE.
Como siempre, se pueden utilizar parntesis para alterar esta prioridad en una
condicin de bsqueda.
Los operadores lgicos pueden devolver tres valores distintos: TRUE, FALSE, NULL
(UNKNOWN).
Hallar los vendedores que estn por debajo de su cuota y tienen ventas inferiores a
30.000.
SELECT nombre
FROM empleados
WHERE ventas < cuota AND ventas < 30000;
Hallar los vendedores que estn debajo de su cuota, pero cuyas ventas no sean
inferiores a 150.000.
SELECT nombre
FROM empleados
WHERE ventas < cuota AND ventas < 150000;
SELECT oficina
FROM oficinas
WHERE NOT dir = 108;
SELECT oficina
FROM oficinas
WHERE dir <> 108;
Devuelven:
oficina
11
12
13
Las oficinas sin director no aparecen, para que aparezcan deben aadir otro predicado:
oficina dir
11 106
12 104
13 105
26 NULL
28 NULL
Para practicar puedes realizar este Ejercicio Consultas con mltiples condiciones.
4.1. Introduccin
Hasta ahora hemos visto consultas que obtienen los datos de una sola tabla, en este
tema veremos cmo obtener datos de diferentes tablas.
En esta parte ampliaremos la clusula FROM y descubriremos nuevas palabras
reservadas (UNION, EXCEPT e INTERSECT) que corresponden a operaciones
relacionales.
Para obtener datos de varias tablas tenemos que combinar estas tablas mediante alguna
operacin basada en el lgebra relacional.
El lgebra relacional define una serie de operaciones cuyos operandos son tablas y cuyo
resultado es tambin una tabla.
Las operaciones de lgebra relacional implementadas en Transact-Sql son:
La unin UNION
La diferencia EXCEPT
La interseccin INTERSECT
El producto cartesiano CROSS JOIN
La composicin interna INNER JOIN
La composicin externa LEFT JOIN, RIGHT JOIN Y FULL JOIN
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 > representa la especificacin de la consulta que nos devolver la tabla a
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:
El resultado sera:
OFI ciudad
11 Valencia
28 Valencia
23 Madrid
ORDER BY ofi;
OFI ciudad
11 Valencia
23 Madrid
28 Valencia
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:
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.
{<consulta>|(<consulta>)}
EXCEPT
{<consulta>|(<consulta>)}
[{EXCEPT {<consulta>|(<consulta>)}}[ ...n ] ]
[ORDER BY {expression_columna|posicion_columna [ASC|DESC]}
[ ,...n ]]
Por ejemplo tenemos las tablas T1 y T2.
T1 T2
Cod
Codigo
1
2
2
3
4
4
5
5
6
Devuelve:
Cod
1
6
Ejemplo:
Listar los productos que no aparezcan en ningn pedido.
{ <consulta>|(<consulta>)}
INTERSECT
{<especificacion_consulta>|(<especificacion_consulta>)}
[{INTERSECT {<consulta>|(<consulta>)}} [ ...n ] ]
[ORDER BY {expression_columna|posicion_columna [ASC|DESC]}
[ ,...n ]]
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.
Empezaremos por estudiar la operacin a partir de la cual estn definidas las dems
operaciones de composicin de tabla, el producto cartesiano.
Tabla_origen puede ser un nombre de tabla o de vista o una tabla derivada (resultado
de una SELECT), en este ltimo caso la SELECT tiene que aparecer entre parntesis y la
tabla derivada debe llevar asociado obligatoriamente un alias de tabla. Tambin puede ser
una composicin de tablas.
Se pueden utilizar hasta 256 orgenes de tabla en una instruccin, aunque el lmite vara
en funcin de la memoria disponible y de la complejidad del resto de las expresiones de la
consulta. Tambin se puede especificar una variable table como un origen de tabla.
Ejemplo:
SELECT *
FROM empleados, oficinas;
Si ejecutamos esta consulta veremos que las filas del resultado estn formadas por las
columnas de empleados y las columnas de oficinas. En las filas aparece cada empleado
combinado con la primera oficina, luego los mismos empleados combinados 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.
SELECT *
FROM empleados, oficinas
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.
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;
Para practicar puedes realizar este Ejercicio El producto cartesiano CROSS JOIN.
FROM
<tabla_origen> INNER JOIN <tabla_origen> ON <condicion_combi>
SELECT *
FROM empleados INNER JOIN oficinas
ON empleados.oficina=oficinas.oficina;
SELECT *
FROM pedidos INNER JOIN productos
ON producto = idproducto AND fab = idfab;
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.
ON empleados.oficina=oficinas.oficina;
Para resolver este problema debemos utilizar otro tipo de composicin, la composicin
externa.
Para practicar puedes realizar este Ejercicio La composicin interna INNER JOIN.
Sintaxis
FROM
<tabla_origen> {LEFT|RIGHT|FULL} [OUTER] JOIN <tabla_origen>
ON <condicion_combi>
ON empleados.oficina=oficinas.oficina;
Obtiene los empleados con su oficina y los empleados (tabla a la izquierda LEFT del
JOIN) que no tienen oficina aparecern tambin en el resultado con los campos de la tabla
oficinas rellenados a NULL.
Obtiene los empleados con su oficina y las oficinas (tabla a la derecha RIGHT del JOIN)
que no tienen empleados aparecern tambin en el resultado con los campos de la tabla
empleados rellenados a NULL.
ON empleados.oficina=oficinas.oficina;
Aparecen tanto los empleados sin oficina como las oficinas sin empleados.
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:
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.
Si necesitamos LEFT y RIGHT entonces utilizamos FULL JOIN.
Para practicar puedes realizar este Ejercicio La composicin externa LEFT JOIN y
RIGHT JOIN.
Por ejemplo:
O bien:
ON empleados.oficina = oficinas.oficina);
Ejercicio propuesto de la Unidad 4 Prueba evaluativa de la Unidad 4
5.1. Introduccin
Una de las funcionalidades de la sentencia SELECT es el permitir obtener resmenes
de los datos contenidos en las columnas de las tablas.
Para poder llevarlo a cabo la sentencia SELECT consta de una serie de clusulas
especficas (GROUP BY, HAVING), y Transact-SQL tiene definidas unas funciones para
poder realizar estos clculos, las funciones de agregado (tambin llamadas funciones de
columna).
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
Expresion puede ser de cualquier tipo excepto text, image o ntext. No se permite
utilizar funciones de agregado ni subconsultas. El tipo de dato devuelto es int.
Si el nmero de valores devueltos por expresion es superior a 231-1, COUNT genera un
error, en ese caso hay que utilizar la funcin COUNT_BIG.
La funcin cuenta los valores distintos de NULL que hay en la columna. La palabra ALL
indica que se tienen que tomar todos los valores de la columna, mientras que DISTINCT
hace que se consideren todas las repeticiones del mismo valor como uno solo. Estos
parmetros son opcionales, por defecto se considera ALL.
Por ejemplo:
Devuelve 4 porque tenemos cuatro valores distintos, no nulos, en la columna regin, los
valores repetidos los considera slo una vez. Ahora s nos devuelve cuntas regiones
tenemos en oficinas.
Si utilizamos * en vez de expresin, devuelve el nmero de filas del origen que nos
quedan despus de ejecutar la clusula WHERE.
Por ejemplo:
Es mejor que:
Las dos nos devuelven el nmero de empleados que tienen una oficina asignada pero
la primera es mejor porque se calcula ms rpidamente.
Devuelve la suma de las ventas de todas las oficinas y de los objetivos de todas las
oficinas, el de mayor importe.
Es una funcin de agregado que genera como salida una columna adicional con el valor
1 si la fila se agrega mediante el operador CUBE o ROLLUP, o el valor 0 cuando la fila no
es el resultado de CUBE o ROLLUP.
Nb_columna tiene que ser una de las columnas de agrupacin y la clusula GROUP BY
debe contener el operador CUBE o ROLLUP.
En el siguiente punto, cuando veamos las clusulas CUBE y ROLLUP quedar ms claro.
Muchas veces cuando calculamos resmenes nos interesan totales parciales, por
ejemplo saber de cada empleado cunto ha vendido, y cul ha sido su pedido mximo, de
cada cliente cundo fue la ltima vez que nos compr, etc.
En todos estos casos en vez de obtener una fila nica de resultados necesitamos una fila
por cada empleado, cliente, etc.
Una consulta con una clusula GROUP BY agrupa los datos de la tabla origen y
produce una nica fila resultado por cada grupo formado. Las columnas indicadas en el
GROUP BY se llaman columnas de agrupacin o agrupamiento .
Cuando queremos realizar una agrupacin mltiple, por varias columnas, stas se
indican en la clusula GROUP BY en el orden de mayor a menor agrupacin igual que con
la clusula ORDER BY.
expresion_agrupacion puede ser una columna o una expresin no agregada que haga
referencia a una columna devuelta por la clusula FROM. Un alias de columna que est
definido en la lista de seleccin no puede utilizarse para especificar una columna de
agrupamiento.
No se pueden utilizar columnas de tipo text, ntext e image en expresion_agrupacion.
Ejemplo:
Resultado:
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.
Ejemplo:
Resultado:
Nmero Importe
rep clie
de pedidos mximo
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
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
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.
Resultado:
Nmero Importe
rep clie
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.
Por ejemplo:
Resultado:
Nmero Importe
rep clie
de pedidos mximo
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
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
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:
Resultado:
Nmero Importe
rep clie
de pedidos mximo
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
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
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.
Las filas que corresponden a subtotales aparecen con un 1 y las normales con un cero.
HAVING funciona igual que la clusula WHERE pero en vez de actuar sobre las filas del
origen de datos, acta sobre las filas del resultado, selecciona grupos de filas por lo que la
condicin de bsqueda sufrir alguna limitacin, la misma que para la lista de seleccin:
Ejemplo:
SELECT oficina, count(numemp) AS [Nmero de empleados]
FROM empleados
GROUP BY oficina
HAVING COUNT(numemp)<2;
Resultado:
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:
HAVING SUM(ventas)=10000
Para practicar puedes realizar este Ejercicio Seleccin sobre agrupaciones con
HAVING.
6.1. Introduccin
Una subconsulta es una consulta que aparece dentro de otra consulta o subconsultas,
en la lista de seleccin o en la clusula WHERE o HAVING, originalmente no se podan
incluir en la lista de seleccin.
Una subconsulta se denomina tambin consulta o seleccin interna, mientras que la
instruccin que contiene la subconsulta es conocida como consulta o seleccin externa.
Aparece siempre encerrada entre parntesis y tiene la misma sintaxis que una
sentencia SELECT normal con alguna limitacin:
No puede incluir una clusula COMPUTE o FOR BROWSE y slo puede incluir una
clusula ORDER BY cuando se especifica tambin una clusula TOP.
Una subconsulta puede anidarse en la clusula WHERE o HAVING de una instruccin
externa SELECT, INSERT, UPDATE o DELETE, o bien en otra subconsulta. Se puede
disponer de hasta 32 niveles de anidamiento, aunque el lmite vara dependiendo de la
memoria disponible y de la complejidad del resto de las expresiones de la consulta. Hay
que tener en cuenta que para cada fila de la consulta externa, se calcula la subconsulta, si
anidamos varias consultas, el nmero de veces que se ejecutarn las subconsultas
puede dispararse!
Ejemplo de subconsulta: Listar los empleados cuya cuota no supere el importe vendido
por el empleado.
SELECT nombre
FROM empleados
WHERE cuota <= (SELECT SUM(importe)
FROM pedidos
WHERE rep = numemp);
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).
La columna oficina se encuentra en los dos orgenes (oficinas y empleados) pero esta
consulta no dar error (no se nos pedir cualificar los nombres como pasara en una
composicin de tablas), dentro de la subconsulta se considera oficina el campo de la tabla
empleados. Con lo que comparara la oficina del empleado con la misma oficina del
empleado y eso no es lo que queremos, queremos comparar la oficina del empleado con
la oficina de oficinas, lo escribiremos pues as para forzar a que busque la columna en la
tabla oficinas.
Los operadores de comparacin sin modificar son los operadores de comparacin que
vimos con la clusula WHERE.
Sintaxis:
En este caso la segunda expresin ser una subconsulta, con una sola columna en la
lista de seleccin y deber devolver una nica fila como mucho.
Ese valor nico ser el que se compare con el resultado de la primera expresin.
Si la subconsulta no devuelve ninguna fila, la comparacin opera como si la segunda
expresin fuese nula.
Si la subconsulta devuelve ms de una fila o ms de una columna, da error.
Ejemplo:
SELECT nombre
FROM empleados
WHERE cuota <= (SELECT SUM(importe)
FROM pedidos
WHERE rep = numemp);
La subconsulta devuelve una sola columna y como mucho una fila ya que es una
consulta de resumen sin clusula GROUP BY.
Ejemplo:
SELECT *
FROM empleados
WHERE oficina IN (SELECT oficina
FROM oficinas
WHERE region = 'Este');
Por cada empleado se calcula la lista de las oficinas del Este (n de oficina) y se
evala si la oficina del empleado est en esta lista. Obtenemos pues los empleados
de oficinas del Este.
La lista generada est vaca por lo que la condicin IN devuelve FALSE y en este caso
no sale ningn empleado.
SELECT empleados.*
FROM Empleados INNER JOIN oficinas ON empleados.oficina =
oficinas.oficina
WHERE region = 'Este';
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.
* 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
WHERE oficina NOT IN (SELECT oficina
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
WHERE oficina NOT IN (SELECT oficina
FROM empleados
WHERE oficina IS NOT NULL);
En este caso, como un empleado puede tener varios pedidos hay que aadir DISTINCT
para eliminar las repeticiones de empleados (si un empleado tiene varios pedidos de ACI
aparecera varias veces).
Sin embargo esta sentencia con NOT IN, queremos los empleados que no tienen
pedidos de ACI:
Esta consulta devuelve los empleados que tienen pedidos que no son de ACI, pero un
empleado puede tener pedidos de ACI y otros de otros fabricantes y por estos otros
saldra en el resultado cuando s tiene pedidos de ACI y no debera salir.
Hay que tener mucho cuidado con este tipo de preguntas.
El test ANY
ANY significa que, para que una fila de la consulta externa satisfaga la condicin
especificada, la comparacin se debe cumplir para al menos un valor de los devueltos por
la subconsulta.
Por cada fila de la consulta externa se evala la comparacin con cada uno de los
valores devueltos por la subconsulta y si la comparacin es True para alguno de los
valores ANY es verdadero, si la comparacin no se cumple con ninguno de los valores de
la consulta, ANY da False a no ser que todos los valores devueltos por la subconsulta
sean nulos en tal caso ANY dar NULL.
Si la subconsulta no devuelve filas ANY da False incluso si expresion es nula.
Ejemplo:
SELECT *
FROM empleados
WHERE cuota > ANY (SELECT cuota
FROM empleados empleados2
WHERE empleados.oficina = empleados2.oficina);
Obtenemos los empleados que tienen una cuota superior a la cuota de alguno de sus
compaeros de oficina, es decir los empleados que no tengan la menor cuota de su
oficina.
El test ALL
SELECT *
FROM empleados
WHERE cuota > ALL (SELECT cuota
FROM empleados empleados2
WHERE empleados.oficina = empleados2.oficina);
En el ejemplo anterior obtenemos los empleados que tengan una cuota superior a todas
las cuotas de la oficina del empleado. Podramos pensar que obtenemos el empleado de
mayor cuota de su oficina pero no lo es, aqu tenemos un problema, la cuota del empleado
aparece en el resultado de subconsulta por lo tanto > no se cumplir para todos los
valores y slo saldrn los empleados que no tengan oficina (para los que la subconsulta
no devuelve filas).
Para salvar el problema tendramos que quitar del resultado de la subconsulta la cuota
del empleado modificando el WHERE:
De esta forma saldran los empleados que tienen una cuota mayor que cualquier otro
empleado de su misma oficina.
O bien
Para no considerar los empleados que tengan la misma cuota que el empleado. En este
caso saldran los empleados con la mayor cuota de sus oficina, pero si dos empleados
tienen la misma cuota superior, saldran, hecho que no sucedera con la otra versin.
Ejemplo:
SELECT *
FROM empleados
WHERE EXISTS (SELECT *
FROM pedidos
WHERE numemp = rep and fab ='ACI');
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
WHERE EXISTS (SELECT *
FROM pedidos
WHERE fab ='ACI');
Sea el empleado que sea, la subconsulta siempre devolver filas (si existe algn
pedido cuyo fabricante sea ACI) o nunca, indistintamente del empleado que sea, por lo
que se obtendrn todos los empleados o ninguno para que el resultado vare segn las
filas de la consulta externa habr que incluir una referencia externa.
Otra cosa a tener en cuenta es que la lista de seleccin de una subconsulta que se
especifica con EXISTS casi siempre consta de un asterisco (*). No hay razn para
enumerar los nombres de las columnas porque no se van a utilizar y supone un trabajo
extra para el sistema.
SELECT *
FROM empleados
WHERE NOT EXISTS (SELECT *
FROM pedidos
WHERE fab ='ACI' AND rep=numemp);
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
FROM ...
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.
Para practicar puedes realizar este Ejercicio Insertar datos creando una nueva tabla.
<destino> ::=
{
[nbBaseDatos.nbEsquema. | nbEsquema.]nbTablaVista
}
Con esta instruccin podemos insertar una fila de valores determinados o un conjunto
de filas derivadas de otra consulta.
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.
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.
Aqu no hemos indicado una lista de columnas luego los valores se tienen que indicar
en el mismo orden que las columnas dentro de la tabla, si nos equivocamos de orden, el
valor se guardar en una columna errnea (si los tipos son compatibles) o generar un
mensaje de error y la fila no se insertar (si los tipos no son compatibles).
Para practicar puedes realizar este Ejercicio Insertar una fila de valores.
Tabla_derivada es cualquier instruccin SELECT vlida que devuelva filas con los datos
que se van a cargar en el destino.
Cada fila devuelta por la SELECT es una lista de valores que se intentar insertar como
con la clusula VALUES, por lo que las columnas devueltas por la SELECT debern
cumplir las mismas reglas que los valores de la lista de valores anteriores.
Ejemplo:
Hubiese dado error porque la columna col1 es INT y el valor a asignar es texto (el
nombre de la ciudad de la oficina).
En este caso hemos incluido una lista de columnas, la SELECT debe generar los
valores correspondientes, y col3 que no se rellena explcitamente se rellenar con NULL
porque la columna col3 no est definida como columna calculada, ni con DEFAULT, ni
IDENTITY y adems admite nulos.
Hace que la nueva fila contenga los valores predeterminados definidos para cada
columna.
Hay que tener en cuenta una serie de aspectos al utilizar esta instruccin:
Puede generar filas duplicadas en la tabla si los valores que se generan son siempre 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.
UPDATE
[ TOP ( expression ) [ PERCENT ] ]
<destino>
SET { nbcolumna = { expresion | DEFAULT | NULL }
} [ ,...n ]
[ FROM{ <origen> }]
[ WHERE <condicion> ]
[;]
<destino> ::=
{
[nbBaseDatos.[nbEsquema.]| nbEsquema.]nbTablaVista
}
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:
En una misma sentencia podemos actualizar varias columnas, slo tenemos que indicar
las distintas asignaciones separadas por comas:
Si no queremos actualizar todas las filas de la tabla sino unas cuantas, utilizaremos la
clusula TOP, o unas determinadas, utilizaremos la clusula WHERE.
Por ejemplo:
[ 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
SET ventas = 0
WHERE region = 'Este';
Cuando el campo de la otra tabla se utiliza para la clusula SET, entonces debemos
utilizar la clusula FROM.
La clusula FROM permite definir un origen de datos basado en varias tablas, y ese
origen ser el utilizado para realizar la actualizacin.
Por ejemplo queremos actualizar el importe de los pedidos con el precio de la tabla
productos.
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.
Para practicar puedes realizar este Ejercicio Modificar datos con UPDATE.
DELETE
[ TOP ( expression ) [ PERCENT ] ] [ FROM ] <destino>
[ FROM <origen>]
[ WHERE < condicion>]
[; ]
<destino> ::=
{
[nbBaseDatos. nbEsquema. | nbEsquema.]nbTablaVista
}
Con esta instruccin podemos eliminar una o varias filas de una tabla.
DELETE oficinas;
Equivalente a:
Por ejemplo:
DELETE oficinas
WHERE region = Este;
Por ejemplo:
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:
Esto se poda haber resuelto, como toda la vida, mediante una subconsulta:
Para finalizar no debemos olvidar que para poder ejecutar un DELETE se requieren
permisos DELETE en la tabla de donde vamos a eliminar, y tambin se requieren los
permisos para utilizar SELECT si la instruccin contiene una clusula WHERE.
En el ejemplo anterior, si un empleado asignado a una oficina del Este tiene pedidos, no
se podr eliminar y entonces no se eliminar ningn empleado.
Para practicar puedes realizar este Ejercicio Eliminar filas con DELETE.
TRUNCATE TABLE
[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.
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).
8.1. Introduccin
El DDL (Data Definition Language, o Data Description Language segn autores), 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, 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.
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 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
Estructura interna
Como ya vimos en el primer tema, las bases de datos de SQL Server 2005 utilizan tres
tipos de archivos:
CREATE DATABASE
Con la clusula ON especificamos los ficheros utilizados para almacenar los archivos
de datos.
[ ON
[ PRIMARY ] [ <esp_fichero> [ ,...n ]
[ , <grupo> [ ,...n ] ]
<esp_fichero> ::=
(
NAME = nbfichero_logico ,
FILENAME = 'nbfichero_fisico'
[ , SIZE = tamao [ KB | MB | GB | TB ] ]
[ , MAXSIZE = { max_size [ KB | MB | GB | TB ] |
UNLIMITED } ]
[ , 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.
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.
<grupo> ::=
{
FILEGROUP nbgrupo [ DEFAULT ]
<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).
La sintaxis es la siguiente:
COLLATE <nbintercalacion>
< nbintercalacion >:: =
nbinterWindows_ CaseSensitivity_AccentSensitivity
[ WITH <external_access_option> ]
<external_access_option> ::=
{
DB_CHAINING { ON | OFF }
| TRUSTWORTHY { ON | OFF }
}
Para crear una instantnea de base de datos (copia de slo lectura de una base de
datos).
Para crear una base de datos protegida mediante contrasea, opcin disponible para
SQL Server Mobile (Microsoft SQL Server 2005 Mobile Edition (SQL Server Mobile), antes
denominado Microsoft SQL Server 2000 Windows CE 2.0 (SQL Server CE), es una base
de datos compacta y con una gran variedad de funciones diseada para admitir una lista
ampliada de dispositivos inteligentes y Tablet PC. Entre los dispositivos inteligentes estn
todos los dispositivos que ejecuten Microsoft Windows CE 5.0, Microsoft Mobile
Pocket PC 2003, Microsoft Mobile Version 5.0 Pocket PC o Microsoft Mobile Version 5.0
Smart Phone. Esta compatibilidad adicional con dispositivos permite a los programadores
usar la misma funcionalidad de base de datos en un gran nmero de dispositivos.)
use b1
DROP DATABASE b1
Como se ve en la sintaxis podemos eliminar varias bases de datos con una sla
sentencia DROP DATABASE.
Por ejemplo:
Para poder ejecutar esta sentencia se debe de tener el permiso ALTER en la base de
datos. Esta sentencia se debe ejecutar en el modo de confirmacin automtica (modo de
administracin de transacciones predeterminado) y no se permite en una transaccin
explcita o 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:
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:
ALTER DATABASE Cliente
MODIFY NAME = Clientes;
<cambiar_ficheros>::=
{
ADD FILE < esp_fichero > [ ,...n ]
[ TO FILEGROUP { nbgrupo | DEFAULT } ]
| ADD LOG FILE < esp_fichero > [ ,...n ]
| REMOVE FILE nbfichero
| MODIFY FILE < esp_fichero >
}
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.
Con ADD LOG FILE podemos aadir un nuevo archivo de registro.
Con REMOVE FILE nbfichero eliminamos el archivo con nombre 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.
<esp_fichero>::=
(
NAME = nbarchivo
[ , NEWNAME = nuevo_nbarchivo ]
[ , FILENAME = 'nbarchivo_fisico' ]
[ , SIZE = tamao [ KB | MB | GB | TB ] ]
[ , MAXSIZE = { tamao_mximo [ KB | MB | GB | TB ] |
UNLIMITED } ]
[ , FILEGROWTH = incremento [ KB | MB | GB | TB| % ] ]
[ , OFFLINE ]
)
Con FILENAME podemos cambiar el nombre del fichero fsico, esto nos permite
tambin cambiar la ubicacin del archivo fsico.
Por ejemplo:
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.
<cambiar_grupos>::=
{
| ADD FILEGROUP nbgrupo
| REMOVE FILEGROUP nbgrupo
| MODIFY FILEGROUP nbgrupo
{
{ READONLY | READWRITE }
| { READ_ONLY | READ_WRITE }
}
| DEFAULT
| NAME = nuevo_ nbgrupo
}
}
Para cambiar este estado, se debe tener acceso exclusivo a la base de datos.
El grupo de archivos principal no puede ser de slo lectura.
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.
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> [ ,...n ] [ WITH <termination> ] }
| ALLOW_SNAPSHOT_ISOLATION {ON | OFF }
| READ_COMMITTED_SNAPSHOT {ON | OFF } [ WITH
<termination> ]
}
<optionspec>::=
{
<db_state_option>
| <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> ::=
{ ONLINE | OFFLINE | EMERGENCY }
<db_user_access_option> ::=
{ SINGLE_USER | RESTRICTED_USER | MULTI_USER }
<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 }
| CURSOR_DEFAULT { LOCAL | GLOBAL }
}
<auto_option> ::=
{
AUTO_CLOSE { ON | OFF }
| AUTO_CREATE_STATISTICS { ON | OFF }
| 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 }
}
<recovery_option> ::=
{
RECOVERY { FULL | BULK_LOGGED | SIMPLE }
| TORN_PAGE_DETECTION { ON | OFF }
| PAGE_VERIFY { CHECKSUM | TORN_PAGE_DETECTION | NONE }
}
< database_mirroring_option> ::=
{ <partner_option> | <witness_option> }
<partner_option> ::=
PARTNER { = 'partner_server'
| FAILOVER
| FORCE_SERVICE_ALLOW_DATA_LOSS
| OFF
| RESUME
| SAFETY { FULL | OFF }
| SUSPEND
| REDO_QUEUE ( integer { KB | MB | GB } |
UNLIMITED )
| TIMEOUT integer
}
<witness_option> ::=
WITNESS { = 'witness_server'
| OFF
}
<supplemental_logging_option> ::=
SUPPLEMENTAL_LOGGING { ON | OFF }
<service_broker_option> ::=
{
ENABLE_BROKER
| DISABLE_BROKER
| NEW_BROKER
| ERROR_BROKER_CONVERSATIONS
}
<date_correlation_optimization_option> ::=
{
DATE_CORRELATION_OPTIMIZATION { ON | OFF }
}
<parameterization_option> ::=
{
PARAMETERIZATION { SIMPLE | FORCED }
}
<termination> ::=
{
ROLLBACK AFTER integer [ SECONDS ]
| ROLLBACK IMMEDIATE
| NO_WAIT
}
CREATE TABLE
[ nbBaseDatos.[nbEsquema].| nbEsquema.]nbTabla
( { <definicion_columna> | < definicion_colCalc > } [
,...n ]
[ <restriccion_tabla> ] [ ,...n ] )
[ ; ]
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
[ ( precision [ , escala ] | max |
[ { CONTENT | DOCUMENT } ]
xml_schema_collection ) ]
[ 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.
Max slo se aplica a los tipos de datos varchar, nvarchar y varbinary para almacenar
231 bytes de datos de caracteres y binarios, y 230 bytes de datos Unicode.
[ COLLATE nbIntercalacion ]
Con la clusula COLLATE podemos definir el tipo de intercalacin que se utilizar para
la columna (Ver CREATE TABLE).
Con la clusula DEFAULT podemos especificar un valor por defecto, es decir el valor
que tomar el campo cuando no se haya especificado explcitamente un valor durante la
insercin. Las definiciones DEFAULT se pueden aplicar a cualquier columna excepto a las
definidas como timestamp o a aquellas que tengan la propiedad IDENTITY. Si se
especifica un valor por defecto a una columna de un tipo definido por el usuario, dicho tipo
debe ser compatible con la conversin implcita de exp_constante en el tipo definido por el
usuario. exp_constante slo puede ser NULL o un valor constante (por ejemplo, una
cadena de caracteres, una funcin escalar o una funcin del sistema, definida por el
usuario o 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.
[ 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 a 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.
Para ver ms consideraciones sobre columnas IDENTITY y ROWGUIDCOL.
Por ltimo nos quedan las restricciones de clave que aparecen en la sintaxis como:
[ <restriccion_columna> [ ...n ] ]
< restriccion_columna > ::=
[ CONSTRAINT nbRestriccion]
{ { PRIMARY KEY | UNIQUE }[ CLUSTERED | NONCLUSTERED ]
[ WITH FILLFACTOR = factorRelleno
| WITH ( < opcion_indice > [ , ...n ] )
]
[ ON { partition_scheme_name ( partition_column_name
)
| filegroup | "default" } ]
| [ FOREIGN KEY ]
REFERENCES [ nbEsquema.] nbTablaPadre [ ( col_padre
) ]
[ ON DELETE { NO ACTION | CASCADE | SET NULL | SET
DEFAULT } ]
}
[ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET
DEFAULT } ]
[ NOT FOR REPLICATION ]
| CHECK [ NOT FOR REPLICATION ] (expresion_validacion)
nbRestriccion es el nombre de la restriccin, como hemos visto antes, debe ser nico
en el esquema al que pertenece la tabla. Las restricciones se implementan internamente
con ndices por lo que a veces podemos utilizar el trmino ndice o restriccin
indistintamente.
PRIMARY KEY indica que la columna es la clave principal de la tabla. Slo se puede
crear una restriccin PRIMARY KEY para cada tabla. Si la clave primaria (principal) est
compuesta por varias columnas entonces no podemos utilizar esta restriccin, tendremos
que utilizar una restriccin de tabla que veremos ms adelante.
CLUSTERED indica que el ndice que se va a crear es un ndice agrupado. Como slo
puede haber un ndice agrupado por tabla, si todava no hay ninguno definido, por defecto
se crear con la clave primaria, si ya existe un ndice 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 a 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.
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.
Con CHECK indicamos una regla de validacin que debern cumplir todas las filas de la
tabla, es una restriccin que exige la integridad del dominio al limitar los valores posibles
que se pueden escribir en la columna.
expression es una expresin lgica que devuelve TRUE o 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 CHECK en el nivel de tabla slo puede hacer referencia a
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:
Precio CURRENCY CONSTRAINT precio_pos CHECK (Precio > = 0)
Por ltimo a nivel de columna podemos definir una restriccin de clave ajena:
[ FOREIGN KEY ]
REFERENCES [ nbEsquema.] nbTablaPadre [ ( col_padre )
]
[ ON DELETE { NO ACTION | CASCADE | SET NULL | SET
DEFAULT } ]
[ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET
DEFAULT } ]
[ NOT FOR REPLICATION ]
Con esta clusula definimos una regla de integridad referencial, los valores contenidos
en la columna debern apuntar a 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.
.,
Proveedor INTEGER REFERENCES Proveedores ON DELETE 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.
.,
Proveedor INTEGER REFERENCES Proveedores ON DELETE CASCADE,
)
.,
Proveedor INTEGER REFERENCES Proveedores ON DELETE SET NULL,
)
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.
Indica qu ocurre cuando se intenta cambiar un valor del campo relacionado de la tabla
padre en la relacin que estamos definiendo. El valor predeterminado es NO ACTION.
.,
Proveedor INTEGER REFERENCES Proveedores ON UPDATE NO
ACTION,
)
.,
Proveedor INTEGER REFERENCES Proveedores ON UPDATE CASCADE,
)
.,
Proveedor INTEGER REFERENCES Proveedores ON UPDATE SET
NULL,
)
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 y la
explicacin de ese ejemplo.
Volviendo al ejemplo anterior de la tabla de Personas, podemos definir la misma
utilizando restricciones de tabla:
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:
Ocurre lo mismo con las dems restricciones. Imaginemos ahora una tabla de lneas de
pedido en la que tenemos en una lnea el producto pedido, y la cantidad pedida.
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 y 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.
Una columna calculada es una columna cuyo valor no se introduce, sino que se obtiene
como resultado de un clculo.
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:
Una tabla temporal es una tabla creada por un determinado proceso y desaparece
cuando termina ste.
Se pueden crear tablas temporales locales y globales. Las tablas temporales locales son
visibles slo en la sesin actual y las 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 temporales locales y el prefijo ## (##nbTabla) tablas temporales
globales.
Por ejemplo:
Esta instruccin crea una tabla temporal local llamada trabajo con una sola columna.
Las tablas temporales funcionan casi como las tablas normales con algunas diferencias.
nbTabla no puede tener ms de 116 caracteres. Esto se debe a que si se crea una tabla
temporal local en un procedimiento almacenado o una aplicacin que varios usuarios
pueden ejecutar al mismo tiempo, el Motor de base de datos tiene que ser capaz de
distinguir las tablas creadas por los distintos usuarios, lo consigue aadiendo
internamente un sufijo numrico a cada nombre de tabla temporal local. El nombre
completo de una tabla temporal tal como se almacena en la tabla sysobjects de tempdb
consta del nombre de la tabla especificado en la instruccin CREATE TABLE y el sufijo
numrico generado por el sistema.
Para que las reglas de integridad referencial se cumplan, no se puede eliminar una
tabla sealada por una restriccin FOREIGN KEY. Primero se debe quitar la restriccin
FOREIGN KEY o la tabla que tiene la clave ajena.
Se pueden quitar varias tablas de cualquier base de datos en una misma sentencia
DROP TABLE. Se irn eliminando en el mismo orden en que aparecen en la lista por lo
que podremos eliminar dos tablas relacionadas con una sola sentencia pero escribiendo la
tabla que contiene la clave ajena primero y despus la tabla principal.
Ejemplo:
Elimina la tabla miTabla tanto su definicin como los datos, ndices definidos sobre ella
y permisos.
Ejemplo:
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:
ALTER TABLE Clientes ADD email varchar(50);
Aade una restriccin de clave primaria sobre la columna codcli que ya existe en la
tabla.
Ejemplos:
Crea una vista con los datos de todos los empleados y 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.
En definitiva se puede optar por utilizar la lista de columnas o definir alias de campo en
la sentencia SELECT.
Las columnas que se vayan a modificar en la vista deben hacer referencia directa a los
datos subyacentes de las columnas de la tabla, es decir que las columnas no se pueden
obtener de otra forma, como con una funcin de agregado: AVG, COUNT, SUM, MIN,
MAX, GROUPING, STDEV, STDEVP, VAR y VARP, o un clculo.
Las columnas formadas mediante los operadores de conjunto UNION, UNION ALL,
CROSSJOIN, EXCEPT e INTERSECT equivalen a un clculo y tampoco son
actualizables.
Las columnas que se van a modificar no se ven afectadas por las clusulas GROUP BY,
HAVING o DISTINCT.
Se eliminan las vista de la base de datos actual. Cuando eliminamos una vista
eliminamos su definicin y los permisos asociados a ella.
Se pueden quitar varias vistas en una misma sentencia DROP VIEW escribiendo los
nombres de las vistas a eliminar separados por comas.
Para ejecutar DROP VIEW, como mnimo, se necesita el permiso ALTER en SCHEMA o
el permiso CONTROL en OBJECT.
Ejemplo:
Si eliminamos una tabla mediante DROP TABLE, se deben quitar explcitamente, con
DROP VIEW, las vistas basadas en esta tabla ya que no se quitarn por s solas.
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 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 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.
Ventajas
Inconvenientes
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 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.
Ejemplos:
Crea un ndice no agrupado sobre las columnas apellidos y nombre de la tabla Clientes
en la base de datos actual, las filas se ordenarn de forma ascendente por apellido y
dentro del mismo apellido por nombre.
Crea un ndice no agrupado sobre las columnas edad y apellidos de la tabla Clientes en
la base de datos actual, las filas se ordenarn de forma descendente por edad y
ascendente por apellido. Aparecern los clientes de mayor a menor edad y los clientes de
la misma edad se ordenarn por apellido (por orden alfabtico).
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.
Sintaxis simplificada:
Ejemplo:
9.1. Introduccin
Hasta ahora hemos estudiado sentencias SQL orientadas a realizar una determinada
tarea sobre la base de datos como definir tablas, obtener informacin de las tablas,
actualizarlas; estas sentencias las hemos ejecutado desde el editor de consultas del
MSSMS de una en una o a lo sumo una a continuacin de la otra dentro de la misma
consulta formando un lote 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:
Tipos de datos.
Definicin de variables.
Estructuras de control de flujo.
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 (o triggers) y funciones definidas por el usuario.
Nosotros estudiaremos los dos 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.
Transact-SQL permite abreviar la palabra reservada PROCEDURE por PROC sin que
ello afecte a la funcionalidad de la instruccin.
Ejemplos:
Para eliminar varios procedimientos de golpe, indicamos sus nombres separados por
comas:
CREATE PROCEDURE
Transact-SQL permite abreviar la palabra reservada PROCEDURE por PROC sin que
ello afecte a la funcionalidad de la instruccin.
Es equivalente a
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
En este caso, como la llamada es la primera del lote (va detrs del GO) podamos
haber obviado la palabra EXEC y haber escrito directamente:
Dice_Hola
Aqu hemos hecho dos llamadas, una con el valor Lo que quiera y otra con el valor
Otra cosa.
USE Biblio;
--DROP PROC VerUsuariosPoblacion; --La comentamos la primera
vez
GO
CREATE PROCEDURE VerUsuariosPoblacion @pob CHAR(30),@pro
CHAR(30)
AS
SELECT * FROM usuarios WHERE poblacion=@pob AND provincia =
@pro;
GO
EXEC VerUsuariosPoblacion Madrid, Valencia
USE Gestion
GO
CREATE PROC ultimo_contrato @ofi INT, @fecha DATETIME OUTPUT
AS
SELECT @fecha=(SELECT MAX(contrato) FROM empleados WHERE
oficina=@ofi)
GO
RETURN
RETURN [expresion_entera]
EXECUTE @variable_donde_recogemos_estado =
nombre_procedimiento @par, ...
Con el procedimiento del punto anterior no se puede utilizar esta forma de devolver un
resultado porque lo que se devuelve es una fecha, no es un valor entero, pero si
quisiramos definir un procedimiento que nos devuelva el nmero de empleados de una
oficina podramos hacerlo de dos formas:
USE Gestion
GO
CREATE PROC trabajadores @ofi INT, @num INT OUTPUT
AS
SELECT @num=(SELECT COUNT(*) FROM empleados WHERE
oficina=@ofi)
GO
IF condicion
{ sentencia_sql | bloque_sql }
[ ELSE
{ sentencia_sql | bloque_sql } ]
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 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.
WHILE condicion
{ sentencia_sql | bloque_sql }
| BREAK
| CONTINUE
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.
Ejemplo:
PRINT CONVERT(CHAR(8),Getdate(),108);
WAITFOR DELAY '00:00:03'
PRINT CONVERT(CHAR(8),Getdate(), 108);
WAITFOR DELAY '00:03'
PRINT CONVERT(CHAR(8),Getdate(), 108);
9.9. GOTO
Altera el flujo de ejecucin y lo dirige a una etiqueta.
Las etiquetas se indican mediante un nombre seguido del carcter:
GOTO NombreEtiqueta
Ejemplo:
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 TRY
CATCH y se devuelve informacin sobre el error.
USE Gestion;
GO
BEGIN TRY
SELECT * FROM TablaQueNoExiste;
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() as ErrorNumero,ERROR_MESSAGE() as
MensajeDeError;
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.
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.
Ejemplo:
USE Gestion8
GO
CREATE TRIGGER ActualizaVentasEmpleados
ON pedidos FOR INSERT
AS
UPDATE empleados SET ventas=ventas+inserted.importe
FROM empleados, inserted
WHERE numemp=inserted.rep;
GO
Vemos que al insertar un pedido de 100 del empleado 108, sus ventas han
aumentado en 100.
ALTER TRIGGER
Ejemplo:
Ejemplo: