Top Banner

of 102

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript

2 - Crear una tabla (create table - sp_tables - sp_columns - drop table)Una base de datos almacena su informacin en tablas. Una tabla es una estructura de datos que organiza los datos en columnas y filas; cada columna es un campo (o atributo) y cada fila, un registro. La interseccin de una columna con una fila, contiene un dato especfico, un solo valor. Cada registro contiene un dato por cada columna de la tabla. Cada campo (columna) debe tener un nombre. El nombre del campo hace referencia a la informacin que almacenar. Cada campo (columna) tambin debe definir el tipo de dato que almacenar. Las tablas forman parte de una base de datos. Nosotros trabajaremos con la base de datos llamada wi520641_sqlserverya (este nombre se debe a que las empresas de hosting es la que lo define), que ya he creado en el servidor sqlserverya.com.ar. Para ver las tablas existentes creadas por los usuarios en una base de datos usamos el procedimiento almacenado "sp_tables @table_owner='dbo';": sp_tables @table_owner='dbo'; El parmetro @table_owner='dbo' indica que solo muestre las tablas de usuarios y no las que crea el SQL Server para administracin interna. Finalizamos cada comando con un punto y coma. Al crear una tabla debemos resolver qu campos (columnas) tendr y que tipo de datos almacenarn cada uno de ellos, es decir, su estructura. La sintaxis bsica y general para crear una tabla es la siguiente: create table NOMBRETABLA( NOMBRECAMPO1 TIPODEDATO, ... NOMBRECAMPON TIPODEDATO ); La tabla debe ser definida con un nombre que la identifique y con el cual accederemos a ella. Creamos una tabla llamada "usuarios" y entre parntesis definimos los campos y sus tipos: create table usuarios ( nombre varchar(30), clave varchar(10) );

Cada campo con su tipo debe separarse con comas de los siguientes, excepto el ltimo. Cuando se crea una tabla debemos indicar su nombre y definir al menos un campo con su tipo de dato. En esta tabla "usuarios" definimos 2 campos: y y nombre: que contendr una cadena de caracteres de 30 caracteres de longitud, que almacenar el nombre de usuario y clave: otra cadena de caracteres de 10 de longitud, que guardar la clave de cada usuario.

Cada usuario ocupar un registro de esta tabla, con su respectivo nombre y clave. Para nombres de tablas, se puede utilizar cualquier caracter permitido para nombres de directorios, el primero debe ser un caracter alfabtico y no puede contener espacios. La longitud mxima es de 128 caracteres. Si intentamos crear una tabla con un nombre ya existente (existe otra tabla con ese nombre), mostrar un mensaje indicando que ya hay un objeto llamado 'usuarios' en la base de datos y la sentencia no se ejecutar. Esto es muy importante ya que cuando haga los ejercicios en este sitio puede haber otra persona que haya creado una tabla con el nombre que usted especifique. Para ver la estructura de una tabla usamos el procedimiento almacenado "sp_columns" junto al nombre de la tabla: sp_columns usuarios; aparece mucha informacin que no analizaremos en detalle, como el nombre de la tabla, su propietario, los campos, el tipo de dato de cada campo, su longitud, etc.: ...COLUMN_NAME TYPE_NAME LENGHT _______________________________________ nombre varchar 30 clave varchar 10 Para eliminar una tabla usamos "drop table" junto al nombre de la tabla a eliminar: drop table usuarios; Si intentamos eliminar una tabla que no existe, aparece un mensaje de error indicando tal situacin y la sentencia no se ejecuta. Para evitar este mensaje podemos agregar a la instruccin lo siguiente: if object_id('usuarios') is not null drop table usuarios; En la sentencia precedente especificamos que elimine la tabla "usuarios" si existe.

3 - Insertar y recuperar registros de una tabla (insert into - select)Un registro es una fila de la tabla que contiene los datos propiamente dichos. Cada registro tiene un dato por cada columna (campo). Nuestra tabla "usuarios" consta de 2 campos, "nombre" y "clave".

Al ingresar los datos de cada registro debe tenerse en cuenta la cantidad y el orden de los campos. La sintaxis bsica y general es la siguiente: insert into NOMBRETABLA (NOMBRECAMPO1, ..., NOMBRECAMPOn) values (VALORCAMPO1, ..., VALORCAMPOn); Usamos "insert into", luego el nombre de la tabla, detallamos los nombres de los campos entre parntesis y separados por comas y luego de la clusula "values" colocamos los valores para cada campo, tambin entre parntesis y separados por comas. Para agregar un registro a la tabla tipeamos: insert into usuarios (nombre, clave) values ('Mariano','payaso'); Note que los datos ingresados, como corresponden a cadenas de caracteres se colocan entre comillas simples. Para ver los registros de una tabla usamos "select": select * from usuarios; El comando "select" recupera los registros de una tabla. Con el asterisco indicamos que muestre todos los campos de la tabla "usuarios". Es importante ingresar los valores en el mismo orden en que se nombran los campos: insert into usuarios (clave, nombre) values ('River','Juan'); En el ejemplo anterior se nombra primero el campo "clave" y luego el campo "nombre" por eso, los valores tambin se colocan en ese orden. Si ingresamos los datos en un orden distinto al orden en que se nombraron los campos, no aparece un mensaje de error y los datos se guardan de modo incorrecto. En el siguiente ejemplo se colocan los valores en distinto orden en que se nombran los campos, el valor de la clave (la cadena "Boca") se guardar en el campo "nombre" y el valor del nombre (la cadena "Luis") en el campo "clave": insert into usuarios (nombre,clave) values ('Boca','Luis');

4 - Tipos de datos bsicosYa explicamos que al crear una tabla debemos resolver qu campos (columnas) tendr y que tipo de datos almacenar cada uno de ellos, es decir, su estructura. El tipo de dato especifica el tipo de informacin que puede guardar un campo: caracteres, nmeros, etc. Estos son algunos tipos de datos bsicos de SQL Server (posteriormente veremos otros):

y

y

y

varchar: se usa para almacenar cadenas de caracteres. Una cadena es una secuencia de caracteres. Se coloca entre comillas (simples); ejemplo: 'Hola', 'Juan Perez'. El tipo "varchar" define una cadena de longitud variable en la cual determinamos el mximo de caracteres entre parntesis. Puede guardar hasta 8000 caracteres. Por ejemplo, para almacenar cadenas de hasta 30 caracteres, definimos un campo de tipo varchar(30), es decir, entre parntesis, junto al nombre del campo colocamos la longitud. Si asignamos una cadena de caracteres de mayor longitud que la definida, la cadena no se carga, aparece un mensaje indicando tal situacin y la sentencia no se ejecuta. Por ejemplo, si definimos un campo de tipo varchar(10) e intentamos asignarle la cadena 'Buenas tardes', aparece un mensaje de error y la sentencia no se ejecuta. integer: se usa para guardar valores numricos enteros, de -2000000000 a 2000000000 aprox. Definimos campos de este tipo cuando queremos representar, por ejemplo, cantidades. float: se usa para almacenar valores numricos con decimales. Se utiliza como separador el punto (.). Definimos campos de este tipo para precios, por ejemplo.

Antes de crear una tabla debemos pensar en sus campos y optar por el tipo de dato adecuado para cada uno de ellos. Por ejemplo, si en un campo almacenaremos nmeros enteros, el tipo "float" sera una mala eleccin; si vamos a guardar precios, el tipo "float" es ms adecuado, no as "integer" que no tiene decimales. Otro ejemplo, si en un campo vamos a guardar un nmero telefnico o un nmero de documento, usamos "varchar", no "integer" porque si bien son dgitos, con ellos no realizamos operaciones matemticas.

5 - Recuperar algunos campos (select)Hemos aprendido cmo ver todos los registros de una tabla, empleando la instruccin "select". La sintaxis bsica y general es la siguiente: select * from NOMBRETABLA; El asterisco (*) indica que se seleccionan todos los campos de la tabla. Podemos especificar el nombre de los campos que queremos ver separndolos por comas: select titulo,autor from libros; La lista de campos luego del "select" selecciona los datos correspondientes a los campos nombrados. En el ejemplo anterior seleccionamos los campos "titulo" y "autor" de la tabla "libros", mostrando todos los registros. Los datos aparecen ordenados segn la lista de seleccin, en dicha lista los nombres de los campos se separan con comas

6 - Recuperar algunos registros (where)Hemos aprendido a seleccionar algunos campos de una tabla. Tambin es posible recuperar algunos registros. Existe una clusula, "where" con la cual podemos especificar condiciones para una consulta "select". Es decir, podemos recuperar algunos registros, slo los que cumplan con ciertas

condiciones indicadas con la clusula "where". Por ejemplo, queremos ver el usuario cuyo nombre es "Marcelo", para ello utilizamos "where" y luego de ella, la condicin: select nombre, clave from usuarios where nombre='Marcelo'; La sintaxis bsica y general es la siguiente: select NOMBRECAMPO1, ..., NOMBRECAMPOn from NOMBRETABLA where CONDICION; Para las condiciones se utilizan operadores relacionales (tema que trataremos ms adelante en detalle). El signo igual(=) es un operador relacional. Para la siguiente seleccin de registros especificamos una condicin que solicita los usuarios cuya clave es igual a "River": select nombre,clave from usuarios where clave='River'; Si ningn registro cumple la condicin establecida con el "where", no aparecer ningn registro. Entonces, con "where" establecemos condiciones para recuperar algunos registros. Para recuperar algunos campos de algunos registros combinamos en la consulta la lista de campos y la clusula "where": select nombre from usuarios where clave='River'; En la consulta anterior solicitamos el nombre de todos los usuarios cuya clave sea igual a "River".

7 - Operadores relacionalesLos operadores son smbolos que permiten realizar operaciones matemticas, concatenar cadenas, hacer comparaciones. SQL Server tiene 4 tipos de operadores: 1. 2. 3. 4. relacionales (o de comparacin) aritmticos de concatenacin lgicos.

Por ahora veremos solamente los primeros. Los operadores relacionales (o de comparacin) nos permiten comparar dos expresiones, que pueden ser variables, valores de campos, etc.

Hemos aprendido a especificar condiciones de igualdad para seleccionar registros de una tabla; por ejemplo: select *from libros where autor='Borges'; Utilizamos el operador relacional de igualdad. Los operadores relacionales vinculan un campo con un valor para que SQL Server compare cada registro (el campo especificado) con el valor dado. Los operadores relacionales son los siguientes: = > < >= 20; Queremos seleccionar los libros cuyo precio sea menor o igual a 30: select *from libros where precio (mayor), < (menor), >= (mayor o igual), =20 and precio 2; En una clusula "having" puede haber hasta 128 condiciones. Cuando utilice varias condiciones, tiene que combinarlas con operadores lgicos (and, or, not). Podemos encontrar el mayor valor de los libros agrupados y ordenados por editorial y seleccionar las filas que tengan un valor menor a 100 y mayor a 30: select editorial, max(precio) as 'mayor' from libros group by editorial having min(precio)30 order by editorial;

Entonces, usamos la clasula "having" para restringir las filas que devuelve una salida "group by". Va siempre despus de la clusula "group by" y antes de la clusula "order by" si la hubiere.

39 - Modificador del group by (with rollup)Podemos combinar "group by" con los operadores "rollup" y "cube" para generar valores de resumen a la salida. El operador "rollup" resume valores de grupos. representan los valores de resumen de la precedente. Tenemos la tabla "visitantes" con los siguientes campos: nombre, edad, sexo, domicilio, ciudad, telefono, montocompra. Si necesitamos la cantidad de visitantes por ciudad empleamos la siguiente sentencia: select ciudad,count(*) as cantidad from visitantes group by ciudad; Esta consulta muestra el total de visitantes agrupados por ciudad; pero si queremos adems la cantidad total de visitantes, debemos realizar otra consulta: select count(*) as total from visitantes; Para obtener ambos resultados en una sola consulta podemos usar "with rollup" que nos devolver ambas salidas en una sola consulta: select ciudad,count(*) as cantidad

from visitantes group by ciudad with rollup; La consulta anterior retorna los registros agrupados por ciudad y una fila extra en la que la primera columna contiene "null" y la columna con la cantidad muestra la cantidad total. La clusula "group by" permite agregar el modificador "with rollup", el cual agrega registros extras al resultado de una consulta, que muestran operaciones de resumen. Si agrupamos por 2 campos, "ciudad" y "sexo": select ciudad,sexo,count(*) as cantidad from visitantes group by ciudad,sexo with rollup; La salida muestra los totales por ciudad y sexo y produce tantas filas extras como valores existen del primer campo por el que se agrupa ("ciudad" en este caso), mostrando los totales para cada valor, con la columna correspondiente al segundo campo por el que se agrupa ("sexo" en este ejemplo) conteniendo "null", y 1 fila extra mostrando el total de todos los visitantes (con las columnas correspondientes a ambos campos conteniendo "null"). Es decir, por cada agrupacin, aparece una fila extra con el/ los campos que no se consideran, seteados a "null". Con "rollup" se puede agrupar hasta por 10 campos. Es posible incluir varias funciones de agrupamiento, por ejemplo, queremos la cantidad de visitantes y la suma de sus compras agrupados por ciudad y sexo: select ciudad,sexo, count(*) as cantidad, sum(montocompra) as total from visitantes group by ciudad,sexo with rollup; Entonces, "rollup" es un modificador para "group by" que agrega filas extras mostrando resultados de resumen de los subgrupos. Si se agrupa por 2 campos SQL Server genera tantas filas extras como valores existen del primer campo (con el segundo campo seteado a "null") y una fila extra con ambos campos conteniendo "null". Con "rollup" se puede emplear "where" y "having", pero no es compatible con "all".

40 - Modificador del group by (with cube)Hemos aprendido el modificador "rollup", que agrega filas extras mostrando resultados de resumen por cada grupo y subgrupo. Por ejemplo, tenemos una tabla llamada "empleados" que contiene, entre otros, los campos "sexo", "estadocivil" y "seccion". Si se agrupa por esos tres campos (en ese orden) y se emplea "rollup":

select sexo,estadocivil,seccion, count(*) from empleados group by sexo,estadocivil,seccion with rollup; SQL Server genera varias filas extras con informacin de resumen para los siguientes subgrupos: - sexo y estadocivil (seccion seteado a "null"), - sexo (estadocivil y seccion seteados a "null") y - total (todos los campos seteados a "null"). Si se emplea "cube": select sexo,estadocivil,seccion, count(*) from empleados group by sexo,estadocivil,seccion with cube; retorna ms filas extras adems de las anteriores: sexo y seccion (estadocivil estadocivil y seccion (sexo seccion (sexo y estadocivil estadocivil (sexo y seccion seteado a "null"), seteado a "null"), seteados a "null") y seteados a "null"),

Es decir, "cube" genera filas de resumen de subgrupos para todas las combinaciones posibles de los valores de los campos por los que agrupamos. Se pueden colocar hasta 10 campos en el "group by". Con "cube" se puede emplear "where" y "having", pero no es compatible con "all".

41 - Funcin groupingLa funcin "grouping" se emplea con los operadores "rollup" y "cube" para distinguir los valores de detalle y de resumen en el resultado. Es decir, permite diferenciar si los valores "null" que aparecen en el resultado son valores nulos de las tablas o si son una fila generada por los operadores "rollup" o "cube". Con esta funcin aparece una nueva columna en la salida, una por cada "grouping"; retorna el valor 1 para indicar que la fila representa los valores de resumen de "rollup" o "cube" y el valor 0 para representar los valores de campo. Slo se puede emplear la funcin "grouping" en los campos que aparecen en la clusula "group by". Si tenemos una tabla "visitantes" con los siguientes registros almacenados: Nombre sexo ciudad ------------------------------Susana Molina f Cordoba Marcela Mercado f Cordoba Roberto Perez f null

Alberto Garcia m Teresa Garcia f

Cordoba Alta Gracia

y contamos la cantidad agrupando por ciudad (note que hay un valor nulo en dicho campo) empleando "rollup": select ciudad, count(*) as cantidad from visitantes group by ciudad with rollup; aparece la siguiente salida: ciudad cantidad ------------------------NULL 1 Alta Gracia 1 Cordoba 3 NULL 5 La ltima fila es la de resumen generada por "rollup", pero no es posible distinguirla de la primera fila, en la cual "null" es un valor del campo. Para diferenciarla empleamos "grouping": select ciudad, count(*) as cantidad, grouping(ciudad) as resumen from visitantes group by ciudad with rollup; aparece la siguiente salida: ciudad cantidad resumen --------------------------------------NULL 1 0 Alta Gracia 1 0 Cordoba 3 0 NULL 5 1 La ltima fila contiene en la columna generada por "grouping" el valor 1, indicando que es la fila de resumen generada por "rollup"; la primera fila, contiene en dicha columna el valor 0, que indica que el valor "null" es un valor del campo "ciudad". Entonces, si emplea los operadores "rollup" y "cube" y los campos por los cuales agrupa admiten valores nulos, utilice la funcin "grouping" para distinguir los valores de detalle y de resumen en el resultado.

42 - Clusulas compute y compute byLas clusulas "compute" y "compute by" generan totales que aparecen en columnas extras al final del resultado.

Produce filas de detalle y un valor nico para una columna. Se usa con las funciones de agrupamiento: avg(), count(), max(), min(), sum(). La sintaxis bsica y general es la siguiente: select CAMPOS from TABLA compute FUNCION(CAMPO); El campo que se coloque en la clusula "compute" debe estar incluida en la lista de campos del "select". Para ver todos los datos de los visitantes y el promedio del monto de compra de nuestra tabla "visitantes": select *from visitantes compute avg(montocompra); Produce la misma salida que las siguientes 2 sentencias: select *from visitantes; select avg(montocompra) from visitantes; En una misma instruccin se pueden colocar varias clusulas "compute": select edad,ciudad,montocompra from visitantes compute avg(edad),sum(montocompra); "Compute by" genera cortes de control y subtotales. Se generan filas de detalle y varios valores de resumen cuando cambian los valores del campo. Con "compute by" se DEBE usar tambin la clusula "order by" y los campos que se incluyan luego de "by" deben estar en el "order by". Listando varios campos luego del "by" corta un grupo en subgrupos y aplica la funcin de agregado en cada nivel de agrupamiento: select nombre,ciudad,provincia from visitantes order by provincia compute count(provincia) by provincia; select nombre,ciudad,provincia from visitantes order by provincia,ciudad compute count(provincia) by provincia,ciudad; Los campos que aparecen luego de la clusula "compute by" DEBEN ser idnticos a un subconjunto de los campos que aparecen despus de "order by" y estar en el mismo orden. Si la clusula "order by" tiene los siguientes campos:

... order by a,b,c... la clusula "compute by" puede incluir los siguientes subconjuntos de campos: ... compute ... by a... o ... compute ... by a,b... o ... compute ... by a,b,c... En una misma instruccin se pueden colocar varias clusulas "compute" combinadas con varias clusulas "compute by": select *from visitantes order by provincia,ciudad compute avg(edad), sum(montocompra) compute avg(montocompra),count(provincia) by provincia,ciudad; El resultado de la consulta anterior muestra el promedio de la compra y la cantidad al final de cada subgrupo de provincia y ciudad (compute by) y el promedio de las edades y el total del monto de compras de todos (compute). Los tipos de datos ntext, text e image no se pueden incluir en una clusula "compute" o "compute by".

43 - Registros duplicados (distinct)Con la clusula "distinct" se especifica que los registros con ciertos datos duplicados sean obviadas en el resultado. Por ejemplo, queremos conocer todos los autores de los cuales tenemos libros, si utilizamos esta sentencia: select autor from libros; Aparecen repetidos. Para obtener la lista de autores sin repeticin usamos: select distinct autor from libros; Tambin podemos tipear: select autor from libros group by autor; Note que en los tres casos anteriores aparece "null" como un valor para "autor" Si slo queremos la lista de autores conocidos, es decir, no queremos incluir "null" en la lista, podemos utilizar la sentencia siguiente: select distinct autor from libros where autor is not null;

Para contar los distintos autores, sin considerar el valor "null" usamos: select count(distinct autor) from libros; Note que si contamos los autores sin "distinct", no incluir los valores "null" pero si los repetidos: select count(autor) from libros; Esta sentencia cuenta los registros que tienen autor. Podemos combinarla con "where". Por ejemplo, queremos conocer los distintos autores de la editorial "Planeta": select distinct autor from libros where editorial='Planeta'; Tambin puede utilizarse con "group by" para contar los diferentes autores por editorial: select editorial, count(distinct autor) from libros group by editorial; La clusula "distinct" afecta a todos los campos presentados. Para mostrar los ttulos y editoriales de los libros sin repetir ttulos ni editoriales, usamos: select distinct titulo,editorial from libros order by titulo; Note que los registros no estn duplicados, aparecen ttulos iguales pero con editorial diferente, cada registro es diferente. La palabra clave "distinct" no est permitida con las clusulas "compute" y "compute by". Entonces, "distinct" elimina registros duplicados.

44 - Clusula topLa palabra clave "top" se emplea para obtener slo una cantidad limitada de registros, los primeros n registros de una consulta. Con la siguiente consulta obtenemos todos los datos de los primeros 2 libros de la tabla: select top 2 *from libros; Es decir, luego del "select" se coloca "top" seguido de un nmero entero positivo y luego se contina con la consulta. Se puede combinar con "order by":

select top 3 titulo,autor from libros order by autor; En la consulta anterior solicitamos los ttulos y autores de los 3 primeros libros, ordenados por autor. Cuando se combina con "order by" es posible emplear tambin la clusula "with ties". Esta clusula permite incluir en la seleccion, todos los registros que tengan el mismo valor del campo por el que se ordena, que el ltimo registro retornado si el ltimo registro retornado (es decir, el nmero n) tiene un valor repetido en el registro n+1. Es decir, si el valor del campo por el cual se ordena del ltimo registro retornado (el nmero n) est repetido en los siguientes registros (es decir, el n+1 tiene el mismo valor que n, y el n+2, etc.), lo incluye en la seleccin. Veamos un ejemplo: select top 3 with ties *from libros order by autor; Esta consulta solicita el retorno de los primeros 3 registros; en caso que el registro nmero 4 (y los posteriores), tengan el mismo valor en "autor" que el ltimo registro retornado (nmero 3), tambin aparecern en la seleccin. Si colocamos un valor para "top" que supera la cantidad de registros de la tabla, SQL Server muestra todos los registros.

45 - Clave primaria compuestaLas claves primarias pueden ser simples, formadas por un solo campo o compuestas, ms de un campo. Recordemos que una clave primaria identifica 1 solo registro en una tabla. Para un valor del campo clave existe solamente 1 registro. Los valores no se repiten ni pueden ser nulos. Existe una playa de estacionamiento que almacena cada da los datos de los vehculos que ingresan en la tabla llamada "vehiculos" con los siguientes campos: patente char(6) not null, tipo char (1), 'a'= auto, 'm'=moto, horallegada datetime, horasalida datetime,

Necesitamos definir una clave primaria para una tabla con los datos descriptos arriba. No podemos usar solamente la patente porque un mismo auto puede ingresar ms de una vez en el da a la playa; tampoco podemos usar la hora de entrada porque varios autos pueden ingresar a una misma hora. Tampoco sirven los otros campos.

Como ningn campo, por si slo cumple con la condicin para ser clave, es decir, debe identificar un solo registro, el valor no puede repetirse, debemos usar 2 campos. Definimos una clave compuesta cuando ningn campo por si solo cumple con la condicin para ser clave. En este ejemplo, un auto puede ingresar varias veces en un da a la playa, pero siempre ser a distinta hora. Usamos 2 campos como clave, la patente junto con la hora de llegada, as identificamos unvocamente cada registro. Para establecer ms de un campo como clave primaria usamos la siguiente sintaxis: create table vehiculos( patente char(6) not null, tipo char(1),--'a'=auto, 'm'=moto horallegada datetime, horasalida datetime, primary key(patente,horallegada) ); Nombramos los campos que formarn parte de la clave separados por comas. Al ingresar los registros, SQL Server controla que los valores para los campos establecidos como clave primaria no estn repetidos en la tabla; si estuviesen repetidos, muestra un mensaje y la insercin no se realiza. Lo mismo sucede si realizamos una actualizacin. Entonces, si un solo campo no identifica unvocamente un registro podemos definir una clave primaria compuesta, es decir formada por ms de un campo.

46 - Integridad de los datosEs importante, al disear una base de datos y las tablas que contiene, tener en cuenta la integridad de los datos, esto significa que la informacin almacenada en las tablas debe ser vlida, coherente y exacta. Hasta el momento, hemos controlado y restringido la entrada de valores a un campo mediante el tipo de dato que le definimos (cadena, numricos, etc.), la aceptacin o no de valores nulos, el valor por defecto. Tambin hemos asegurado que cada registro de una tabla sea nico definiendo una clave primaria y empleando la propiedad identity. SQL Server ofrece ms alternativas, adems de las aprendidas, para restringir y validar los datos, las veremos ordenadamente y al finalizar haremos un resumen de las mismas. Comenzamos por las restricciones. Las restricciones (constraints) son un mtodo para mantener la integridad de los datos, asegurando que los valores ingresados sean vlidos y que las relaciones entre las tablas se mantenga. Se establecen a los campos y las tablas.

Pueden definirse al crear la tabla ("create table") o agregarse a una tabla existente (empleando "alter table") y se pueden aplicar a un campo o a varios. Se aconseja crear las tablas y luego agregar las restricciones. Se pueden crear, modificar y eliminar las restricciones sin eliminar la tabla y volver a crearla. El procedimiento almacenado del sistema "sp_helpconstraint" junto al nombre de la tabla, nos muestra informacin acerca de las restricciones de dicha tabla. Cuando se agrega una restriccin a una tabla, SQL Server comprueba los datos existentes. Hay varios tipos de restricciones.

47 - Restriccin defaultLa restriccin "default" especifica un valor por defecto para un campo cuando no se inserta explcitamente en un comando "insert". Anteriormente, para establecer un valor por defecto para un campo emplebamos la clusula "default" al crear la tabla, por ejemplo: create table libros( ... autor varchar(30) default 'Desconocido', ... ); Cada vez que establecamos un valor por defecto para un campo de una tabla, SQL Server creaba automticamente una restriccin "default" para ese campo de esa tabla. Dicha restriccin, a la cual no le dbamos un nombre, reciba un nombre dado por SQL Server que consiste "DF" (por default), seguido del nombre de la tabla, el nombre del campo y letras y nmeros aleatorios. Podemos agregar una restriccin "default" a una tabla existente con la sintaxis bsica siguiente: alter table NOMBRETABLA add constraint NOMBRECONSTRAINT default VALORPORDEFECTO for CAMPO; En la sentencia siguiente agregamos una restriccin "default" al campo autor de la tabla existente "libros", que almacena el valor "Desconocido" en dicho campo si no ingresamos un valor en un "insert": alter table libros add constraint DF_libros_autor default 'Desconocido' for autor; Por convencin, cuando demos el nombre a las restricciones "default" emplearemos un formato similar al que le da SQL Server: "DF_NOMBRETABLA_NOMBRECAMPO".

Solamente se permite una restriccin "default" por campo y no se puede emplear junto con la propiedad "identity". Una tabla puede tener varias restricciones "default" para sus distintos campos. La restriccin "default" acepta valores tomados de funciones del sistema, por ejemplo, podemos establecer que el valor por defecto de un campo de tipo datetime sea "getdate()". Podemos ver informacin referente a las restriciones de una tabla con el procedimiento almacenado "sp_helpcontraint": sp_helpconstraint libros; aparecen varias columnas con la siguiente informacin: - constraint_type: el tipo de restriccin y sobre qu campo est establecida (DEFAULT on column autor), - constraint_name: el nombre de la restriccin (DF_libros_autor), - delete_action y update_action: no tienen valores para este tipo de restriccin. - status_enabled y status_for_replication: no tienen valores para este tipo de restriccin. - constraint_keys: el valor por defecto (Desconocido). Entonces, la restriccin "default" especifica un valor por defecto para un campo cuando no se inserta explcitamente en un "insert", se puede establecer uno por campo y no se puede emplear junto con la propiedad "identity".

48 - Restriccin checkLa restriccin "check" especifica los valores que acepta un campo, evitando que se ingresen valores inapropiados. La sintaxis bsica es la siguiente: alter table NOMBRETABLA add constraint NOMBRECONSTRAINT check CONDICION; Trabajamos con la tabla "libros" de una librera que tiene los siguientes campos: codigo, titulo, autor, editorial, preciomin (que indica el precio para los minoristas) y preciomay (que indica el precio para los mayoristas). Los campos correspondientes a los precios (minorista y mayorista) se definen de tipo decimal(5,2), es decir, aceptan valores entre -999.99 y 999.99. Podemos controlar que no se ingresen valores negativos para dichos campos agregando una restriccin "check": alter table libros add constraint CK_libros_precio_positivo check (preciomin>=0 and preciomay>=0);

Este tipo de restriccin verifica los datos cada vez que se ejecuta una sentencia "insert" o "update", es decir, acta en inserciones y actualizaciones. Si la tabla contiene registros que no cumplen con la restriccin que se va a establecer, la restriccin no se puede establecer, hasta que todos los registros cumplan con dicha restriccin. La condicin puede hacer referencia a otros campos de la misma tabla. Por ejemplo, podemos controlar que el precio mayorista no sea mayor al precio minorista: alter table libros add constraint CK_libros_preciominmay check (preciomay=0); La restriccin no se aplica en los datos existentes, pero si intentamos ingresar un nuevo valor que no cumpla la restriccin, SQL Server no lo permite. Entonces, para evitar la comprobacin de datos existentes al crear la restriccin, la sintaxis bsica es la siguiente: alter table TABLA with nocheck add constraint NOMBRERESTRICCION check (CONDICION); Por defecto, si no especificamos, la opcin es "with check". Tambin podemos deshabilitar las restricciones para agregar o actualizar datos sin comprobarla: alter table libros nocheck constraint CK_libros_precio; En el ejemplo anterior deshabilitamos la restriccin "CK_libros_precio" para poder ingresar un valor negativo para "precio". Para habilitar una restriccin deshabilitada se ejecuta la misma instruccin pero con la clusula "check" o "check all": alter table libros check constraint CK_libros_precio; Si se emplea "check constraint all" no se coloca nombre de restricciones, habilita todas las restricciones que tiene la tabla nombrada. Para habilitar o deshabilitar restricciones la comprobacin de datos en inserciones o actualizaciones, la sintaxis bsica es: alter table NOMBRETABLA OPCIONdeRESTRICCION constraint NOMBRERESTRICCION; Para saber si una restriccin est habilitada o no, podemos ejecutar el procedimiento almacenado "sp_helpconstraint" y fijarnos lo que informa la columna "status_enabled". Entonces, las clusulas "check" y "nocheck" permiten habilitar o deshabilitar restricciones "check" (tambin las restricciones "foreign key" que veremos ms adelante), a las dems se las debe eliminar ("default" y las que veremos posteriormente).

50 - Restriccin primary keyHemos visto las restricciones que se aplican a los campos, "default" y "check". Ahora veremos las restricciones que se aplican a las tablas, que aseguran valores nicos para cada registro. Hay 2 tipos: 1) primary key y 2) unique. Anteriormente, para establecer una clave primaria para una tabla emplebamos la siguiente sintaxis al crear la tabla, por ejemplo: create table libros( codigo int not null, titulo varchar(30), autor varchar(30), editorial varchar(20), primary key(codigo) ); Cada vez que establecamos la clave primaria para la tabla, SQL Server creaba automticamente una restriccin "primary key" para dicha tabla. Dicha restriccin, a la cual no le dbamos un nombre, reciba un nombre dado por SQL Server que comienza con "PK" (por primary key), seguido del nombre de la tabla y una serie de letras y nmeros aleatorios. Podemos agregar una restriccin "primary key" a una tabla existente con la sintaxis bsica siguiente: alter table NOMBRETABLA add constraint NOMBRECONSTRAINT primary key (CAMPO,...); En el siguiente ejemplo definimos una restriccin "primary key" para nuestra tabla "libros" para asegurarnos que cada libro tendr un cdigo diferente y nico: alter table libros add constraint PK_libros_codigo primary key(codigo); Con esta restriccin, si intentamos ingresar un registro con un valor para el campo "codigo" que ya existe o el valor "null", aparece un mensaje de error, porque no se permiten valores duplicados ni nulos. Igualmente, si actualizamos. Por convencin, cuando demos el nombre a las restricciones "primary key" seguiremos el formato "PK_NOMBRETABLA_NOMBRECAMPO". Sabemos que cuando agregamos una restriccin a una tabla que contiene informacin, SQL Server controla los datos existentes para confirmar que cumplen las exigencias de la restriccin, si no los cumple, la restriccin no se aplica y aparece un mensaje de error. Por ejemplo, si intentamos definir la restriccin "primary key" para "libros" y hay registros con cdigos repetidos o con un valor "null", la restriccin no se establece.

Cuando establecamos una clave primaria al definir la tabla, automticamente SQL Server redefina el campo como "not null"; pero al agregar una restriccin "primary key", los campos que son clave primaria DEBEN haber sido definidos "not null" (o ser implcitamente "not null" si se definen identity). SQL Server permite definir solamente una restriccin "primary key" por tabla, que asegura la unicidad de cada registro de una tabla. Si ejecutamos el procedimiento almacenado "sp_helpconstraint" junto al nombre de la tabla, podemos ver las restricciones "primary key" (y todos los tipos de restricciones) de dicha tabla. Un campo con una restriccin "primary key" puede tener una restriccin "check". Un campo "primary key" tambin acepta una restriccin "default" (excepto si es identity), pero no tiene sentido ya que el valor por defecto solamente podr ingresarse una vez; si intenta ingresarse cuando otro registro ya lo tiene almacenado, aparecer un mensaje de error indicando que se intenta duplicar la clave.

51 - Restriccin uniqueHemos visto que las restricciones aplicadas a tablas aseguran valores nicos para cada registro. Anteriormente aprendimos la restriccin "primary key", otra restriccin para las tablas es "unique". La restriccin "unique" impide la duplicacin de claves alternas (no primarias), es decir, especifica que dos registros no puedan tener el mismo valor en un campo. Se permiten valores nulos. Se pueden aplicar varias restricciones de este tipo a una misma tabla, y pueden aplicarse a uno o varios campos que no sean clave primaria. Se emplea cuando ya se estableci una clave primaria (como un nmero de legajo) pero se necesita asegurar que otros datos tambin sean nicos y no se repitan (como nmero de documento). La sintaxis general es la siguiente: alter table NOMBRETABLA add constraint NOMBRERESTRICCION unique (CAMPO); Ejemplo: alter table alumnos add constraint UQ_alumnos_documento unique (documento); En el ejemplo anterior se agrega una restriccin "unique" sobre el campo "documento" de la tabla "alumnos", esto asegura que no se pueda ingresar un documento si ya existe. Esta restriccin permite valores nulos, asi que si se ingresa el valor "null" para el campo "documento", se acepta. Por convencin, cuando demos el nombre a las restricciones "unique" seguiremos la misma estructura: "UQ_NOMBRETABLA_NOMBRECAMPO". Quiz parezca innecesario colocar el nombre de

la tabla, pero cuando empleemos varias tablas ver que es til identificar las restricciones por tipo, tabla y campo. Recuerde que cuando agregamos una restriccin a una tabla que contiene informacin, SQL Server controla los datos existentes para confirmar que cumplen la condicin de la restriccin, si no los cumple, la restriccin no se aplica y aparece un mensaje de error. En el caso del ejemplo anterior, si la tabla contiene nmeros de documento duplicados, la restriccin no podr establecerse; si podr establecerse si tiene valores nulos. SQL Server controla la entrada de datos en inserciones y actualizaciones evitando que se ingresen valores duplicados

52 - Informacin de restricciones (sp_helpconstraint)El procedimiento almacenado "sp_helpconstraint" seguido del nombre de una tabla muestra la informacin referente a todas las restricciones establecidas en dicha tabla, devuelve las siguientes columnas: - constraint_type: tipo de restriccin. Si es una restriccin de campo (default o check) indica sobre qu campo fue establecida. Si es de tabla (primary key o unique) indica el tipo de ndice creado (tema que veremos posteriormente). - constraint_name: nombre de la restriccin. - delete_action: solamente es aplicable para restricciones de tipo "foreign key" (la veremos posteriormente). - update_action: slo es aplicable para restricciones de tipo "foreign key" (la veremos posteriormente). - status_enabled: solamente es aplicable para restricciones de tipo "check" y "foreign key". Indica si est habilitada (Enabled) o no (Disabled). Indica "n/a" en cualquier restriccin para la que no se aplique. - status_for_replication: solamente es aplicable para restricciones de tipo "check" y "foreign key". Indica "n/a" en cualquier restriccin para la que no se aplique. - constraint_keys: Si es una restriccin "check" muestra la condicin de chequeo; si es una restriccin "default", el valor por defecto; si es una "primary key" o "unique" muestra el/ los campos a los que se aplicaron la restriccin

53 - Eliminar restricciones (alter table - drop)Para eliminar una restriccin, la sintaxis bsica es la siguiente: alter table NOMBRETABLA drop NOMBRERESTRICCION; Para eliminar la restriccin "DF_libros_autor" de la tabla libros tipeamos: alter table libros drop DF_libros_autor;

Pueden eliminarse varias restricciones con una sola instruccin separndolas por comas. Cuando eliminamos una tabla, todas las restricciones que fueron establecidas en ella, se eliminan tambin.

54 - Crear y asociar reglas (create rule - sp_bindrule)Vimos que SQL Server ofrece varias alternativas para asegurar la integridad de datos, mediante el uso de: 1. RESTRICCIONES (constraints), que se establecen en tablas y campos y son controlados automticamente por SQL Server. Hay 3 tipos: I) DE LOS CAMPOS (hace referencia a los valores vlidos para un campo determinado). Pueden ser: a) DEFAULT: especifica un valor por defecto para un campo cuando no se inserta explcitamente en un comando "insert". b) CHECK: especifica un rango de valores que acepta un campo, se emplea en inserciones y actualizaciones ("insert" y "update"). II) DE LA TABLA (asegura un identificador nico para cada registro de una tabla). Hay 2 tipos: a) PRIMARY KEY: identifica unvocamente cada uno de los registros; asegura que no haya valores duplicados ni valores nulos. Se crea un ndice automticamente. b) UNIQUE: impide la duplicacin de claves alternas (no primarias). Se permiten valores nulos. Se crea un ndice automticamente. III) REFERENCIAL: lo veremos ms adelante. 2. REGLAS (rules) y 3. VALORES PREDETERMINADOS (defaults).

Veamos las reglas. Las reglas especifican los valores que se pueden ingresar en un campo, asegurando que los datos se encuentren en un intervalo de valores especfico, coincidan con una lista de valores o sigan un patrn. Una regla se asocia a un campo de una tabla (o a un tipo de dato definido por el usuario, tema que veremos posteriormente). Un campo puede tener solamente UNA regla asociado a l. Sintaxis bsica es la siguiente:

create rule NOMBREREGLA as @VARIABLE CONDICION Entonces, luego de "create rule" se coloca el nombre de la regla, luego la palabra clave "as" seguido de una variable (a la cual la precede el signo arroba) y finalmente la condicin. Por convencin, nombraremos las reglas comenzando con "RG", el nombre del campo al que se asocia y alguna palabra que haga referencia a la condicin. La variable puede tener cualquier nombre, pero debe estar precedido por el signo arroba (@), dicha variable ser reemplazada por el valor del campo cuando se asocie. La condicin se refiere a los valores permitidos para inserciones y actualizaciones y puede contener cualquier expresin vlida para una clusula "where"; no puede hacer referencia a los campos de una tabla. Creamos una regla para restringir los valores que se pueden ingresar en un campo "sueldo" de una tabla llamada "empleados", estableciendo un intervalo de valores: create rule RG_sueldo_intervalo as @sueldo between 100 and 1000 Luego de crear la regla, debemos asociarla a un campo ejecutando un procedimiento almacenado del sistema empleando la siguiente sintaxis bsica: exec sp_bindrule NOMBREREGLA, 'TABLA.CAMPO'; Asociamos la regla creada anteriormente al campo "sueldo" de la tabla "empleados": exec sp_bindrule RG_sueldo_intervalo, 'empleados.sueldo'; Si intentamos agregar (o actualizar) un registro con valor para el campo "sueldo" que no est en el intervalo de valores especificado en la regla, aparece un mensaje de error indicando que hay conflicto con la regla y la insercin (o actualizacin) no se realiza. SQL Server NO controla los datos existentes para confirmar que cumplen con la regla como lo hace al aplicar restricciones; si no los cumple, la regla se asocia igualmente; pero al ejecutar una instruccin "insert" o "update" muestra un mensaje de error, es decir, acta en inserciones y actualizaciones. La regla debe ser compatible con el tipo de datos del campo al cual se asocia; si esto no sucede, SQL Server no lo informa al crear la regla ni al asociarla, pero al ejecutar una instruccin "insert" o "update" muestra un mensaje de error. No se puede crear una regla para campos de tipo text, image, o timestamp. Si asocia una nueva regla a un campo que ya tiene asociada otra regla, la nueva regla reeemplaza la asociacin anterior; pero la primera regla no desaparece, solamente se deshace la asociacin. La sentencia "create rule" no puede combinarse con otras sentencias en un lote.

La funcin que cumple una regla es bsicamente la misma que una restriccin "check", las siguientes caractersticas explican algunas diferencias entre ellas: - podemos definir varias restricciones "check" sobre un campo, un campo solamente puede tener una regla asociada a l; - una restriccin "check" se almacena con la tabla, cuando sta se elimina, las restricciones tambin se borran. Las reglas son objetos diferentes e independientes de las tablas, si eliminamos una tabla, las asociaciones desaparecen, pero las reglas siguen existiendo en la base de datos; - una restriccin "check" puede incluir varios campos; una regla puede asociarse a distintos campos (incluso de distintas tablas); - una restriccin "check" puede hacer referencia a otros campos de la misma tabla, una regla no. Un campo puede tener reglas asociadas a l y restricciones "check". Si hay conflicto entre ellas, SQL Server no lo informa al crearlas y/o asociarlas, pero al intentar ingresar un valor que alguna de ellas no permita, aparece un mensaje de error. Con "sp_helpconstraint" podemos ver las reglas asociadas a los campos de una tabla. Con "sp_help" podemos ver todos los objetos de la base de datos activa, incluyendo las reglas, en tal caso en la columna "Object_type" aparece "rule".

55 - Eliminar y dasasociar reglas (sp_unbindrule - drop rule)Para eliminar una regla, primero se debe deshacer la asociacin, ejecutando el procedimiento almacenado del sistema "sp_unbindrule": exec sp_unbindrule 'TABLA.CAMPO'; No es posible eliminar una regla si est asociada a un campo. Si intentamos hacerlo, aparece un mensaje de error y la eliminacin no se realiza. Con la instruccin "drop rule" eliminamos la regla: drop rule NOMBREREGLA; Quitamos la asociacin de la regla "RG_sueldo_intervalo" con el campo "sueldo" de la tabla "empleados" tipeando: exec sp_unbindrule 'empleados.sueldo'; Luego de quitar la asociacin la eliminamos: drop rule RG_sueldo_100a1000; Si eliminamos una tabla, las asociaciones de reglas de sus campos desaparecen, pero las reglas siguen existiendo.

56 - Informacin de reglas (sp_help - sp_helpconstraint)Podemos utilizar el procedimiento almacenado "sp_help" con el nombre del objeto del cual queremos informacin, en este caso el nombre de una regla: sp_help NOMBREREGLA; muestra nombre, propietario, tipo y fecha de creacin. Con "sp_help", no sabemos si las reglas existentes estn o no asociadas a algn campo. "sp_helpconstraint" retorna una lista de todas las restricciones que tiene una tabla. Podemos ver las reglas asociadas a una tabla con este procedimiento almacenado: sp_helpconstraint NOMBRETABLA; muestra la siguiente informacin: - constraint_type: indica que es una regla con "RULE", nombrando el campo al que est asociada. - constraint_name: nombre de la regla. - constraint_keys: muestra el texto de la regla. Para ver el texto de una regla empleamos el procedimiento almacenado "sp_helptext" seguido del nombre de la regla: sp_helptext NOMBREREGLA; Tambin se puede consultar la tabla del sistema "sysobjects", que nos muestra el nombre y varios datos de todos los objetos de la base de datos actual. La columna "xtype" indica el tipo de objeto, en caso de ser una regla aparece el valor "R": select *from sysobjects; Si queremos ver todas las reglas creadas por nosotros, podemos tipear: select *from sysobjects where xtype='R' and-- tipo regla name like 'RG%';--bsqueda con comodn

57 - Valores predeterminados (create default)Hemos visto que para mantener la integridad declarativa se emplean restricciones, reglas (que hemos estudiado en secciones anteriores) y valores predeterminados. Veamos los valores predeterminados. Los valores predeterminados se asocian con uno o varios campos (o tipos de datos definidos por el usuario); se definen una sola vez y se pueden usar muchas veces.

Si no se coloca un valor cuando se ingresan datos, el valor predeterminado especifica el valor del campo al que est asociado. Sintaxis bsica: create default NOMBREVALORPREDETERMINADO as VALORPREDETERMINADO; "VALORPREDETERMINADO" no puede hacer referencia a campos de una tabla (u otros objetos) y debe ser compatible con el tipo de datos y longitud del campo al cual se asocia; si esto no sucede, SQL Server no lo informa al crear el valor predeterminado ni al asociarlo, pero al ejecutar una instruccin "insert" muestra un mensaje de error. En el siguiente ejemplo creamos un valor predeterminado llamado "VP_datodesconocido' con el valor "Desconocido": create default VP_datodesconocido as 'Desconocido' Luego de crear un valor predeterminado, debemos asociarlo a un campo (o a un tipo de datos definido por el usuario) ejecutando el procedimiento almacenado del sistema "sp_bindefault": exec sp_bindefault NOMBRE, 'NOMBRETABLA.CAMPO'; La siguiente sentencia asocia el valor predeterminado creado anteriormente al campo "domicilio" de la tabla "empleados": exec sp_bindefault VP_datodesconocido, 'empleados.domicilio'; Podemos asociar un valor predeterminado a varios campos. Asociamos el valor predeterminado "VP_datodesconocido" al campo "barrio" de la tabla "empleados": exec sp_bindefault VP_datodesconocido, 'empleados.barrio'; La funcin que cumple un valor predeterminado es bsicamente la misma que una restriccin "default", las siguientes caractersticas explican algunas semejanzas y diferencias entre ellas: - un campo solamente puede tener definida UNA restriccin "default", un campo solamente puede tener UN valor predeterminado asociado a l, - una restriccin "default" se almacena con la tabla, cuando sta se elimina, las restricciones tambin. Los valores predeterminados son objetos diferentes e independientes de las tablas, si eliminamos una tabla, las asociaciones desaparecen, pero los valores predeterminados siguen existiendo en la base de datos. - una restriccin "default" se establece para un solo campo; un valor predeterminado puede asociarse a distintos campos (inclusive, de diferentes tablas). - una restriccin "default" no puede establecerse sobre un campo "identity", tampoco un valor predeterminado. No se puede asociar un valor predeterminado a un campo que tiene una restriccin "default".

Un campo con un valor predeterminado asociado puede tener reglas asociadas a l y restricciones "check". Si hay conflicto entre ellas, SQL Server no lo informa al crearlas y/o asociarlas, pero al intentar ingresar un valor que alguna de ellas no permita, aparece un mensaje de error. La sentencia "create default" no puede combinarse con otra sentencia en un mismo lote. Si asocia a un campo que ya tiene asociado un valor predeterminado otro valor predeterminado, la nueva asociacin reemplaza a la anterior. Veamos otros ejemplos. Creamos un valor predeterminado que inserta el valor "0" en un campo de tipo numrico: create default VP_cero as 0; En el siguiente creamos un valor predeterminado que inserta ceros con el formato vlido para un nmero de telfono: create default VP_telefono as '(0000)0-000000'; Con "sp_helpconstraint" podemos ver los valores predeterminados asociados a los campos de una tabla. Con "sp_help" podemos ver todos los objetos de la base de datos activa, incluyendo los valores predeterminados, en tal caso en la columna "Object_type" aparece "default".

58 - Desasociar y eliminar valores predeterminadosUn valor predeterminado no puede eliminarse si no se ha desasociado previamente. Para deshacer una asociacin empleamos el procedimiento almacenado "sp_unbindefault" seguido de la tabla y campo al que est asociado: sp_unbindefault 'TABLA.CAMPO'; Quitamos la asociacin al campo "sueldo" de la tabla "empleados": sp_unbindefault 'empleados.sueldo'; Con la instruccin "drop default" podemos eliminar un valor predeterminado: drop default NOMBREVALORPREDETERMINADO; Eliminamos el valor predeterminado llamado "VP_cero": drop default VP_cero; Si eliminamos una tabla, las asociaciones de valores predeterminados de sus campos desaparecen, pero los valores predeterminados siguen existiendo.

59 - Informacin de valores predeterminadosPara obtener informacin de los valores predeterminados podemos emplear los mismos procedimientos almacenados que usamos para las reglas. Si empleamos "sp_help", vemos todos los objetos de la base de datos activa (incluyendo los valores predeterminados); en la columna "Object_type" (tipo de objeto) muestra "default". Si al procedimiento almacenado "sp_help" le agregamos el nombre de un valor predeterminado, nos muestra el nombre, propietario, tipo y fecha de creacin: sp_help NOMBREVALORPREDETERMINADO; Con "sp_help", no sabemos si los valores predeterminados existentes estn o no asociadas a algn campo. "sp_helpconstraint" retorna una lista de todas las restricciones que tiene una tabla. Tambin los valores predeterminados asociados; muestra la siguiente informacin: - constraint_type: indica que es un valor predeterminado con "DEFAULT", nombrando el campo al que est asociado. - constraint_name: nombre del valor predeterminado. - constraint_keys: muestra el texto del valor predeterminado. Con "sp_helptext" seguido del nombre de un valor predeterminado podemos ver el texto de cualquier valor predeterminado: sp_helptext NOMBREVALORPREDETERMINADO; Tambin se puede consultar la tabla del sistema "sysobjects", que nos muestra el nombre y varios datos de todos los objetos de la base de datos actual. La columna "xtype" indica el tipo de objeto, en caso de ser un valor predeterminado aparece el valor "D": select *from sysobjects; Si queremos ver todos los valores predeterminados creados por nosotros, podemos tipear: select *from sysobjects where xtype='D' and-- tipo valor predeterminado name like 'VP%';--bsqueda con comodn

60 - IndicesSQL Server accede a los datos de dos maneras: 1. recorriendo las tablas; comenzando el principio y extrayendo los registros que cumplen las condiciones de la consulta. 2. empleando ndices; recorriendo la estructura de rbol del ndice para localizar los registros y extrayendo los que cumplen las condiciones de la consulta.

Los ndices se emplean para facilitar la obtencin de informacin de una tabla. El indice de una tabla desempea la misma funcin que el ndice de un libro: permite encontrar datos rpidamente; en el caso de las tablas, localiza registros. Una tabla se indexa por un campo (o varios). Un ndice posibilita el acceso directo y rpido haciendo ms eficiente las bsquedas. Sin ndice, SQL Server debe recorrer secuencialmente toda la tabla para encontrar un registro. El objetivo de un indice es acelerar la recuperacin de informacin. La indexacin es una tcnica que optimiza el acceso a los datos, mejora el rendimiento acelerando las consultas y otras operaciones. Es til cuando la tabla contiene miles de registros, cuando se realizan operaciones de ordenamiento y agrupamiento y cuando se combinan varias tablas (tema que veremos ms adelante). La desventaja es que consume espacio en el disco en disco y genera costo de mantenimiento (tiempo y recursos). Los ndices ms adecuados son aquellos creados con campos que contienen valores nicos. Es importante identificar el o los campos por los que sera til crear un ndice, aquellos campos por los cuales se realizan bsqueda con frecuencia: claves primarias, claves externas o campos que combinan tablas. No se recomienda crear ndices por campos que no se usan con frecuencia en consultas o no contienen valores nicos. SQL Server permite crear dos tipos de ndices: 1) agrupados y 2) no agrupados.

61 - Indices agrupados y no agrupados (clustered y nonclustered)Dijimos que SQL Server permite crear dos tipos de ndices: 1) agrupados (clustered) y 2) no agrupados (nonclustered). 1) Un INDICE AGRUPADO es similar a una gua telefnica, los registros con el mismo valor de campo se agrupan juntos. Un ndice agrupado determina la secuencia de almacenamiento de los registros en una tabla. Se utilizan para campos por los que se realizan busquedas con frecuencia o se accede siguiendo un orden. Una tabla slo puede tener UN ndice agrupado. El tamao medio de un ndice agrupado es aproximadamente el 5% del tamao de la tabla. 2) Un INDICE NO AGRUPADO es como el ndice de un libro, los datos se almacenan en un lugar diferente al del ndice, los punteros indican el lugar de almacenamiento de los elementos indizados en la tabla. Un ndice no agrupado se emplea cuando se realizan distintos tipos de busquedas frecuentemente, con campos en los que los datos son nicos. Una tabla puede tener hasta 249 ndices no agrupados. Si no se especifica un tipo de ndice, de modo predeterminado ser no agrupado. Los campos de tipo text, ntext e image no se pueden indizar.

Es recomendable crear los ndices agrupados antes que los no agrupados, porque los primeros modifican el orden fsico de los registros, ordenndolos secuencialmente. La diferencia bsica entre ndices agrupados y no agrupados es que los registros de un ndice agrupado estn ordenados y almacenados de forma secuencial en funcin de su clave. SQL Server crea automaticamente ndices cuando se crea una restriccin "primary key" o "unique" en una tabla. Es posible crear ndices en las vistas. Resumiendo, los ndices facilitan la recuperacin de datos, permitiendo el acceso directo y acelerando las bsquedas, consultas y otras operaciones que optimizan el rendimiento general.

62 - Creacin de ndicesPara crear ndices empleamos la instruccin "create index". La sintaxis bsica es la siguiente: create TIPODEINDICE index NOMBREINDICE on TABLA(CAMPO); "TIPODEINDICE" indica si es agrupado (clustered) o no agrupado (nonclustered). Si no especificamos crea uno No agrupado. Independientemente de si es agrupado o no, tambin se puede especificar que sea "unique", es decir, no haya valores repetidos. Si se intenta crear un ndice unique para un campo que tiene valores duplicados, SQL Server no lo permite. En este ejemplo se crea un ndice agrupado nico para el campo "codigo" de la tabla "libros": create unique clustered index I_libros_codigo on libros(codigo); Para identificar los ndices fcilmente, podemos agregar un prefijo al nombre del ndice, por ejemplo "I" y luego el nombre de la tabla y/o campo. En este ejemplo se crea un ndice no agrupado para el campo "titulo" de la tabla "libros": create nonclustered index I_libros_titulo on libros(titulo); Un ndice puede tener ms de un campo como clave, son ndices compuestos. Los campos de un ndice compuesto tienen que ser de la misma tabla (excepto cuando se crea en una vista - tema que veremos posteriormente). Creamos un ndice compuesto para el campo "autor" y "editorial": create index I_libros_autoreditorial on libros(autor,editorial); SQL Server crea automticamente ndices cuando se establece una restriccin "primary key" o "unique" en una tabla. Al crear una restriccin "primary key", si no se especifica, el ndice ser

agrupado (clustered) a menos que ya exista un ndice agrupado para dicha tabla. Al crear una restriccin "unique", si no se especifica, el ndice ser no agrupado (non-clustered). Ahora podemos entender el resultado del procedimiento almacenado "sp_helpconstraint" cuando en la columna "constraint_type" mostraba el tipo de ndice seguido de las palabras "clustered" o "non_clustered". Puede especificarse que un ndice sea agrupado o no agrupado al agregar estas restricciones. Agregamos una restriccin "primary key" al campo "codigo" de la tabla "libros" especificando que cree un ndice NO agrupado: alter table libros add constraint PK_libros_codigo primary key nonclustered (codigo); Para ver los indices de una tabla: sp_helpindex libros; Muestra el nombre del ndice, si es agrupado (o no), primary (o unique) y el campo por el cual se indexa. Todos los ndices de la base de datos activa se almacenan en la tabla del sistema "sysindexes", podemos consultar dicha tabla tipeando: select name from sysindexes; Para ver todos los ndices de la base de datos activa creados por nosotros podemos tipear la siguiente consulta: select name from sysindexes where name like 'I_%';

63 - Regenerar ndicesVimos que para crear ndices empleamos la instruccin "create index". Empleando la opcin "drop_existing" junto con "create index" permite regenerar un ndice, con ello evitamos eliminarlo y volver a crearlo. La sintaxis es la siguiente: create TIPODEINDICE index NOMBREINDICE on TABLA(CAMPO) with drop_existing; Tambin podemos modificar alguna de las caractersticas de un ndice con esta opcin, a saber: - tipo: cambindolo de no agrupado a agrupado (siempre que no exista uno agrupado para la misma tabla). No se puede convertir un ndice agrupado en No agrupado. - campo: se puede cambiar el campo por el cual se indexa, agregar campos, eliminar algn campo de un ndice compuesto.

- nico: se puede modificar un ndice para que los valores sean nicos o dejen de serlo. En este ejemplo se crea un ndice no agrupado para el campo "titulo" de la tabla "libros": create nonclustered index I_libros on libros(titulo); Regeneramos el ndice "I_libros" y lo convertimos a agrupado: create clustered index I_libros on libros(titulo) with drop_existing; Agregamos un campo al ndice "I_libros": create clustered index I_libros on libros(titulo,editorial) with drop_existing; Esta opcin no puede emplearse con ndices creados a partir de una restriccin "primary key" o "unique".

64 - Eliminar ndicesLos ndices creados con "create index" se eliminan con "drop index"; la siguiente es la sintaxis bsica: drop index NOMBRETABLA.NOMBREINDICE; Eliminamos el ndice "I_libros_titulo": drop index libros.I_libros_titulo; Los ndices que SQL Server crea automticamente al establecer una restriccin "primary key" o "unique" no pueden eliminarse con "drop index", se eliminan automticamente cuando quitamos la restriccin. Podemos averiguar si existe un ndice para eliminarlo, consultando la tabla del sistema "sysindexes": if exists (select name from sysindexes where name = 'NOMBREINDICE') drop index NOMBRETABLA.NOMBREINDICE; Eliminamos el ndice "I_libros_titulo" si existe: if exists (select *from sysindexes where name = 'I_libros_titulo') drop index libros.I_libros_titulo;

65 - Trabajar con varias tablas

Hasta el momento hemos trabajado con una sola tabla, pero generalmente, se trabaja con ms de una. Para evitar la repeticin de datos y ocupar menos espacio, se separa la informacin en varias tablas. Cada tabla almacena parte de la informacin que necesitamos registrar. Por ejemplo, los datos de nuestra tabla "libros" podran separarse en 2 tablas, una llamada "libros" y otra "editoriales" que guardar la informacin de las editoriales. En nuestra tabla "libros" haremos referencia a la editorial colocando un cdigo que la identifique. Veamos: create table libros( codigo int identity, titulo varchar(40) not null, autor varchar(30) not null default 'Desconocido', codigoeditorial tinyint not null, precio decimal(5,2), primary key (codigo) ); create table editoriales( codigo tinyint identity, nombre varchar(20) not null, primary key(codigo) ); De esta manera, evitamos almacenar tantas veces los nombres de las editoriales en la tabla "libros" y guardamos el nombre en la tabla "editoriales"; para indicar la editorial de cada libro agregamos un campo que hace referencia al cdigo de la editorial en la tabla "libros" y en "editoriales". Al recuperar los datos de los libros con la siguiente instruccin: select* from libros; vemos que en el campo "editorial" aparece el cdigo, pero no sabemos el nombre de la editorial. Para obtener los datos de cada libro, incluyendo el nombre de la editorial, necesitamos consultar ambas tablas, traer informacin de las dos. Cuando obtenemos informacin de ms de una tabla decimos que hacemos un "join" (combinacin). Veamos un ejemplo: select *from libros join editoriales on libros.codigoeditorial=editoriales.codigo; Resumiendo: si distribuimos la informacin en varias tablas evitamos la redundancia de datos y ocupamos menos espacio fsico en el disco. Un join es una operacin que relaciona dos o ms tablas para obtener un resultado que incluya datos (campos y registros) de ambas; las tablas participantes se combinan segn los campos comunes a ambas tablas.

Hay hay tres tipos de combinaciones. En los siguientes captulos explicamos cada una de ellas.

66 - Combinacin interna (inner join)Un join es una operacin que relaciona dos o ms tablas para obtener un resultado que incluya datos (campos y registros) de ambas; las tablas participantes se combinan segn los campos comunes a ambas tablas. Hay tres tipos de combinaciones: 1. combinaciones internas (inner join o join), 2. combinaciones externas y 3. combinaciones cruzadas. Tambin es posible emplear varias combinaciones en una consulta "select", incluso puede combinarse una tabla consigo misma. La combinacin interna emplea "join", que es la forma abreviada de "inner join". Se emplea para obtener informacin de dos tablas y combinar dicha informacin en una salida. La sintaxis bsica es la siguiente: select CAMPOS from TABLA1 join TABLA2 on CONDICIONdeCOMBINACION; Ejemplo: select *from libros join editoriales on codigoeditorial=editoriales.codigo; Analicemos la consulta anterior. - especificamos los campos que aparecern en el resultado en la lista de seleccin; - indicamos el nombre de la tabla luego del "from" ("libros"); - combinamos esa tabla con "join" y el nombre de la otra tabla ("editoriales"); se especifica qu tablas se van a combinar y cmo; - cuando se combina informacin de varias tablas, es necesario especificar qu registro de una tabla se combinar con qu registro de la otra tabla, con "on". Se debe especificar la condicin para enlazarlas, es decir, el campo por el cual se combinarn, que tienen en comn. "on" hace coincidir registros de ambas tablas basndose en el valor de tal campo, en el ejemplo, el campo "codigoeditorial" de "libros" y el campo "codigo" de "editoriales" son los que enlazarn ambas tablas. Se emplean campos comunes, que deben tener tipos de datos iguales o similares. La condicion de combinacin, es decir, el o los campos por los que se van a combinar (parte "on"), se especifica segn las claves primarias y externas.

Note que en la consulta, al nombrar el campo usamos el nombre de la tabla tambin. Cuando las tablas referenciadas tienen campos con igual nombre, esto es necesario para evitar confusiones y ambiguedades al momento de referenciar un campo. En el ejemplo, si no especificamos "editoriales.codigo" y solamente tipeamos "codigo", SQL Server no sabr si nos referimos al campo "codigo" de "libros" o de "editoriales" y mostrar un mensaje de error indicando que "codigo" es ambiguo. Entonces, si las tablas que combinamos tienen nombres de campos iguales, DEBE especificarse a qu tabla pertenece anteponiendo el nombre de la tabla al nombre del campo, separado por un punto (.). Si una de las tablas tiene clave primaria compuesta, al combinarla con la otra, en la clusula "on" se debe hacer referencia a la clave completa, es decir, la condicin referenciar a todos los campos clave que identifican al registro. Se puede incluir en la consulta join la clusula "where" para restringir los registros que retorna el resultado; tambin "order by", "distinct", etc.. Se emplea este tipo de combinacin para encontrar registros de la primera tabla que se correspondan con los registros de la otra, es decir, que cumplan la condicin del "on". Si un valor de la primera tabla no se encuentra en la segunda tabla, el registro no aparece. Para simplificar la sentencia podemos usar un alias para cada tabla: select l.codigo,titulo,autor,nombre from libros as l join editoriales as e on l.codigoeditorial=e.codigo; En algunos casos (como en este ejemplo) el uso de alias es para fines de simplificacin y hace ms legible la consulta si es larga y compleja, pero en algunas consultas es absolutamente necesario.

67 - Combinacin externa izquierda (left join)Vimos que una combinacin interna (join) encuentra registros de la primera tabla que se correspondan con los registros de la segunda, es decir, que cumplan la condicin del "on" y si un valor de la primera tabla no se encuentra en la segunda tabla, el registro no aparece. Si queremos saber qu registros de una tabla NO encuentran correspondencia en la otra, es decir, no existe valor coincidente en la segunda, necesitamos otro tipo de combinacin, "outer join" (combinacin externa). Las combinaciones externas combinan registros de dos tablas que cumplen la condicin, ms los registros de la segunda tabla que no la cumplen; es decir, muestran todos los registros de las tablas relacionadas, an cuando no haya valores coincidentes entre ellas. Este tipo de combinacin se emplea cuando se necesita una lista completa de los datos de una de las tablas y la informacin que cumple con la condicin. Las combinaciones externas se realizan solamente entre 2 tablas. Hay tres tipos de combinaciones externas: "left outer join", "right outer join" y "full outer join"; se pueden abreviar con "left join", "right join" y "full join" respectivamente.

Vamos a estudiar las primeras. Se emplea una combinacin externa izquierda para mostrar todos los registros de la tabla de la izquierda. Si no encuentra coincidencia con la tabla de la derecha, el registro muestra los campos de la segunda tabla seteados a "null". En el siguiente ejemplo solicitamos el ttulo y nombre de la editorial de los libros: select titulo,nombre from editoriales as e left join libros as l on codigoeditorial = e.codigo; El resultado mostrar el ttulo y nombre de la editorial; las editoriales de las cuales no hay libros, es decir, cuyo cdigo de editorial no est presente en "libros" aparece en el resultado, pero con el valor "null" en el campo "titulo". Es importante la posicin en que se colocan las tablas en un "left join", la tabla de la izquierda es la que se usa para localizar registros en la tabla de la derecha. Entonces, un "left join" se usa para hacer coincidir registros en una tabla (izquierda) con otra tabla (derecha); si un valor de la tabla de la izquierda no encuentra coincidencia en la tabla de la derecha, se genera una fila extra (una por cada valor no encontrado) con todos los campos correspondientes a la tabla derecha seteados a "null". La sintaxis bsica es la siguiente: select CAMPOS from TABLAIZQUIERDA left join TABLADERECHA on CONDICION; En el siguiente ejemplo solicitamos el ttulo y el nombre la editorial, la sentencia es similar a la anterior, la diferencia est en el orden de las tablas: select titulo,nombre from libros as l left join editoriales as e on codigoeditorial = e.codigo; El resultado mostrar el ttulo del libro y el nombre de la editorial; los ttulos cuyo cdigo de editorial no est presente en "editoriales" aparecen en el resultado, pero con el valor "null" en el campo "nombre". Un "left join" puede tener clausula "where" que restringa el resultado de la consulta considerando solamente los registros que encuentran coincidencia en la tabla de la derecha, es decir, cuyo valor de cdigo est presente en "libros": select titulo,nombre from editoriales as e left join libros as l on e.codigo=codigoeditorial where codigoeditorial is not null;

Tambin podemos mostrar las editoriales que NO estn presentes en "libros", es decir, que NO encuentran coincidencia en la tabla de la derecha: select titulo,nombre from editoriales as e left join libros as l on e.codigo=codigoeditorial where codigoeditorial is null;

68 - Combinacin externa derecha (right join)Vimos que una combinacin externa izquierda (left join) encuentra registros de la tabla izquierda que se correspondan con los registros de la tabla derecha y si un valor de la tabla izquierda no se encuentra en la tabla derecha, el registro muestra los campos correspondientes a la tabla de la derecha seteados a "null". Una combinacin externa derecha ("right outer join" o "right join") opera del mismo modo slo que la tabla derecha es la que localiza los registros en la tabla izquierda. En el siguiente ejemplo solicitamos el ttulo y nombre de la editorial de los libros empleando un "right join": select titulo,nombre from libros as l right join editoriales as e on codigoeditorial = e.codigo; El resultado mostrar el ttulo y nombre de la editorial; las editoriales de las cuales no hay libros, es decir, cuyo cdigo de editorial no est presente en "libros" aparece en el resultado, pero con el valor "null" en el campo "titulo". Es FUNDAMENTAL tener en cuenta la posicin en que se colocan las tablas en los "outer join". En un "left join" la primera tabla (izquierda) es la que busca coincidencias en la segunda tabla (derecha); en el "right join" la segunda tabla (derecha) es la que busca coincidencias en la primera tabla (izquierda). En la siguiente consulta empleamos un "left join" para conseguir el mismo resultado que el "right join" anterior": select titulo,nombre from editoriales as e left join libros as l on codigoeditorial = e.codigo; Note que la tabla que busca coincidencias ("editoriales") est en primer lugar porque es un "left join"; en el "right join" precedente, estaba en segundo lugar. Un "right join" hace coincidir registros en una tabla (derecha) con otra tabla (izquierda); si un valor de la tabla de la derecha no encuentra coincidencia en la tabla izquierda, se genera una fila extra (una por cada valor no encontrado) con todos los campos correspondientes a la tabla izquierda seteados a "null". La sintaxis bsica es la siguiente: select CAMPOS from TABLAIZQUIERDA

right join TABLADERECHA on CONDICION; Un "right join" tambin puede tener clusula "where" que restringa el resultado de la consulta considerando solamente los registros que encuentran coincidencia en la tabla izquierda: select titulo,nombre from libros as l right join editoriales as e on e.codigo=codigoeditorial where codigoeditorial is not null; Mostramos las editoriales que NO estn presentes en "libros", es decir, que NO encuentran coincidencia en la tabla de la derecha empleando un "right join": select titulo,nombre from libros as l rightjoin editoriales as e on e.codigo=codigoeditorial where codigoeditorial is null;

69 - Combinacin externa completa (full join)Vimos que un "left join" encuentra registros de la tabla izquierda que se correspondan con los registros de la tabla derecha y si un valor de la tabla izquierda no se encuentra en la tabla derecha, el registro muestra los campos correspondientes a la tabla de la derecha seteados a "null". Aprendimos tambin que un "right join" opera del mismo modo slo que la tabla derecha es la que localiza los registros en la tabla izquierda. Una combinacin externa completa ("full outer join" o "full join") retorna todos los registros de ambas tablas. Si un registro de una tabla izquierda no encuentra coincidencia en la tabla derecha, las columnas correspondientes a campos de la tabla derecha aparecen seteadas a "null", y si la tabla de la derecha no encuentra correspondencia en la tabla izquierda, los campos de esta ltima aparecen conteniendo "null". Veamos un ejemplo: select titulo,nombre from editoriales as e full join libros as l on codigoeditorial = e.codigo; La salida del "full join" precedente muestra todos los registros de ambas tablas, incluyendo los libros cuyo cdigo de editorial no existe en la tabla "editoriales" y las editoriales de las cuales no hay correspondencia en "libros".

70 - Combinaciones cruzadas (cross join)Vimos que hay tres tipos de combinaciones: 1) combinaciones internas (join), 2) combinaciones externas (left, right y full join) y 3) combinaciones cruzadas. Las combinaciones cruzadas (cross join) muestran todas las combinaciones de todos los registros de las tablas combinadas. Para este tipo de join no se incluye una condicin de enlace. Se genera

el producto cartesiano en el que el nmero de filas del resultado es igual al nmero de registros de la primera tabla multiplicado por el nmero de registros de la segunda tabla, es decir, si hay 5 registros en una tabla y 6 en la otra, retorna 30 filas. La sintaxis bsica es sta: select CAMPOS from TABLA1 cross join TABLA2; Veamos un ejemplo. Un pequeo restaurante almacena los nombres y precios de sus comidas en una tabla llamada "comidas" y en una tabla denominada "postres" los mismos datos de sus postres. Si necesitamos conocer todas las combinaciones posibles para un men, cada comida con cada postre, empleamos un "cross join": select c.nombre as 'plato principal', p.nombre as 'postre' from comidas as c cross join postres as p; La salida muestra cada plato combinado con cada uno de los postres. Como cualquier tipo de "join", puede emplearse una clusula "where" que condicione la salida.

71 - AutocombinacinDijimos que es posible combinar una tabla consigo misma. Un pequeo restaurante tiene almacenadas sus comidas en una tabla llamada "comidas" que consta de los siguientes campos: - nombre varchar(20), - precio decimal (4,2) y - rubro char(6)-- que indica con 'plato' si es un plato principal y 'postre' si es postre. Podemos obtener la combinacin de platos empleando un "cross join" con una sola tabla: select c1.nombre as 'plato principal', c2.nombre as postre, c1.precio+c2.precio as total from comidas as c1 cross join comidas as c2; En la consulta anterior aparecen filas duplicadas, para evitarlo debemos emplear un "where": select c1.nombre as 'plato principal', c2.nombre as postre, c1.precio+c2.precio as total from comidas as c1 cross join comidas as c2 where c1.rubro='plato' and

c2.rubro='postre'; En la consulta anterior se emple un "where" que especifica que se combine "plato" con "postre". En una autocombinacin se combina una tabla con una copia de si misma. Para ello debemos utilizar 2 alias para la tabla. Para evitar que aparezcan filas duplicadas, debemos emplear un "where". Tambin se puede realizar una autocombinacin con "join": select c1.nombre as 'plato principal', c2.nombre as postre, c1.precio+c2.precio as total from comidas as c1 join comidas as c2 on c1.codigoc2.codigo where c1.rubro='plato' and c2.rubro='postre'; Para que no aparezcan filas duplicadas se agrega un "where".

72 - Combinaciones y funciones de agrupamientoPodemos usar "group by" y las funciones de agrupamiento con combinaciones de tablas. Para ver la cantidad de libros de cada editorial consultando la tabla "libros" y "editoriales", tipeamos: select nombre as editorial, count(*) as cantidad from editoriales as e join libros as l on codigoeditorial=e.codigo group by e.nombre; Note que las editoriales que no tienen libros no aparecen en la salida porque empleamos un "join". Empleamos otra funcin de agrupamiento con "left join". Para conocer el mayor precio de los libros de cada editorial usamos la funcin "max()", hacemos un "left join" y agrupamos por nombre de la editorial: select nombre as editorial, max(precio) as 'mayor precio' from editoriales as e left join libros as l on codigoeditorial=e.codigo group by nombre; En la sentencia anterior, mostrar, para la editorial de la cual no haya libros, el valor "null" en la columna calculada.

73 - Combinacin de ms de dos tablasPodemos hacer un "join" con ms de dos tablas. Cada join combina 2 tablas. Se pueden emplear varios join para enlazar varias tablas. Cada resultado de un join es una tabla que puede combinarse con otro join. La librera almacena los datos de sus libros en tres tablas: libros, editoriales y autores. En la tabla "libros" un campo "codigoautor" hace referencia al autor y un campo "codigoeditorial" referencia la editorial. Para recuperar todos los datos de los libros empleamos la siguiente consulta: select titulo,a.nombre,e.nombre from autores as a join libros as l on codigoautor=a.codigo join editoriales as e on codigoeditorial=e.codigo; Analicemos la consulta anterior. Indicamos el nombre de la tabla luego del "from" ("autores"), combinamos esa tabla con la tabla "libros" especificando con "on" el campo por el cual se combinarn; luego debemos hacer coincidir los valores para el enlace con la tabla "editoriales" enlazndolas por los campos correspondientes. Utilizamos alias para una sentencia ms sencilla y comprensible. Note que especificamos a qu tabla pertenecen los campos cuyo nombre se repiten en las tablas, esto es necesario para evitar confusiones y ambiguedades al momento de referenciar un campo. Note que no aparecen los libros cuyo cdigo de autor no se encuentra en "autores" y cuya editorial no existe en "editoriales", esto es porque realizamos una combinacin interna. Podemos combinar varios tipos de join en una misma sentencia: select titulo,a.nombre,e.nombre from autores as a right join libros as l on codigoautor=a.codigo left join editoriales as e on codigoeditorial=e.codigo; En la consulta anterior solicitamos el ttulo, autor y editorial de todos los libros que encuentren o no coincidencia con "autores" ("right join") y a ese resultado lo combinamos con "editoriales", encuentren o no coincidencia. Es posible realizar varias combinaciones para obtener informacin de varias tablas. Las tablas deben tener claves externas relacionadas con las tablas a combinar. En consultas en las cuales empleamos varios "join" es importante tener en cuenta el orden de las tablas y los tipos de "join"; recuerde que la tabla resultado del primer join es la que se combina con el segundo join, no la segunda tabla nombrada. En el ejemplo anterior, el "left join" no se realiza entre las tablas "libros" y "editoriales" sino entre el resultado del "right join" y la tabla "editoriales".

74 - Combinaciones con update y deleteLas combinaciones no slo se utilizan con la sentencia "select", tambin podemos emplearlas con "update" y "delete". Podemos emplear "update" o "delete" con "join" para actualizar o eliminar registros de una tabla consultando otras tablas. En el siguiente ejemplo aumentamos en un 10% los precios de los libros de cierta editorial, necesitamos un "join" para localizar los registros de la editorial "Planeta" en la tabla "libros": update libros set precio=precio+(precio*0.1) from libros join editoriales as e on codigoeditorial=e.codigo where nombre='Planeta'; Eliminamos todos los libros de editorial "Emece": delete libros from libros join editoriales on codigoeditorial = editoriales.codigo where editoriales.nombre='Emece';

75 - Clave forneaUn campo que no es clave primaria en una tabla y sirve para enlazar sus valores con otra tabla en la cual es clave primaria se denomina clave fornea, externa o ajena. En el ejemplo de la librera en que utilizamos las tablas "libros" y "editoriales" con estos campos: libros: codigo (clave primaria), titulo, autor, codigoeditorial, precio y editoriales: codigo (clave primaria), nombre. el campo "codigoeditorial" de "libros" es una clave fornea, se emplea para enlazar la tabla "libros" con "editoriales" y es clave primaria en "editoriales" con el nombre "codigo". Las claves forneas y las claves primarias deben ser del mismo tipo para poder enlazarse. Si modificamos una, debemos modificar la otra para que los valores se correspondan. Cuando alteramos una tabla, debemos tener cuidado con las claves forneas. Si modificamos el tipo, longitud o atributos de una clave fornea, sta puede quedar inhabilitada para hacer los enlaces. Entonces, una clave fornea es un campo (o varios) empleados para enlazar datos de 2 tablas, para establecer un "join" con otra tabla en la cual es clave primaria.

76 - Restricciones (foreign key)

Hemos visto que una de las alternativas que SQL Server ofrece para asegurar la integridad de datos es el uso de restricciones (constraints). Aprendimos que las restricciones se establecen en tablas y campos asegurando que los datos sean vlidos y que las relaciones entre las tablas se mantengan; vimos que existen distintos tipos de restricciones: 1) de los campos: default y check 2) de la tabla: primary key y unique. 3) referencial: foreign key, la analizaremos ahora. Con la restriccin "foreign key" se define un campo (o varios) cuyos valores coinciden con la clave primaria de la misma tabla o de otra, es decir, se define una referencia a un campo con una restriccin "primary key" o "unique" de la misma tabla o de otra. La integridad referencial asegura que se mantengan las referencias entre las claves primarias y las externas. Por ejemplo, controla que si se agrega un cdigo de editorial en la tabla "libros", tal cdigo exista en la tabla "editoriales". Tambin controla que no pueda eliminarse un registro de una tabla ni modificar la clave primaria si una clave externa hace referencia al registro. Por ejemplo, que no se pueda eliminar o modificar un cdigo de "editoriales" si existen libros con dicho cdigo. La siguiente es la sintaxis parcial general para agregar una restriccin "foreign key": alter table NOMBRETABLA1 add constraint NOMBRERESTRICCION foreign key (CAMPOCLAVEFORANEA) references NOMBRETABLA2 (CAMPOCLAVEPRIMARIA); Analicmosla: - NOMBRETABLA1 referencia el nombre de la tabla a la cual le aplicamos la restriccin, - NOMBRERESTRICCION es el nombre que le damos a la misma, - luego de "foreign key", entre parntesis se coloca el campo de la tabla a la que le aplicamos la restriccin que ser establecida como clave fornea, - luego de "references" indicamos el nombre de la tabla referenciada y el campo que es clave primaria en la misma, a la cual hace referencia la clave fornea. La tabla referenciada debe tener definida una restriccin "primary key" o "unique"; si no la tiene, aparece un mensaje de error. Para agregar una restriccin "foreign key" al campo "codigoeditorial" de "libros", tipeamos: alter table libros add constraint FK_libros_codigoeditorial foreign key (codigoeditorial) references editoriales(codigo); En el ejemplo implementamos una restriccin "foreign key" para asegurarnos que el cdigo de la editorial de la de la tabla "libros" ("codigoeditorial") est asociada con un cdigo vlido en la tabla "editoriales" ("codigo").

Cuando agregamos cualquier restriccin a una tabla que contiene informacin, SQL Server controla los datos existentes para confirmar que cumplen con la restriccin, si no los cumple, la restriccin no se aplica y aparece un mensaje de error. Por ejemplo, si intentamos agregar una restriccin "foreign key" a la tabla "libros" y existe un libro con un valor de cdigo para editorial que no existe en la tabla "editoriales", la restriccin no se agrega. Acta en inserciones. Si intentamos ingresar un registro (un libro) con un valor de clave fornea (codigoeditorial) que no existe en la tabla referenciada (editoriales), SQL server muestra un mensaje de error. Si al ingresar un registro (un libro), no colocamos el valor para el campo clave fornea (codigoeditorial), almacenar "null", porque esta restriccin permite valores nulos (a menos que se haya especificado lo contrario al definir el campo). Acta en eliminaciones y actualizaciones. Si intentamos eliminar un registro o modificar un valor de clave primaria de una tabla si una clave fornea hace referencia a dicho registro, SQL Server no lo permite (excepto si se permite la accin en cascada, tema que veremos posteriormente). Por ejemplo, si intentamos eliminar una editorial a la que se hace referencia en "libros", aparece un mensaje de error. Esta restriccin (a diferencia de "primary key" y "unique") no crea ndice automaticamente. La cantidad y tipo de datos de los campos especificados luego de "foreign key" DEBEN coincidir con la cantidad y tipo de datos de los campos de la clusula "references". Esta restriccin se puede definir dentro de la misma tabla (lo veremos ms adelante) o entre distintas tablas. Una tabla puede tener varias restricciones "foreign key". No se puede eliminar una tabla referenciada en una restriccin "foreign key", aparece un mensaje de error. Una restriccion "foreign key" no puede modificarse, debe eliminarse y volverse a crear. Para ver informacin acerca de esta restriccin podemos ejecutar el procedimiento almacenado "sp_helpconstraint" junto al nombre de la tabla. Nos muestra el tipo, nombre, la opcin para eliminaciones y actualizaciones, el estado (temas que veremos ms adelante), el nombre del campo y la tabla y campo que referencia. Tambin informa si la tabla es referenciada por una clave fornea.

77 - Restricciones foreign key en la misma tablaLa restriccin "foreign key", que define una referencia a un campo con una restriccin "primary key" o "unique" se puede definir entre distintas tablas (como hemos aprendido) o dentro de la misma tabla. Veamos un ejemplo en el cual definimos esta restriccin dentro de la misma tabla. Una mutual almacena los datos de sus afiliados en una tabla llamada "afiliados". Algunos afiliados inscriben a sus familiares. La tabla contiene un campo que hace referencia al afiliado que lo incorpor a la mutual, del cual dependen.

La estructura de la tabla es la siguiente: create table afiliados( numero int identity not null, documento char(8) not null, nombre varchar(30), afiliadotitular int, primary key (documento), unique (numero) ); En caso que un afiliado no haya sido incorporado a la mutual por otro afiliado, el campo "afiliadotitular" almacenar "null". Establecemos una restriccin "foreign key" para asegurarnos que el nmero de afiliado que se ingrese en el campo "afiliadotitular" exista en la tabla "afiliados": alter table afiliados add constraint FK_afiliados_afiliadotitular foreign key (afiliadotitular) references afiliados (numero); La sintaxis es la misma, excepto que la tabla se autoreferencia. Luego de aplicar esta restriccin, cada vez que se ingrese un valor en el campo "afiliadotitular", SQL Server controlar que dicho nmero exista en la tabla, si no existe, mostrar un mensaje de error. Si intentamos eliminar un afiliado que es titular de otros afiliados, no se podr hacer, a menos que se haya especificado la accin en cascada (prximo tema).

78 - Restricciones foreign key (acciones)Continuamos con la restriccin "foreign key". Si intentamos eliminar un registro de la tabla referenciada por una restriccin "foreign key" cuyo valor de clave primaria existe referenciada en la tabla que tiene dicha restriccin, la accin no se