Você está na página 1de 280

Transact-SQL User's Guide (Spanish)

Prefacio Chapter 1: Introduccin Chapter 2: Consultas: seleccin de datos de una tabla Chapter 3: Cmo resumir, agrupar y ordenar resultados de consultas Chapter 4: Combinaciones: recuperacin de datos de varias tablas Chapter 5: Subconsultas: uso de consultas dentro de otras consultas Chapter 6: Uso y creacin de tipos de datos Chapter 7: Creacin de bases de datos y tablas Chapter 8: Adicin, modificacin y eliminacin de datos Chapter 9: Vistas: limitacin del acceso a datos Chapter 10: Uso de funciones incorporadas en consultas Chapter 11: Creacin de ndices en tablas Chapter 12: Definicin de valores predeterminados y reglas para datos Chapter 13: Uso de lotes y lenguaje de control de flujo Chapter 14: Uso de procedimientos almacenados Chapter 15: Disparadores: imposicin de la integridad de referencia Chapter 16: Cursores: acceso a los datos fila por fila Chapter 17: Transacciones: mantenimiento de la consistencia y recuperacin de datos Glosario Prefacio Este manual, la Gua del Usuario de Transact-SQL , trata sobre Transact-SQL(R), una versin mejorada del lenguaje de bases de datos relacionales SQL. La Gua del Usuario de Transact-SQL est pensada para los principiantes y aquellos usuarios que ya tienen experiencia con otras implementaciones de SQL. A quin va dirigido Los usuarios de los sistemas de administracin de bases de datos de SQL Server(TM) de Sybase que no estn familiarizados con SQL pueden considerar esta gua como un libro de texto y comenzar por el principio. Los usuarios que carecen de experiencia con SQL deben concentrarse en la primera parte de este manual. En la segunda parte se describen temas que son ms avanzados que los incluidos en la primera. Para los lectores que ya conocen otras versiones de SQL, este manual resulta til como mtodo de revisin y como gua a las mejoras de Transact-SQL. Los expertos en SQL deben estudiar las funciones y caractersticas que Transact-SQL ha aadido a SQL estndar, sobre todo el material sobre procedimientos almacenados. Utilizacin del manual Este manual es una gua completa a Transact-SQL que contiene un captulo introductorio con una descripcin general de SQL y varios captulos divididos en dos partes principales: Conceptos bsicos y Temas avanzados. El Captulo 1, "Introduccin", trata las convenciones para nombres utilizadas por SQL y las mejoras (tambin conocidas como extensiones) aadidas por Transact-SQL. Tambin incluye una explicacin sobre cmo empezar a usar Transact-SQL con la utilidad isql . Todos los usuarios deberan leer este captulo, ya que constituye una iniciacin al resto de los captulos. "Parte 1: Conceptos bsicos" incluye los captulos 2 a 9. Estos captulos constituyen una introduccin a la funcionalidad bsica de SQL. Los usuarios nuevos de SQL deben familiarizarse con los conceptos descritos en estos captulos antes de pasar a la segunda parte. Los usuarios que ya tienen experiencia con SQL posiblemente quieran hojear los captulos para aprender sobre las diversas extensiones Transact-SQL que presentan y, al mismo tiempo, repasar el material. "Parte 2: Temas avanzados" incluye los captulos 10 a 17. En estos captulos se describe Transact-SQL en mayor detalle, as como las mayora de sus extensiones. Esta parte la deberan estudiar los usuarios familiarizados con SQL, pero no con TransactSQL. Los ejemplos de esta gua, de los cuales hay muchos, estn basados en la base de datos de muestra p ubs2 . Para aprovechar al mximo la informacin de la Gua del Usuario de Tr ansact-SQL , los usuarios nuevos deben trabajar con los ejemplos paso a paso. Dirjase a su administrador del sistema para solicitar una copia limpia de p ubs2 . Si desea obtener una descripcin completa de la base de datos pubs2 , consulte el Suplemento de Referencia de SQL Server . Puede utilizar Transact-SQL con el programa autnomo isql de SQL Server. i sql es un programa de utilidad que se ejecuta directamente desde el sistema operativo.
Page 1 of 280

Documentos relacionados La documentacin del sistema de administracin de bases de datos relacionales de SQL Server est diseada para satisfacer la necesidad de simplicidad del usuario sin experiencia y, al mismo tiempo, el deseo de comodidad y amplitud de informacin del usuario con experiencia. La gua del usuario y los manuales de referencia abarcan las distintas necesidades de los usuarios finales, desarrolladores de aplicaciones, programadores y administradores de base de datos. Otros manuales que pueden resultar de utilidad son:

Novedades de SQL Server de Sybase, Versin 11.0 , que describe las caractersticas nuevas introducidas en la versin
11.0.

Gua de Administracin del Sistema SQL Server , que proporciona informacin pormenorizada sobre la administracin

de servidores y bases de datos. En este manual se incluyen instrucciones y pautas para administrar recursos fsicos y bases de datos del sistema y del usuario, as como para especificar parmetros de conversin de caracteres, de idiomas internacionales y de criterios de ordenacin. Manual de Referencia de SQL Server , que contiene informacin detallada sobre los comandos y procedimientos del sistema explicados en este manual. Suplemento de Referencia de SQL Server , que proporciona una lista de palabras reservadas de Transact-SQL, definiciones de tablas del sistema, una descripcin de la base de datos de muestra p ubs2 , una lista de mensajes de error de SQL Server y otros datos de referencia comunes a todos los manuales. Gua de Mejora de Rendimiento y Afinacin de SQL Server , que proporciona informacin detallada sobre cmo afinar SQL Server y las consultas para obtener el mximo rendimiento. Manual de programas de utilidad de SQL Server, que incluye informacin sobre los programas de utilidad de Sybase, como i sql y b cp , que se ejecutan desde el sistema operativo.

Gua del Usuario de las Caractersticas de Seguridad de SQL Server , que est dirigida al usuario general y donde se explica cmo utilizar las caractersticas de seguridad de SQL Server. Gua de Administracin de Seguridad de SQL Server , que est dirigida a los administradores del sistema responsables
de mantener la seguridad del entorno operativo de SQL Server. En el manual se explica cmo utilizar las caractersticas de seguridad de SQL Server para controlar el acceso de usuarios a los datos. La gua de instalacin y configuracin de SQL Server, donde se describen los procedimientos de instalacin de SQL Server y se documentan las tareas de administracin especficas del sistema operativo. Master Index for SQL Server Publications, donde se combinan los ndices del Manual de Referencia de SQL Server , la Gua del Usuario de Tr ansact-SQL , la Gua de Administracin del Sistema y la Gua de Mejora de Rendimiento y Afinacin . Utilice dicho ndice para localizar diversos temas en distintos contextos a lo largo de toda la documentacin.

Convenciones utilizadas en este manual Formato de las instrucciones SQL SQL es un lenguaje de forma libre: no hay reglas acerca del nmero de palabras que pueden ponerse en una lnea, o acerca de dnde debe dividirse una lnea. Sin embargo, a efectos de legibilidad, todos los ejemplos e instrucciones de sintaxis de este manual se han de formatear, de modo que cada clusula de una instruccin comience en una nueva lnea. Las clusulas que tienen ms de una parte se extienden a lneas adicionales, que aparecen con sangra. Convenciones de sintaxis SQL Las convenciones de las instrucciones de sintaxis de este manual son las siguientes: Tabla 1: Convenciones de las instrucciones de sintaxis Clave Definicin Los nombres de comando, de opcin de comando, de utilidad, de indicador de utilidad y otras palabras clave se coman do o imprimen en C ourier negrita en las instrucciones de sintaxis, y en Helvetica negrita en el texto de los comand o prrafos.

variable
{} [] ()

Las variables o las palabras que representan valores que debe introducir el usuario se muestran en cursiva. Las llaves indican que el usuario debe elegir al menos una de las opciones contenidas en ellas. No incluya las llaves en la opcin. Los corchetes significan que es opcional elegir una o ms de las opciones contenidas entre ellos. No incluya los corchetes en la opcin. Los parntesis deben utilizarse como parte del comando.
Page 2 of 280

| ,

La barra vertical significa que puede seleccionar slo una de las opciones mostradas. La coma significa que puede elegir tantas de las opciones mostradas como desee, separando las elegidas con comas, que se deben introducir como parte del comando.

Las instrucciones de sintaxis (que muestran la sintaxis y todas las opciones de un comando) se imprimen de la siguiente manera: sp_dropdevice [ device_name ]

o, en el caso de un comando con ms opciones: select column_name from table_name where search_conditions En las instrucciones de sintaxis, las palabras clave (comandos) aparecen en una fuente normal y los identificadores en minsculas: fuente normal para las palabras clave y cursiva para las palabras suministradas por el usuario.

Los ejemplos que muestran el uso de comandos Transact-SQL se imprimen de la siguiente forma: select * from publishers

Los ejemplos de salida de la computadora se imprimen de la siguiente manera: pub_id ------0736 0877 1389 pub_name ------------------New Age Books Binnet & Hardley Algodata Infosystems city ----------Boston Washington Berkeley state ----MA DC CA

(3 rows affected) Uso de maysculas o minsculas Las palabras clave pueden escribirse indistintamente en maysculas o minsculas: SELECT es lo mismo que Select y que select . Opciones obligatorias {debe elegir al menos una}

Llaves y barras verticales: elija una y slo una opcin. {die_on_your_feet | live_on_your_knees | live_on_your_feet}

Llaves y com a : elija una o ms opciones. Si elige ms de una, seprelas con comas. {cash, check, credit}

Opciones optativas [no tiene que elegir ninguna]

Un elemento entre corchetes: no tiene obligacin de elegirlo. [anchovies]

Corchetes y barras verticales: elija una sola o ninguna . [beans | rice | sweet_potatoes]
Page 3 of 280

Corchetes y comas: elija ninguna, una o ms de una opcin. Si elige ms de una, seprelas con comas. [extra_cheese, avocados, sour_cream]

Puntos suspensivos: reptalo una vez (y otra)... Los puntos suspensivos (...) significan que es posible repetir la ltima unidad tantas veces como se desee. En esta instruccin de sintaxis, buy es una palabra clave necesaria: buy thing = [, thing price [cash | check | credit] = price [cash | check | credit] ]...

Debe comprar al menos una cosa y dar su precio. Puede elegir una forma de pago: una de las opciones que aparecen entre corchetes. Tambin puede elegir comprar cosas adicionales: tantas como quiera. Por cada cosa que compre, d su nombre y precio, y (de forma opcional) su forma de pago. Expresiones En las instrucciones de sintaxis de SQL Server, se usan distintos tipos de expresiones. Tabla 2: Tipos de expresiones utilizadas en instrucciones de sintaxis Uso Definicin Puede incluir constantes, literales, funciones, identificadores de columnas, variables o parmetros Expresin que devuelve TRUE, FALSE o UNKNOWN Expresin que siempre devuelve el mismo valor, como "5+3" o "ABCDE" Cualquier expresin de coma flotante o expresin que se convierte de forma implcita en un valor de coma flotante Cualquier expresin de nmero entero o expresin que se convierte de forma implcita en un valor de nmero entero Cualquier expresin numrica que devuelve un solo valor Cualquier expresin que devuelve un solo valor de tipo de caracteres Expresin que devuelve un solo valor b inary o varbinary

expression logical expression constant expression float_expr integer_expr numeric_expr char_expr binary_expression
Si necesita ayuda

Existe a su disposicin ayuda sobre el software de Sybase en la forma de documentacin y Servicio de Asistencia Tcnica de Sybase. Cada instalacin de Sybase tiene una persona designada que puede ponerse en contacto con el Servicio de Asistencia Tcnica. Si no puede resolver un problema usando los manuales, deber pedir a la persona designada que se ponga en contacto con el Servicio de Asistencia Tcnica de Sybase. Chapter 1

Introduccin
Este captulo trata lo siguiente:

Introduccin general a SQL y sus componentes Convenciones para nombres usadas para las diferentes partes de SQL Mejoras de Transact-SQL (tambin conocidas como extensiones) aadidas a SQL Compatibilidad ANSI Uso de Transact-SQL con la utilidad isql Introduccin general Convenciones para nombres
Page 4 of 280

Extensiones Transact-SQL Cumplimiento de normas Uso de Transact-SQL con la utilidad isql

Introduccin general SQL (Structured Query Language - Lenguaje estructurado de consultas) es un lenguaje de alto nivel para sistemas de bases de datos relacionales. Desarrollado originalmente por el Laboratorio de Investigacin de IBM en San Jos a finales de los aos 70, SQL ha sido adoptado y adaptado en muchos sistemas de administracin de bases de datos relacionales. Ha sido aprobado como norma oficial para lenguajes de consultas relacionales por parte del American National Standards Institute (ANSI) y la International Organizacion for Standardization (ISO). Transact-SQL es compatible con IBM SQL y con la mayora de las dems implementaciones comerciales de SQL, y tambin proporciona importantes capacidades y funciones adicionales. Aunque la "Q" de SQL significa "Query" (consulta), SQL incluye comandos no slo para la consulta (recuperacin de datos) de una base de datos, sino tambin para la creacin de bases de datos y objetos de base de datos , adicin de datos nuevos, modificacin de datos existentes y otras funciones. Consultas, modificacin de datos y comandos En este manual, consulta se refiere a una solicitud de recuperacin de datos, llevada a cabo con el comando select . Por ejemplo: select au_lname, city, state from authors where state = 'NY' Modificacin de datos se refiere a la adicin, eliminacin o edicin de datos, realizadas mediante el comando insert, delete o update, respectivamente. Por ejemplo: insert into authors (au_lname, au_fname, au_id) values ("Smith", "Gabriella", "999-03-2346") Otros comandos SQL son instrucciones para realizar operaciones administrativas. Por ejemplo: drop table authors Cada comando o instruccin SQL comienza con una palabra clave , como insert , que da nombre a la operacin bsica realizada. Muchos comandos SQL tienen una o ms frases de palabras clave , o clusulas , que adaptan el comando para que satisfaga una necesidad en particular. Cuando se ejecuta una consulta, Transact-SQL muestra el resultado al usuario. Si ninguno de los datos cumplen los criterios especificados en la consulta, el usuario obtiene un mensaje al efecto. Las instrucciones de modificacin de datos y administrativas no muestran resultados, ya que no recuperan datos. Transact-SQL proporciona un mensaje que permite saber al usuario si la modificacin de datos u otro comando se ha llevado a cabo. Tablas, columnas y filas SQL es un lenguaje de bases de datos especficamente diseado para el modelo relacional de administracin de bases de datos. En un sistema de administracin de bases de datos relacionales, los usuarios ven los datos como tablas, que tambin se conocen como relaciones. Cada fila (o registro) de una tabla describe una aparicin de una entidad: una persona, empresa, venta o alguna otra cosa. Cada columna, o campo, describe una caracterstica de la entidad: un nombre de persona o direccin, un nombre de empresa o su presidente, artculos vendidos, o una cantidad o fecha. Una base de datos consta de un conjunto de tablas relacionadas. Figure 1-1: Una tabla de una base de datos relacional Las operaciones relacionales Las operaciones bsicas de consulta en un sistema relacional son la seleccin (tambin llamada restriccin), proyeccin y combinacin. Todas ellas pueden combinarse en el comando select de SQL.

Page 5 of 280

Una seleccin es un subconjunto de las filas de una tabla, basada en ciertas condiciones especificadas por el usuario. Por ejemplo, podra consultar las filas de todos los autores que viven en California. Una proyeccin es un subconjunto de las columnas de una tabla. Por ejemplo, una consulta puede mostrar slo el nombre y la ciudad de todos los autores, omitiendo la calle, el nmero de telfono y el resto de la informacin. Una combinacin enlaza las filas de dos o ms tablas comparando los valores de campos especificados. Por ejemplo, supongamos que hay una tabla con informacin sobre autores que incluye las columnas au_id (nmero de ID del autor) y au_lname (apellido del autor), y otra tabla con informacin sobre ttulos de libros que incluye una columna au_id (nmero de ID del autor del libro). Las tablas authors y titles podran combinarse, verificando la igualdad de los valores de las columnas au_id de cada tabla. Siempre que exista una coincidencia, se crear una fila nueva, con columnas de ambas tablas, que aparecer como parte del resultado de la combinacin. Las combinaciones a menudo se mezclan con proyecciones y selecciones para que slo aparezcan las columnas elegidas de las filas seleccionadas coincidentes. Convenciones para nombres Una instruccin SQL debe seguir reglas sintcticas y estructurales precisas, y puede incluir slo palabras clave SQL, identificadores (nombres de bases de datos, tablas u otros objetos de base de datos), operadores y constantes. Los caracteres que pueden utilizarse para cada parte de una instruccin SQL varan de una instalacin a otra y se determinan en parte mediante definiciones del juego de caracteres predeterminado usado por SQL Server. Por ejemplo, los caracteres permitidos para el lenguaje SQL, como las palabras clave SQL, caracteres especiales y extensiones Transact-SQL, estn ms limitados que los permitidos para los identificadores. El juego de caracteres que puede utilizarse para los datos es mucho mayor e incluye todos los caracteres que pueden usarse para el lenguaje SQL o los identificadores. La Figura 1-2 muestra la relacin entre los juegos de caracteres permitidos para las palabras clave SQL, identificadores y datos. Figure 1-2: Caracteres usados para distintas partes de las instrucciones SQL En las secciones siguientes se describen los juegos de caracteres que pueden utilizarse para cada parte de una instruccin. La seccin sobre identificadores tambin describe las convenciones para nombres de los objetos de base de datos. Caracteres de datos SQL El juego de caracteres de datos SQL es el mayor juego de donde se toman los caracteres del lenguaje SQL y de los identificadores. Cualquier carcter del juego de caracteres de SQL Server, incluidos los caracteres de un solo byte o de mltiples bytes, puede utilizarse para valores de datos. Caracteres del lenguaje SQL Las palabras clave SQL, extensiones Transact-SQL y caracteres especiales, como los operadores de comparacin ">" y "<", pueden representarse slo mediante valores ASCII de 7 bits que cubran el rango A - Z, a - z, 0 - 9, y los siguientes caracteres ASCII. Tabla 1-1: Caracteres ASCII usados en SQL ; , " (punto y coma) (coma) (signo menos) (comilla doble) ( (parntesis inicial) : (dos puntos) ? (interrogacin final) + (signo ms) / (barra inclinada) | (barra vertical) ] (corchete final) ~ (tilde) # (smbolo de nmero) ) ' (parntesis final) (comilla simple) (espacio) ^ (acento circunflejo) \ ! . (barra invertida) (exclamacin final) (punto) % (signo de porcentaje) _ (subrayado)

* (asterisco) & (smbolo de "y") [ (corchete inicial) @ (smbolo de "en") $ (smbolo de dlar) Identificadores

< (operador menor que) > (operador mayor que) = (operador de igualdad)

Page 6 of 280

Las convenciones para los nombres de objetos de base de datos se aplican a todo el software y la documentacin de SQL Server. Los identificadores pueden tener una longitud de hasta 30 bytes, se utilicen o no caracteres multibyte. El primer carcter de un identificador debe declararse como carcter alfabtico en la definicin del juego de caracteres usado en SQL Server. Note: Los juegos de caracteres multibyte disponen de un margen ms amplio de caracteres para su uso con los identificadores. Por ejemplo, en un servidor que tiene instalado el idioma japons, es posible utilizar los siguientes tipos de caracteres como primer carcter de un identificador: Zenkaku o Hankaku Katakana, Hiragana, Kanji, Romaji, cirlico, griego o ASCII. Los smbolos @ o _ (carcter de subrayado) tambin pueden utilizarse. El smbolo @ como primer carcter de un identificador indica una variable local. Los nombres de tablas temporales deben empezar por # (smbolo de nmero) si se crean fuera de tempdb , o ir precedidos de " tempdb ..". Los nombres de las tablas temporales que existen fuera de tempdb no deben superar los 13 bytes de longitud, incluido el smbolo de nmero, ya que SQL Server les otorga un sufijo numrico interno. Despus del primer carcter, los identificadores pueden incluir caracteres declarados como alfabticos, numricos o los smbolos $, #, @, _, (yen) o (libra esterlina). La distincin entre maysculas y minsculas de SQL Server se establece al instalar el servidor y puede cambiarla el administrador del sistema. Para ver el parmetro del servidor, ejecute este comando: sp_helpsort En un servidor que no distinga entre maysculas y minsculas, los identificadores MIOBJETO , miobjeto y MiObjeto (y todas las combinaciones posibles de caracteres en maysculas y minsculas) se consideran idnticos. Slo se puede crear uno de estos objetos, y el uso de esas combinaciones de maysculas y minsculas referenciar a ese objeto. No se permiten espacios incrustados en los identificadores, y no puede utilizarse ninguna palabra clave SQL reservada. Las palabras reservadas se enumeran en el Suplemento de Referencia de SQL Server . Puede utilizar la funcin valid_name a fin de determinar si el identificador que ha creado es aceptable para SQL Server. A continuacin se muestra la sintaxis: select valid_name ( "string ")

donde string es el identificador que va a verificarse. Si string no es vlido como identificador, SQL Server devuelve un 0 (cero). Si string es un identificador vlido, SQL Server devuelve un nmero distinto de cero. SQL Server devuelve un 0 si los caracteres utilizados son ilegales o si string tiene ms de 30 bytes de longitud. Identificadores delimitados Los identificadores delimitados son nombres de objetos incluidos entre comillas dobles. El uso de identificadores delimitados permite evitar ciertas restricciones sobre los nombres de objeto. Se pueden utilizar las comillas dobles para delimitar los nombres de tablas, vistas y columnas; no se pueden usar para otros objetos de base de datos. Los identificadores delimitados pueden ser palabras reservadas, empezar con caracteres no alfabticos e incluir caracteres que, de otro modo, no estaran permitidos. No pueden superar los 28 bytes. Antes de crear o hacer referencia a un identificador delimitado, ejecute: set quoted_identifier on Esta opcin permite que SQL Server reconozca los identificadores delimitados. Cada vez que utilice el identificador entre comillas dentro de una instruccin, debe incluirlo entre comillas dobles. Por ejemplo: create table "1one"(col1 char(3)) select * from "1one" create table "include spaces" (col1 int) Note: Los identificadores delimitados no pueden usarse como parmetros de los procedimientos del sistema ni con bcp , y pueden no ser compatibles con todos los productos frontales.

Page 7 of 280

Convenciones para nombres Los nombres de objetos de base de datos no necesitan ser nicos en una base de datos. Sin embargo, los nombres de columnas y de ndices deben ser nicos dentro de una tabla, y otros nombres de objetos deben ser nicos para cada propietario dentro de una base de datos. Los nombres de bases de datos deben ser nicos en SQL Server. Si intenta crear una columna utilizando un nombre que no es nico en la tabla o crear otro objeto de base de datos , como una tabla, una vista o un procedimiento almacenado, con un nombre ya usado en la misma base de datos, SQL Server responde con un mensaje de error. Una tabla o columna pueden identificarse de forma nica aadiendo otros nombres que las califiquen, es decir, el nombre de la base de datos, el nombre del propietario y, para una columna, el nombre de la tabla o de la vista. Cada uno de estos calificadores se separa del siguiente mediante un punto: database.owner.table_name.column_name database.owner.view_name.column_name Por ejemplo, si el usuario "sharon" posee la tabla authors de la base de datos pubs2 , el identificador nico de la columna city en dicha tabla es: pubs2.sharon.authors.city La misma sintaxis de asignacin de nombres se aplica a otros objetos de base de datos. De igual modo, puede hacerse referencia a cualquier objeto: pubs2.dbo.titleview dbo.postalcoderule Si la opcin quoted_identifier est definida como on (activada), puede utilizar comillas dobles con partes concretas de un nombre de objeto calificado. Use un par distinto de comillas para cada calificador que precise comillas. Por ejemplo, utilice: database en lugar de: database . owner ." table_name . column_name " . owner ." table_name "." column_name "

No siempre se permite la sintaxis de asignacin de nombres completa en instrucciones create porque no se puede crear una vista, procedimiento, regla, valor predeterminado o disparador en una base de datos diferente de la actual. Las convenciones para nombres se sealan en la sintaxis como: [[ database .] owner .] object_name

o bien: [ owner .] object_name

El valor predeterminado de owner es el usuario actual y el de database es la base de datos actual. Cuando se hace referencia a un objeto en instrucciones SQL distintas de las instrucciones create , sin calificarlo con el nombre de la base de datos ni el nombre del propietario, SQL Server primero busca todos los objetos de propiedad del usuario y despus todos los objetos pertenecientes al propietario de la base de datos , cuyo nombre en la base de datos es "dbo". Siempre que se proporcione suficiente informacin a SQL Server para identificar un objeto, no es necesario teclear cada elemento de su nombre. Los elementos intermedios pueden omitirse y sus posiciones pueden indicarse con puntos: database..table_name Al calificar un nombre de columna y un nombre de tabla en la misma instruccin, hay que asegurarse de utilizar las mismas abreviaturas de nombre para cada uno; tales abreviaturas se evalan como cadenas de caracteres y deben coincidir, o se devolver un error. Aqu se muestran dos ejemplos con entradas diferentes para el nombre de columna. El segundo ejemplo no se ejecuta porque la sintaxis del nombre de la columna no coincide con la del nombre de la tabla.

Page 8 of 280

select pubs2.dbo.publishers.city from pubs2.dbo.publishers city ----------------------Boston Washington Berkeley select pubs2.dbo.publishers.city from pubs2..publishers El prefijo de columna "pubs2.dbo.publishers" no coincide con ningn nombre de tabla o nombre de alias utilizado en la consulta. Identificacin de servidores remotos Los procedimientos almacenados pueden ejecutarse en un SQL Server remoto, y los resultados del procedimiento almacenado aparecen impresos en el terminal que llam al procedimiento. La sintaxis para la identificacin de un servidor remoto y el procedimiento almacenado es: [execute] server .[ database ].[ owner ]. procedure_name

La palabra clave execute puede omitirse cuando la llamada de procedimientos remotos es la primera instruccin de un lote. Si otras instrucciones SQL preceden a la llamada de procedimientos remotos, debe utilizarse execute o exec . Es necesario proporcionar el nombre del servidor y el del procedimiento almacenado. Si se omite el nombre de la base de datos, SQL Server buscar procedure_name en la base de datos predeterminada. Si se facilita el nombre de la base de datos, tambin deber facilitarse el nombre del propietario del procedimiento, a menos que el usuario posea el procedimiento, o que el procedimiento pertenezca al propietario de la base de datos. Todas las instrucciones siguientes ejecutan el procedimiento almacenado byroyalty de la base de datos pubs2 ubicada en el servidor GATEWAY: Instruccin Notas

GATEWAY.pubs2.dbo.byroyalty byroyalty pertenece al propietario de la base de datos. GATEWAY.pubs2..byroyalty GATEWAY...byroyalty declare @var int exec GATEWAY...byroyalty Debe usarse si pubs2 es la base de datos predeterminada. Debe usarse cuando la instruccin no es la primera instruccin de un lote.

Consulte la Gua de Administracin del Sistema SQL Server para obtener informacin sobre la configuracin de SQL Server para acceso remoto. Un nombre de servidor remoto (GATEWAY en el ejemplo anterior) debe coincidir con un nombre de servidor del archivo interfaces de SQL Server. Si el nombre de servidor de interfaces aparece todo en maysculas, tambin debe usarse en maysculas en la llamada de procedimientos remotos. Extensiones Transact-SQL Transact-SQL fue diseado para aumentar la potencia de SQL y para minimizar, si no eliminar, las ocasiones en las que los usuarios deben recurrir a un lenguaje de programacin para llevar a cabo las tareas deseadas. Transact-SQL va ms all de las normas ISO y de las diversas versiones comerciales de SQL. La mayora de las mejoras de Transact-SQL (conocidas como extensiones) se resumen aqu. Otras extensiones, como las herramientas de administracin de Transact-SQL, se describen en sus respectivos manuales. La clusula compute La clusula compute es una extensin Transact-SQL importante que se utiliza con funciones agregadas de fila, sum , max , min, avg y count , para calcular valores totales. Los resultados de una consulta que incluye una clusula compute , se muestran con filas detalladas y resumidas, y tienen el aspecto de un informe que la mayora de los DBMS slo pueden producir con un generador de informes. compute muestra valores totales como filas adicionales en los resultados, en lugar de columnas nuevas. La clusula compute se explica en el Captulo 3, "Cmo resumir, agrupar y ordenar resultados de consultas". Lenguaje de control de flujo
Page 9 of 280

Transact-SQL proporciona un lenguaje de control de flujo que puede utilizarse como parte de cualquier instruccin SQL o lote. Estas estructuras estn disponibles: begin ... end , break , continue , declare , goto label , if ... else , print , raiserror , return , waitfor y while . Las variables locales pueden definirse con declare y valores asignados. El sistema ofrece varias variables globales predefinidas. Procedimientos almacenados Una de las extensiones Transact-SQL ms importantes es la capacidad de crear procedimientos almacenados. Los procedimientos almacenados pueden combinar casi cualquier instruccin SQL con el lenguaje de control de flujo. El creador de un procedimiento almacenado tambin puede definir parmetros que se faciliten cuando se ejecute el procedimiento almacenado. La capacidad de escribir procedimientos almacenados propios aumenta en gran medida la potencia, eficacia y flexibilidad del lenguaje de base de datos SQL. Puesto que el plan de ejecucin se guarda despus de ejecutar los procedimientos almacenados, stos pueden ejecutarse posteriormente mucho ms deprisa que las instrucciones autnomas. Los procedimientos almacenados suministrados por SQL Server, llamados procedimientos del sistema , se proporcionan para su uso en la administracin del sistema de SQL Server. En el Captulo 14, "Uso de procedimientos almacenados", se explican los procedimientos del sistema y el modo de crear procedimientos almacenados. Los procedimientos del sistema se describen de forma detallada en el Manual de Referencia de SQL Server . Los usuarios pueden ejecutar procedimientos almacenados en servidores remotos. Otras extensiones Transact-SQL soportan valores de retorno de procedimientos almacenados, estado de retorno definido por el usuario de procedimientos almacenados y la capacidad de pasar parmetros desde un procedimiento a su solicitante. Disparadores Un disparador es un tipo especial de procedimiento almacenado que se utiliza para proteger la integridad de referencia: para imponer reglas sobre las relaciones entre datos de tablas diferentes. Los disparadores se activan cuando un usuario intenta modificar datos con un comando insert , delete o update . Un disparador puede indicar al sistema que realice un nmero cualquiera de acciones cuando se intenta efectuar un cambio especfico. Al evitar los cambios incorrectos, no autorizados o incoherentes, los disparadores ayudan a mantener la integridad de una base de datos. Los disparadores pueden llamar a procedimientos almacenados locales o remotos, as como a otros disparadores. Los disparadores se pueden anidar a una profundidad de 16 niveles. Reglas y valores predeterminados Transact-SQL proporciona palabras clave para ayudar a mantener la integridad de la entidad (para garantizar que se facilite un valor para cada columna que requiera uno) e integridad de dominio (para garantizar que cada valor de una columna pertenezca al conjunto de valores legales de dicha columna). Los disparadores, descritos anteriormente, ayudan a mantener la integridad de referencia. Los valores predeterminados y las reglas definen las restricciones de integridad que entran en juego durante la introduccin y modificacin de datos. Un valor predeterminado es un valor vinculado a una columna o tipo de datos concreto e insertado por el sistema si no se facilita ningn valor durante la introduccin de datos. Las reglas son restricciones de integridad definidas por el usuario vinculadas a una columna o tipo de datos concreto e impuestas en el momento de la introduccin de datos. Las reglas y valores predeterminados se explican en el Captulo 12, "Definicin de valores predeterminados y reglas para datos". Manipulacin de errores y opciones de set Hay un gran nmero de tcnicas de manipulacin de errores a disposicin del programador de Transact-SQL, incluida la capacidad de capturar el estado de retorno a partir de procedimientos almacenados, definir valores de retorno personalizados a partir de procedimientos almacenados, pasar parmetros desde un procedimiento a su solicitante y obtener informes a partir de variables globales como @@error . Las instrucciones raiserror y print , en combinacin con el lenguaje de control de flujo, pueden dirigir mensajes de error al usuario de una aplicacin Transact-SQL. Los desarrolladores pueden localizar print y raiserror para utilizar diferentes lenguajes. Las opciones de set pueden personalizar la visualizacin de resultados, mostrar estadsticas de procesamiento y proporcionar otras ayudas de diagnstico para depurar los programas Transact-SQL.
Page 10 of 280

Extensiones SQL Server adicionales de SQL Entre otras funciones nicas o poco usuales de Transact-SQL se incluyen:

Menos restricciones para las clusulas group by y order by . Consulte el Captulo 3, "Cmo resumir, agrupar y ordenar resultados de consultas". Subconsultas, que pueden utilizarse casi en cualquier lugar donde se permita una expresin. Consulte el Captulo 5, "Subconsultas: uso de consultas dentro de otras consultas". Tablas temporales y otros objetos de base de datos temporales, que slo existen mientras dura la sesin de trabajo actual y despus desaparecen. Consulte el Captulo 7, "Creacin de bases de datos y tablas". Tipos de datos definidos por el usuario generados a partir de los tipos de datos suministrados por SQL Server. Consulte el Captulo 7 y el Captulo 12, "Definicin de valores predeterminados y reglas para datos". La capacidad de insertar (con insert ) datos de una tabla en la misma tabla. Consulte el Captulo 8, "Adicin, modificacin y eliminacin de datos". La capacidad de extraer datos de una tabla y ponerlos en otra mediante el comando update . Consulte el Captulo 8. La capacidad de quitar datos basados en datos de otras tablas utilizando la combinacin en una instruccin delete . Consulte el Captulo 8. Una forma rpida de eliminar todas las filas de una tabla especificada y recuperar el espacio que ocupaban con el comando truncate table . Consulte el Captulo 8. Actualizaciones y selecciones mediante vistas. A diferencia de la mayora de las dems versiones de SQL, TransactSQL no pone ninguna restriccin en la recuperacin de datos mediante vistas, y relativamente pocas en la actualizacin de datos mediante vistas. Consulte el Captulo 9, "Vistas: limitacin del acceso a datos". Gran nmero de funciones incorporadas. Consulte el Captulo 10, "Uso de funciones incorporadas en consultas". Opciones del comando create index para afinar aspectos de rendimiento determinados por los ndices y controlar el tratamiento de claves y filas duplicadas. Consulte el Captulo 11, "Creacin de ndices en tablas". Control del usuario sobre lo que ocurre cuando se intentan introducir claves duplicadas en un ndice nico o filas duplicadas en una tabla. Consulte el Captulo 11. Operadores basados en bits para su uso con columnas de tipo integer y bit . Consulte el Manual de Referencia de SQL Server . Soporte para los tipos de datos text e image . Consulte el Manual de Referencia de SQL Server .

Cumplimiento de normas La progresin de las normas para los sistemas de administracin de bases de datos relacionales est en curso. Estas normas las ha adoptado, y sigue adoptando, ISO y varios organismos de normalizacin. SQL86 fue la primera de estas normas y se sustituy por SQL89. Esta, a su vez, fue sustituida por SQL92, que es la norma actual. SQL92 define tres niveles de cumplimiento: entrada, intermedio y completo. En EE.UU., el National Institute for Standards and Technology (NIST) ha establecido el nivel transicional, que est entre el de entrada y el intermedio. Algunos comportamientos definidos por las normas no son compatibles con las aplicaciones SQL Server existentes. TransactSQL dispone de opciones de set que permiten conmutar estos comportamientos. El comportamiento compatible est activado de forma predeterminada para todas las aplicaciones de precompilador de Embedded SQL(TM). Otras aplicaciones que precisen satisfacer el comportamiento estndar SQL pueden utilizar los valores de opcin de la Tabla 1-2 para el cumplimiento de SQL92 a nivel de entrada. Para obtener ms informacin sobre la definicin de estas opciones, consulte set en el Manual de Referencia de SQL Server . Tabla 1-2: Opciones de set para el cumplimiento SQL Opcin ansi_permissions ansinull arithabort arithabort numeric_truncation arithignore chained close on endtran fipsflagger quoted_identifier string_rtruncation Parmetro on on off on off on on on on on
Page 11 of 280

transaction isolation level

En las siguientes secciones se describen las diferencias entre el comportamiento estndar y el comportamiento predeterminado de Transact-SQL. Creador de indicadores FIPS Para clientes que escriben aplicaciones que deben cumplir con la norma, SQL Server proporciona una opcin set fipsflagger . Cuando esta opcin est activada, todos los comandos que contienen extensiones Transact-SQL que no se permiten a nivel de entrada SQL92 generan un mensaje informativo. Transacciones encadenadas y niveles de aislamiento Ahora SQL Server proporciona el comportamiento de transacciones "encadenadas" compatible con la norma SQL como una opcin. En el modo encadenado, todos los comandos de recuperacin y modificacin de datos ( delete , insert , open , fetch , select y update ) inician de forma implcita una transaccin . Dado que dicho comportamiento es incompatible con muchas aplicaciones Transact-SQL, las transacciones de tipo Transact-SQL (o "no encadenadas") permanecen como la opcin predeterminada. El modo de transacciones encadenadas puede iniciarse con la nueva opcin set chained . La nueva opcin set transaction isolation level controla los niveles de aislamiento de transacciones. Consulte el Captulo 17, "Transacciones: mantenimiento de la consistencia y recuperacin de datos", para obtener ms informacin. Identificadores delimitados Ahora SQL Server admite el uso de identificadores delimitados para nombres de tablas, vistas y columnas. Los identificadores delimitados son nombres de objetos entre comillas dobles y su uso permite evitar ciertas restricciones sobre nombres de objetos. Utilice la nueva opcin set quoted_identifier para reconocer los identificadores delimitados. Cuando esta opcin est activada, todos los caracteres incluidos entre comillas dobles son tratados como identificadores. Dado que este comportamiento es incompatible con muchas aplicaciones existentes, el valor predeterminado para esta opcin es off (desactivada). Comentarios de tipo estndar SQL En Transact-SQL, los comentarios estn delimitados por pares /* */ y pueden anidarse. Ahora Transact-SQL tambin admite los comentarios de tipo estndar SQL, que estn formados por cualquier cadena de caracteres que empiece por dos signos menos conectados, un comentario y una lnea nueva de finalizacin: select "hello" -- esto es un comentario Los comentarios /* */ de Transact-SQL estn totalmente admitidos y los signos menos "- -" dentro de los comentarios de Transact-SQL todava no se reconocen. Truncado a la derecha de cadenas de caracteres Una nueva opcin de set , string_rtruncation , controla el truncado sin notificacin al usuario de cadenas de caracteres para compatibilidad con la norma SQL. Defina esta opcin como on (activada) para prohibir el truncado sin notificacin al usuario e imponer el comportamiento de la norma SQL. Permisos necesarios para las instrucciones update y delete Una opcin nueva de set , ansi_permissions , determina los permisos necesarios para las instrucciones delete y update . Cuando esta opcin est definida como on , SQL Server utiliza los requisitos de permisos ms estrictos de SQL92 para estas instrucciones. Dado que este comportamiento es incompatible con muchas aplicaciones existentes, el valor predeterminado de esta opcin es off . Errores aritmticos Las opciones de set arithabort y arithignore se han redefinido para permitir la compatibilidad con la norma SQL92:
Page 12 of 280

arithabort arith_overflow especifica el comportamiento posterior a un error de divisin por cero o a una prdida de precisin. El valor predeterminado, on , revierte toda la transaccin o lote en el que se produce el error. Si establece arithabort arith_overflow como off , SQL Server aborta la instruccin que causa el error, pero sigue procesando otras instrucciones de la transaccin o del lote. Para el cumplimiento con la norma SQL92, hay que definir set arithabort arith_overflow off . arithabort numeric_truncation especifica el comportamiento posterior a una prdida de escala mediante un tipo numrico exacto. El valor predeterminado, on , aborta la instruccin que causa el error, pero sigue procesando otras instrucciones de la transaccin o del lote. Si establece arithabort numeric_truncation como off , SQL Server trunca los resultados de la consulta y contina con el procesamiento. Para el cumplimiento con la norma SQL92, hay que definir set arithabort numeric_truncation on . arithignore arith_overflow determina si SQL Server muestra un mensaje despus de un error de divisin por cero o de una prdida de precisin. El valor predeterminado, off , muestra un mensaje de advertencia despus de estos errores. El establecimiento de arithignore arith_overflow como on suprime los mensajes de advertencia despus de estos errores. Para el cumplimiento con la norma SQL92, hay que definir set arithignore off .

Palabras clave sinnimas Se han aadido varias palabras clave para compatibilidad con la norma SQL que son sinnimas de palabras clave Transact-SQL existentes. Tabla 1-3: Palabras clave sinnimas SQL compatibles Sintaxis actual tran transaction any grant all revoke all max ( expression ) min ( expression ) Sintaxis adicional work some grant all privileges revoke all privileges max ([ all | distinct ]) expression min ([ all | distinct ]) expression

user_name built-in function user keyword Tratamiento de valores nulos Una opcin nueva de set , ansinull , determina si la evaluacin de los operandos con valor nulo (null) en comparaciones de igualdad (=) o desigualdad (!=) SQL y en funciones agregadas cumple con la norma SQL. Esta opcin no afecta al modo en que SQL Server evala los valores nulos en otros tipos de instrucciones SQL, como create table . Uso de Transact-SQL con la utilidad isql Es posible usar SQL directamente desde el sistema operativo, con el programa de utilidad autnomo isql . Para utilizar Transact-SQL, debe definir una cuenta, o login, en SQL Server. Cuando se usa isql , es necesario escribir lo siguiente junto al indicador del sistema operativo: isql Aparece en pantalla esta solicitud de informacin: Password: Escriba la contrasea junto a la solicitud y oprima la tecla de retorno. La contrasea no aparece en pantalla mientras se escribe. Observe que los nombres de login y las contraseas distinguen las maysculas de las minsculas. Esto es lo que ver: 1> Ahora puede comenzar a emitir comandos Transact-SQL. Para obtener informacin detallada sobre el uso de isql , consulte el manual Programas de Utilidad de SQL Server correspondiente al sistema operativo.
Page 13 of 280

Seleccin de la contrasea Una vez realizada la conexin, puede cambiar la contrasea en cualquier momento con el procedimiento del sistema sp_password . A continuacin se indica cmo cambiar la contrasea "terrible2" a "3blindmice": 1> sp_password terrible2, 3blindmice 2> go Observe que la palabra "go" aparece en una lnea independiente y que no debe ir precedido de espacios en blanco ni tabuladores. Se trata del terminador de comando, que indica a SQL Server que el usuario ya ha terminado de introducir datos y que est listo para la ejecucin del comando. La contrasea es la primera lnea de defensa frente al acceso a SQL Server de personas no autorizadas. Las contraseas de SQL Server deben tener al menos seis bytes de longitud y pueden contener cualquier carcter imprimible. Cuando cree su propia contrasea, elija una que no pueda adivinarse. No use informacin personal, nombres de mascotas o seres queridos, ni palabras que aparezcan en el diccionario. Las contraseas ms difciles de adivinar son aquellas que combinan maysculas y minsculas o nmeros y letras. Una vez seleccionada la contrasea, su proteccin es responsabilidad del usuario. No proporcione a nadie su contrasea ni la anote en algn sitio donde la puedan ver. Para obtener ms informacin sobre sp_password , consulte el Manual de Referencia de SQL Server . Cuando ejecute un procedimiento almacenado, al final de la ejecucin aparecer un estado de retorno. Un estado de retorno de "0" significa que la ejecucin se ha realizado correctamente. Bases de datos predeterminadas Al crear la cuenta de SQL Server, es posible que se le haya asignado una base de datos predeterminada, a la que se conecta cuando introduce el login. Por ejemplo, la base de datos predeterminada podra ser pubs2 , la de muestra. Si no se le ha asignado ninguna base de datos predeterminada, estar conectado a la base de datos master . Puede sustituir la base de datos predeterminada por otra a la que tenga acceso (permiso) de uso o que admita usuarios invitados. Cualquier usuario con un login a SQL Server, es decir, que aparezca en master..syslogins , puede ser un invitado. Para cambiar la base de datos predeterminada, utilice el procedimiento del sistema sp_modifylogin . Para obtener informacin sobre este procedimiento, consulte el Manual de Referencia de SQL Server . En cualquier caso, para cerciorarse de que se encuentra en pubs2 , ejecute este comando: 1> use pubs2 2> go Ahora est listo para seguir los ejemplos proporcionados en el Captulo 2, "Consultas: seleccin de datos de una tabla". Con un par de excepciones, los ejemplos de instrucciones Transact-SQL mostrados en el resto del manual no incluyen las solicitudes de lnea usadas por la utilidad isql , ni el terminador go . Para obtener ms detalles sobre la utilidad isql , consulte el manual Programas de Utilidad de SQL Server del sistema operativo. Uso de la base de datos de muestra pubs2 La base de datos de muestra pubs2 se utiliza en casi todos los ejemplos de este manual. Puede probar cualquiera de los ejemplos en su propia estacin de trabajo. Los resultados de consulta que aparecen en pantalla pueden no tener el mismo aspecto que los del manual. Esto es porque a algunos de los ejemplos que aparecen aqu se les ha dado otro formato (por ejemplo, realineacin de columnas) a fin de proporcionar mayor claridad visual u ocupar menos espacio en la pgina. Es posible que tenga que obtener permisos adicionales para cambiar la base de datos de muestra mediante create o instrucciones de modificacin de datos. El administrador del sistema puede otorgar estos permisos. Si cambia la base de datos de muestra, compruebe que vuelve a asignarle su estado original para los futuros usuarios y usos. Si necesita ayuda para restaurar la base de datos de muestra, dirjase al administrador del sistema. Contenido de la base de datos de muestra
Page 14 of 280

La base de datos de muestra, pubs2 , se compone de las siguientes tablas: publishers, authors, titles, titleauthor, roysched, sales, salesdetail, stores, discounts, au_pix y blurbs . La mayora de los ejemplos se toman de las primeras cuatro tablas. A continuacin se describe brevemente cada tabla:

publishers contiene los nmeros de identificacin, nombres, ciudades y estados de tres editoriales. authors contiene un nmero de identificacin, nombre y apellido, direccin y tipo de contrato de cada autor. Para cada libro que se ha publicado o se va a publicar, la tabla titles contiene su nmero de identificacin, nombre, tipo, nmero

de identificacin del editor, precio, anticipos, derechos de autor, ventas anuales hasta la fecha, comentarios y fecha de publicacin. titleauthor enlaza las tablas titles y authors . Para cada libro, contiene la ID del autor, la ID del ttulo, el pedido del autor y la divisin de los derechos de autor entre los autores de un libro. roysched enumera los rangos de ventas de unidades y los derechos de autor conectados a cada rango. Los derechos de autor son un porcentaje de los ingresos netos procedentes de las ventas. sales registra la ID de la tienda, el nmero de pedido y la fecha de ventas del libro. Hace la funcin de la tabla master para las filas detalladas en salesdetail. salesdetail registra las ventas en libreras de los ttulos que aparecen en la tabla titles . stores enumera las libreras por ID de tienda. discounts enumera tres tipos de descuentos para libreras. au_pix contiene imgenes de los autores en formato binario y el tipo de datos image . blurbs contiene largas descripciones de los libros en el tipo de datos text .

La base de datos de muestra aparece en el Suplemento de Referencia de SQL Server . Chapter 2

Consultas: seleccin de datos de una tabla


El comando select sirve para consultar la informacin de la base de datos. Puede utilizarse para recuperar un subconjunto de filas de una o varias tablas y un subconjunto de columnas de una o varias tablas. En este captulo se trata lo siguiente:

Seleccin de todas las columnas de una tabla Seleccin de columnas especificadas de una tabla Modificacin de los formatos de resultados de la instruccin select cambiando el nombre de los encabezados de las columnas y aadiendo cadenas de caracteres Inclusin de valores calculados simples en una instruccin select Eliminacin de filas duplicadas con distinct Uso de la clusula from para especificar tablas y vistas Uso de la clusula where con operadores de comparacin, operadores lgicos, between , in , any y like Uso de null y not null

Este captulo se centra en instrucciones select bsicas de una sola tabla. La informacin sobre los usos avanzados de select est disponible en captulos posteriores de este libro. Definicin de consulta Seleccin de columnas en una consulta Eliminacin de resultados de consulta duplicados con distinct Especificacin de tablas: la clusula from Seleccin de filas: la clusula where Definicin de consulta Una consulta es el proceso de solicitar datos de la base de datos y recibir resultados en respuesta. Este proceso tambin se conoce como recuperacin de datos . Todas las consultas SQL se expresan mediante la instruccin select . Las consultas pueden usarse para realizar selecciones , que recuperan un subconjunto de filas de una o ms tablas, y proyecciones , que recuperan un subconjunto de columnas de una o ms tablas. Esta es una versin simplificada de la instruccin select :
Page 15 of 280

select select_list from table_list where search_conditions La clusula select especifica las columnas que desea recuperar. La clusula from especifica las tablas de donde se deben extraer las columnas. La clusula where especifica las filas de las tablas que se desean ver. Por ejemplo, la siguiente instruccin select busca el nombre y los apellidos de los escritores que viven en Oakland en la tabla authors . select au_fname, au_lname from authors where city = "Oakland" Los resultados de la instruccin select se muestran en formato de columna, como a continuacin: au_fname au_lname -------------- ----------Marjorie Green Dick Straight Dirk Stringer Stearns MacFeather Livia Karsen (5 rows affected) Sintaxis de select La sintaxis de select es al mismo tiempo ms sencilla y ms compleja que la del ejemplo mostrado anteriormente. Es ms sencilla en cuanto que la clusula select es la nica que se requiere en una instruccin select . La clusula from se incluye casi siempre, pero tcnicamente slo es necesaria en las instrucciones select que recuperan datos de tablas. La clusula where es opcional, al igual que todas las dems clusulas. Por otro lado, la sintaxis completa de la instruccin select incluye las siguientes frases y palabras clave: select [all | distinct] select_list [into [[ database .]owner.] table_name ] [from [[ database .] owner .]{ view_name [(index index_name [ prefetch size [holdlock | noholdlock] [shared] [,[[ database .] owner .]{ view_name [(index index_name [ prefetch size [holdlock | noholdlock] [shared]]... ] [where search_conditions ]

| table_name ][lru|mru])]} | table_name ][lru|mru])]}

[group by [all] aggregate_free_expression [, aggregate_free_expression ]... ] [having search_conditions ] [order by {[[[ database .] owner .]{ table_name .| view_name .}] column_name | select_list_number | expression } [asc | desc] [,{[[[ database .] owner .]{ table_name | view_name .}] column_name | select_list_number | expression } [asc | desc]]...] [compute row_aggregate ( column_name ) [, row_aggregate ( column_name )]... [by column_name [, column_name ]...]] [for {read only | update [of column_name_list ]}]

[at isolation {read uncommitted | read committed | serializable}] [for browse] Las clusulas de una instruccin select deben usarse en el orden aqu indicado. Es decir, si la instruccin incluye una clusula group by y otra order by , group by debe preceder a order by .

Page 16 of 280

Tal como se explica en la seccin "Identificadores", los nombres de los objetos de base de datos deben calificarse si existe ambigedad sobre el objeto al que se hace referencia. Por ejemplo, si hay varias columnas llamadas name , es posible que haya que calificar name con el nombre de la base de datos, el del propietario o el de la tabla. Dado que en los ejemplos de este captulo se utilizan consultas a una sola tabla, los nombres de columna de los modelos de sintaxis y ejemplos no suelen calificarse con los nombres de las tablas, propietarios y bases de datos a que pertenecen. Estos elementos se han omitido a fin de facilitar la lectura, aunque nunca es incorrecto incluir calificadores. En las siguientes secciones de este captulo se analiza la sintaxis de la instruccin select con ms detalle. En este captulo slo se describen algunas de las clusulas y palabras clave incluidas en las sintaxis del comando select . Las clusulas group by , having , order by y compute se describen en el Captulo 3, "Cmo resumir, agrupar y ordenar resultados de consultas". La clusula into se describe en el Captulo 7, "Creacin de bases de datos y tablas". La clusula at isolation se explica en el Captulo 17, "Transacciones: mantenimiento de la consistencia y recuperacin de datos". Las palabras clave holdlock , noholdlock y shared (que tratan sobre bloqueos en SQL Server), as como la clusula index , se describen en la Gua de Mejora de Rendimiento y Afinacin de SQL Server . Para obtener informacin sobre las clusulas for read only y for update , consulte el Manual de Referencia de SQL Server . Note: La clusula for browse no se trata en este manual; se usa slo en las aplicaciones DB-Library(TM). Consulte el Manual de Referencia de Open Client DB-Library/C para obtener ms detalles al respecto.

Seleccin de columnas en una consulta La lista select se compone con frecuencia de una serie de nombres de columna separados por comas, o de un asterisco para representar todas las columnas en el orden de create table . Sin embargo, la lista de seleccin puede incluir una o ms expresiones, separadas por comas, siempre que la expresin sea una constante, nombre de columna, funcin, subconsulta o cualquier combinacin de los mismos, conectados mediante operadores aritmticos o basados en bits, y parntesis. La sintaxis general de la lista de seleccin es como la siguiente: select expression from table_list [, expression ]...

Si alguno de los nombres de tabla o columna de la lista no cumple con las reglas relativas a los identificadores vlidos, asegrese de definir set quoted_identifier como on e incluir el identificador entre comillas dobles. Seleccin de todas las columnas: s elect * El asterisco (*) tiene un significado especial en las instrucciones select : representa todos los nombres de columna de todas las tablas especificadas por la clusula from . Use el asterisco para ahorrar tiempo al teclear y evitar errores cuando desee ver todas las columnas de una tabla. Esta es la sintaxis general para seleccionar todas las columnas de una tabla: select * from table_list Dado que select * busca todas las columnas actuales de una tabla, los cambios en la estructura de una tabla, como la adicin, supresin o cambio de nombre de columnas, modifican de forma automtica los resultados de una instruccin select * . La presentacin individual de las columnas proporciona un control ms preciso sobre los resultados. La siguiente instruccin recupera todas las columnas de la tabla publishers y las muestra en el orden en que se definieron al crear la tabla. No se incluye ninguna clusula where , por lo que esta instruccin tambin recupera todas las filas. select * from publishers Los resultados tendrn el siguiente aspecto: pub_id ----0736 pub_name -------------New Age Books city --------Boston state ----WA
Page 17 of 280

0877 1389

Binnet & Hardley Algodata Infosystems

Washington Berkeley

DC CA

(3 rows affected) Los resultados son exactamente los mismos si todos los nombres de columna de la tabla se enumeran por orden despus de la palabra clave select : select pub_id, pub_name, city, state from publishers Tambin puede usar * ms de una vez en una consulta: select *, * from publishers El efecto es mostrar todos los nombres de columna y todos los datos guardados en las columnas dos veces. Al igual que los nombres de columna, * puede calificarse con un nombre de tabla, como en la siguiente consulta: select publishers.* from publishers Seleccin de algunas columnas Para seleccionar algunas, pero no necesariamente todas, las columnas de una tabla, use esta sintaxis: select column_name from table_name [, column_name ]...

Cada nombre de columna debe separarse del siguiente con una coma. Cambio del orden de las columnas El orden en que se enumeran los nombres de las columnas determina el orden en que stas aparecen. Los dos ejemplos siguientes muestran cmo se especifica el orden que tendrn las columnas al mostrarlas. En ambos casos se buscan y muestran los nombres de los editores y los nmeros de identificacin de las tres filas de la tabla publishers . En el primero se imprime pub_id en primer lugar, seguido de pub_name . En el segundo se invierte este orden. La informacin es exactamente la misma; lo nico que cambia es su organizacin. select pub_id, pub_name from publishers pub_id pub_name ------------------0736 New Age Books 0877 Binnet & Hardley 1389 Algodata Infosystems (3 rows affected) select pub_name, pub_id from publishers pub_name --------------------New Age Books Binnet & Hardley Algodata Infosystems (3 rows affected) Cambio de los nombres de columna de los resultados de consultas Cuando se muestran los resultados de las consultas, el encabezado predeterminado de cada columna toma el nombre que se le ha asignado durante su creacin. Puede especificar un encabezado de columna mediante: column_heading = column_name
Page 18 of 280

pub_id -----0736 0877 1389

o bien: column_name o bien: column_name as column_heading column_heading

en lugar de indicar slo el nombre de la columna en la lista de seleccin. Esto proporciona un nombre nuevo para la columna. Cuando este nombre se muestra en los resultados, funciona como un encabezado de columna, lo que permite producir resultados ms fciles de leer. Por ejemplo, para cambiar pub_name a "Publisher" en la consulta anterior, escriba cualquiera de estas instrucciones: select Publisher = pub_name, pub_id from publishers select pub_name Publisher, pub_id from publishers select pub_name as Publisher, pub_id from publishers Los resultados de estas instrucciones tendrn este aspecto: Publisher ---------------------New Age Books Binnet & Hardley Algodata Infosystems (3 rows affected) Cadenas de caracteres entre comillas en los encabezados de columna En un encabezado de columna se puede incluir cualquier carcter, incluidos espacios en blanco, si se encierra la totalidad del encabezado entre comillas. No es necesario definir la opcin quoted_identifier como on . Si no se incluye entre comillas, el encabezado debe cumplir con las reglas correspondientes a los identificadores. Estas dos consultas: select "Publisher's Name" = pub_name from publishers y: select pub_name "Publisher's Name" from publishers generan este resultado: Publisher's Name ---------------New Age Books Binnet & Hardley Algodata Infosystems Tambin puede utilizar palabras reservadas Transact-SQL en los encabezados de columna entre comillas. Por ejemplo, la siguiente consulta, que usa la palabra reservada sum como encabezado de columna, es vlida: select "sum" = sum(total_sales) from titles Los encabezados de columna incluidos entre comillas no pueden superar los 30 bytes de longitud. Note: Antes de usar comillas para incluir el nombre de una columna en una instruccin create table , alter table , select into o create view , defina la opcin quoted_identifier de set como on . Cadenas de caracteres en los resultados de las consultas pub_id -----0736 0877 1389

Page 19 of 280

Las instrucciones select vistas hasta ahora generan resultados formados por datos procedentes de las tablas de la clusula from . En los resultados de las consultas tambin pueden mostrarse cadenas de caracteres. Encierre toda la cadena de caracteres entre comillas simples o dobles y seprela de los dems elementos de la lista de seleccin con comas. Use comillas dobles si dentro de la cadena hay un apstrofo, ya que, de lo contrario, ste se interpretar como una comilla simple. A continuacin se muestra un ejemplo de una instruccin con una cadena de caracteres, seguida de sus resultados. select "The publisher's name is", Publisher = pub_name from publishers Publisher ------------------------------------------The publisher's name is New Age Books The publisher's name is Binnet & Hardley The publisher's name is Algodata Infosystems (3 rows affected) Valores calculados en la lista de seleccin Puede llevar a cabo clculos con datos de columnas numricas o con constantes numricas en una lista de seleccin. Operadores aritmticos La tabla siguiente muestra los operadores aritmticos disponibles. Para obtener informacin sobre los operadores basados en bits, consulte el Manual de Referencia de SQL Server . Tabla 2-1: Operadores aritmticos Smbolo + / * % Operacin Adicin Sustraccin Divisin Multiplicacin Mdulo

Los operadores aritmticos (adicin, sustraccin, divisin y multiplicacin) pueden utilizarse en cualquier columna numrica ( int, smallint, tinyint, numeric, decimal, float o money ). El operador mdulo no puede usarse con columnas money . Un mdulo es el resto entero de una operacin de divisin entre dos nmeros enteros. Por ejemplo, 21 % 9 = 3, porque 21 dividido por 9 es igual a 2, y sobra 3. Algunas operaciones aritmticas pueden efectuarse tambin con columnas datetime , mediante las funciones de fecha. Consulte el Captulo 10, "Uso de funciones incorporadas en consultas", para obtener informacin sobre las funciones de fecha. Todos estos operadores pueden usarse en la lista de seleccin con nombres de columnas y constantes numricas, en cualquier combinacin. Por ejemplo, para ver cmo sera un incremento del 100 por cien de las ventas para todos los libros de la tabla titles, escriba: select title_id, total_sales, total_sales * 2 from titles Estos son los resultados: title_id -------BU1032 BU1111 BU2075 BU7832 MC2222 MC3021 MC3026 PC1035 total_sales ----------4095 3876 18722 4095 2032 22246 NULL 8780

--------8190 7752 37444 8190 4064 44492 NULL 17560


Page 20 of 280

PC8888 PC9999 PS1372 PS2091 PS2106 PS3333 PS7777 TC3218 TC4203 TC7777 (18 rows affected)

4095 NULL 375 2045 111 4072 3336 375 15096 4095

8190 NULL 750 4090 222 8144 6672 750 30192 8190

Observe los valores nulos de la columna total_sales y la columna calculada. Los valores nulos no tienen valores explcitos asignados. Cuando se llevan a cabo operaciones aritmticas con un valor nulo (null), el resultado es NULL. Para asignar a la columna calculada un encabezado, como "proj_sales", escriba: select title_id, total_sales, proj_sales = total_sales * 2 from titles Si desea que la visualizacin sea an ms clara, intente aadir cadenas de caracteres, como "Current sales =" y "Projected sales are", a la instruccin select . La columna a partir de la que se genera la columna calculada no tiene que aparecer en la lista de seleccin. La columna total_sales , por ejemplo, se muestra en estos ejemplos de consultas slo para comparar sus valores con los valores de la columna total_sales * 2. Para ver slo los valores calculados, escriba: select title_id, total_sales * 2 from titles Los operadores aritmticos tambin funcionan directamente con los valores de datos de las columnas especificadas, siempre que no haya ninguna constante. A continuacin se muestra un ejemplo: select title_id, total_sales * price from titles title_id ----------------BU1032 81,859.05 BU1111 46,318.20 BU2075 55,978.78 BU7832 81,859.05 MC2222 40,619.68 MC3021 66,515.54 MC3026 NULL PC1035 201,501.00 PC8888 81,900.00 PC9999 NULL PS1372 8,096.25 PS2091 22,392.75 PS2106 777.00 PS3333 81,399.28 PS7777 26,654.64 TC3218 7,856.25 TC4203 180,397.20 TC7777 61,384.05 (18 rows affected) Por ltimo, las columnas calculadas pueden proceder de varias tablas. Los captulos sobre combinaciones y subconsultas ofrecen informacin sobre cmo trabajar con consultas de tablas mltiples. Esta consulta calcula el producto del nmero de copias de un libro de psicologa vendidas en un establecimiento (la columna qty de la tabla salesdetail ) y el precio del libro (la columna price de la tabla titles ). select salesdetail.title_id, stor_id, qty * price from titles, salesdetail where titles.title_id = salesdetail.title_id and titles.title_id = "PS2106"
Page 21 of 280

title_id stor_id ----------------------------------PS2106 8042 210.00 PS2106 8042 350.00 PS2106 8042 217.00 (3 rows affected) Precedencia de los operadores aritmticos Cuando hay ms de un operador aritmtico en una expresin, se calculan primero la multiplicacin, divisin y mdulo, seguidos de la sustraccin y adicin. Cuando todos los operadores aritmticos de una expresin tienen el mismo nivel de precedencia, el orden de ejecucin es de izquierda a derecha. Las expresiones entre parntesis tienen preferencia sobre todas las dems operaciones. Por ejemplo, la siguiente instruccin select multiplica las ventas totales de un libro por su precio para calcular la cantidad de ingresos totales, y luego resta a esta cantidad el anticipo entregado al autor dividido por la mitad. El producto de total_sales y price se calcula en primer lugar porque el operador es el de multiplicacin. A continuacin, el anticipo se divide por 2. Luego, este resultado se resta de total_sales . select title_id, total_sales * price - advance / 2 from titles Para evitar malentendidos, utilice parntesis. La siguiente consulta tiene el mismo significado y produce los mismos resultados que la anterior, pero probablemente resulte ms fcil de entender. select title_id,(total_sales * price)- (advance /2) from titles title_id ----------------BU1032 79,359.05 BU1111 43,818.20 BU2075 50,916.28 BU7832 79,359.05 MC2222 40,619.68 MC3021 59,015.54 MC3026 NULL PC1035 198,001.00 PC8888 77,900.00 PC9999 NULL PS1372 4,596.25 PS2091 1,255.25 PS2106 -2,223.00 PS3333 80,399.28 PS7777 24,654.64 TC3218 4,356.25 TC4203 178,397.20 TC7777 57,384.05 (18 rows affected) Utilice parntesis para modificar el orden de ejecucin; los clculos entre parntesis se realizan antes. Si los parntesis estn anidados, el clculo ms interno es el que se realiza primero. Por ejemplo, el resultado y el significado del ejemplo anterior pueden cambiarse si usa parntesis para que la sustraccin se evale antes que la divisin: select title_id, (total_sales * price - advance) /2 from titles title_id -----------------------------BU1032 38,429.53 BU1111 20,659.10 BU2075 22,926.89 BU7832 38,429.53 MC2222 20,309.84 MC3021 25,757.77 MC3026 NULL PC1035 97,250.50 PC8888 36,950.00
Page 22 of 280

PC9999 PS1372 PS2091 PS2106 PS3333 PS7777 TC3218 TC4203 TC7777 (18 rows affected)

NULL 548.13 10,058.88 -2,611.50 39,699.64 11,327.32 428.13 88,198.60 26,692.03

Seleccin de valores text e image Cuando la lista de seleccin incluye valores de tipo text e image , el lmite de longitud de los datos devueltos depende del valor de la variable global @@textsize . El valor predeterminado de @@textsize depende del software usado para acceder a SQL Server; el valor predeterminado es de 32 K para isql . Este valor se modifica con el comando set : set textsize 25 Con este valor de @@ textsize , una instruccin select que incluya una columna text slo muestra los primeros 25 bytes de datos. Note: Cuando se seleccionan datos de tipo image , el valor devuelto incluye los caracteres "0x", que indican que los datos son hexadecimales. Estos dos caracteres se cuentan como parte de @@textsize . Para restablecer el valor predeterminado de @@textsize , use: set textsize 0 El valor predeterminado mostrado es la longitud real de los datos cuando su tamao es menor que textsize . Para obtener ms informacin sobre los tipos de datos text e image , consulte el Captulo 6, "Uso y creacin de tipos de datos". Uso de readtext El comando readtext proporciona otra forma de recuperar valores text e image . Este comando necesita el nombre de la tabla y la columna, el puntero de texto, un desplazamiento inicial dentro de la columna y el nmero de caracteres o bytes que deben recuperarse. Este ejemplo busca 6 caracteres en la columna copy de la tabla blurbs : declare @val varbinary(16) select @val = textptr(copy) from blurbs where au_id = "648-92-1872" readtext blurbs.copy @val 2 6 using chars En el ejemplo, readtext muestra los caracteres 3 a 8 de la columna copy , ya que el desplazamiento era de 2. La sintaxis completa del comando readtext es: readtext [[ database .] owner .] table_name . [holdlock] [using {bytes|chars|characters}] [at isolation {read uncommitted | read committed | serializable}] column_name text_ptr offset size

La funcin textptr devuelve una cadena de caracteres binaria de 16 bytes. Declare una variable local para contener el puntero de texto y luego use la variable con readtext . El indicador holdlock hace que el valor de texto quede bloqueado para las lecturas hasta el final de la transaccin. Otros usuarios pueden leer el valor, pero no modificarlo. La clusula at isolation se describe en el Captulo 17, "Transacciones: mantenimiento de la consistencia y recuperacin de datos". Si utiliza un juego de caracteres multibyte, la opcin using permite elegir si readtext debe interpretar el desplazamiento y el tamao como bytes o como caracteres. Tanto chars como characters se usan para especificar caracteres. Esta opcin no tiene ningn efecto cuando se usa con un juego de caracteres de un solo byte o con valores image ( readtext lee los valores image slo de byte en byte). Si no se indica la opcin using , readtext devuelve el valor como si se hubiesen especificado bytes.
Page 23 of 280

SQL Server tiene que determinar el nmero de bytes que deben enviarse al cliente en respuesta a un comando readtext . Cuando el desplazamiento y el tamao estn en bytes, es sencillo determinar el nmero de bytes del texto devuelto. Cuando el desplazamiento y el tamao estn en caracteres, SQL Server debe dar un paso ms para calcular el nmero de bytes que van a devolverse al cliente. Como resultado, el rendimiento puede resultar ms lento cuando se usan caracteres como desplazamiento y tamao. using characters slo es til cuando SQL Server utiliza un juego de caracteres multibyte. Esta opcin garantiza que readtext no devuelva caracteres parciales. Cuando se usan bytes como desplazamiento, SQL Server puede encontrar caracteres parciales al comienzo o al final de los datos text que deben devolverse. En caso de encontrarlos, el servidor sustituye cada carcter parcial por interrogaciones antes de devolver el texto al cliente. No es posible usar readtext con columnas text e image de vistas. Resumen de la lista select La lista select puede incluir * (todas las columnas en el orden establecido por el comando create-table), una lista de nombres de columnas en cualquier orden, cadenas de caracteres, encabezados de columna y expresiones que incluyan operadores aritmticos. Tambin puede incluir funciones agregadas, que se tratan en la seccin sobre group by de este mismo captulo y en el Captulo 3, "Cmo resumir, agrupar y ordenar resultados de consultas". A continuacin se facilitan algunas listas de seleccin que pueden probarse con las tablas de la base de datos de muestra pubs2 : 1. select titles.* from titles 2. select Name = au_fname, Surname = au_lname from authors 3. select Sales = total_sales * price, ToAuthor = advance, ToPublisher = (total_sales * price) - advance from titles 4. select 'Social security #', au_id from authors 5. select this_year = advance, next_year = advance + advance/10, third_year = advance/2, 'for book title #', title_id from titles 6. select 'Total income is', Revenue = price * total_sales, 'for', Book# = title_id from titles Eliminacin de resultados de consulta duplicados con distinct La palabra clave opcional distinct elimina las filas duplicadas de los resultados de una instruccin select . Si no especifica distinct , se obtienen todas las filas, incluidas las duplicadas. De forma opcional, es posible especificar la palabra clave all antes de la lista de seleccin, en cuyo caso se obtienen todas las filas. all es el valor predeterminado. Por ejemplo, si busca todos los cdigos de identificacin de autor de la tabla titleauthor sin distinct, se obtienen estas filas: select au_id from titleauthor au_id ----------172-32-1176 213-46-8915 213-46-8915 238-95-7766 267-41-2394 267-41-2394 274-80-9391 409-56-7008 427-17-2319 472-27-2349 486-29-1786 486-29-1786 648-92-1872 672-71-3249
Page 24 of 280

712-45-1867 722-51-5454 724-80-9391 724-80-9391 756-30-7391 807-91-6654 846-92-7186 899-46-2035 899-46-2035 998-72-3567 998-72-3567 (25 rows affected) Si observa los resultados, podr comprobar que existen varias filas duplicadas. Puede eliminarlas y ver slo los cdigos de ID ( au_id ) nicos, usando distinct . select distinct au_id from titleauthor au_id ----------172-32-1176 213-46-8915 238-95-7766 267-41-2394 274-80-9391 409-56-7008 427-17-2319 472-27-2349 486-29-1786 648-92-1872 672-71-3249 712-45-1867 722-51-5454 724-80-9391 756-30-7391 807-91-6654 846-92-7186 899-46-2035 998-72-3567 (19 rows affected) Note: A fin de mantener la compatibilidad con otras implementaciones de SQL, la sintaxis de SQL Server permite el uso de la palabra clave all para pedir de forma explcita todas las filas. Sin embargo, no existe ninguna razn para usar all , porque "todas las filas" es el valor predeterminado. La palabra clave distinct considera los valores nulos como duplicados el uno del otro. En otras palabras, cuando distinct se incluye en una instruccin select , se devuelve un solo valor NULL en los resultados, independientemente del nmero de valores nulos encontrados. Especificacin de tablas: la clusula from La clusula from es necesaria en todas las instrucciones select que usen datos procedentes de tablas o vistas. Utilcela para mostrar todas las tablas y vistas que contengan las columnas incluidas en la lista de seleccin y en la clusula where . Si la clusula from incluye varias tablas o vistas, seprelas con comas. El nmero mximo de tablas y vistas permitidas en una consulta es 16. Este total incluye las tablas indicadas en la clusula from , las tablas de base a las que hace referencia una definicin de vista, todas las tablas a las que se hace referencia en las subconsultas y todas las tablas a las que se hace referencia como parte de las restricciones de integridad referenciales. La sintaxis de from es la siguiente: select select_list [from [[ database .] owner .]{ table_name [holdlock | noholdlock] [shared] [,[[ database .] owner .]{ table_name [holdlock | noholdlock] [shared]]... ]

| |

view_name view_name

} }

Page 25 of 280

Los nombres de las tablas pueden tener entre 1 y 30 bytes de longitud. Como primer carcter puede usar una letra, @, # o _. Los siguientes caracteres pueden ser dgitos, letras, @, #, $, _, o . Los nombres de las tablas temporales pueden comenzar por # (smbolo de nmero) si se crean fuera de tempdb o con " tempdb ..". Si crea una tabla temporal fuera de tempdb , su nombre no deber exceder los 13 bytes, puesto que SQL Server asigna un sufijo numrico interno al nombre a fin de garantizar que ste sea nico. Para ms informacin, consulte el Captulo 7, "Creacin de bases de datos y tablas". En la clusula from , la sintaxis completa de nombres para tablas y vistas siempre est permitida, por ejemplo: database database . . owner owner . . table_name view_name

Esto slo es necesario cuando puede existir confusin entre varios nombres. Es posible asignar nombres de correlacin a las tablas a fin de ahorrar tiempo al teclear. Los nombres de correlacin se asignan en la clusula from , indicando el nombre de correlacin tras el nombre de la tabla, de la siguiente manera: select p.pub_id, p.pub_name from publishers p Todas las dems referencias a esa tabla, por ejemplo en una clusula where , deben usar el nombre de correlacin. Los nombres de correlacin no pueden comenzar por un valor numrico. Seleccin de filas: la clusula where La clusula where de una instruccin select especifica los criterios que definen las filas exactas que deben recuperarse. El formato general es: select select_list from table_list where search_conditions Las condiciones de bsqueda, o calificaciones, de la clusula where incluyen:

Operadores de comparacin (=, <, >, etc.) where advance * 2 > total_sales * price

Mrgenes ( between y not between ) where total_sales between 4095 and 12000

Listas ( in, not in ) where state in ("CA", "IN", "MD")

Coincidencias de caracteres ( like y not like ) where phone not like "415%"

Valores desconocidos ( is null y is not null ) where advance is null

Combinaciones de los anteriores ( and , or ) where advance < 5000 or total_sales between 2000 and 2500

Adems, la palabra clave where puede introducir:

Condiciones de combinacin (consulte el Captulo 4, "Combinaciones: recuperacin de datos de varias tablas"). Subconsultas (consulte el Captulo 5, "Subconsultas: uso de consultas dentro de otras consultas").
Page 26 of 280

Note: La nica condicin where que puede usar en las columnas de tipo text es like (o not like ). Para obtener una lista completa de las condiciones de bsqueda posibles, incluidas algunas que no se mencionan aqu, consulte las secciones sobre las condiciones de bsqueda o la clusula where del Manual de Referencia de SQL Server . Operadores de comparacin Transact-SQL utiliza los siguientes operadores de comparacin: Tabla 2-2: Operadores de comparacin de SQL Operador = > < >= <= != <> !> !< Significado Igual que Mayor que Menor que Mayor o igual que Menor o igual que Distinto de Distinto de No mayor que No menor que

Los operadores se utilizan con la siguiente sintaxis: where expression comparison_operator expression

donde cada expresin ( expression ) es una constante, nombre de columna, funcin, subconsulta o cualquier combinacin de los mismos conectados mediante operadores aritmticos o basados en bits. En la comparacin de datos de caracteres, < significa antes en el criterio de ordenacin y > significa despus en el criterio de ordenacin (use el procedimiento del sistema sp_helpsort para ver el criterio de SQL Server). Los espacios en blanco finales se ignoran en las comparaciones. As, "Dirk" es lo mismo que "Dirk ". En la comparacin de fechas, < significa antes y > significa despus. Asegrese de incluir entre comillas simples o dobles todos los datos de tipo char , nchar , varchar , nvarchar , text y datetime . Para obtener ms informacin sobre la introduccin de datos datetime , consulte el Captulo 8, "Adicin, modificacin y eliminacin de datos". A continuacin se muestran algunos ejemplos de instrucciones select que emplean operadores de comparacin: select * from titleauthor where royaltyper < 50 select authors.au_lname, authors.au_fname from authors where au_lname >'McBadden' select au_id, phone from authors where phone !='415 658-9932' select title_id, newprice = price * $1.15 from pubs2..titles where advance > 5000 not niega una expresin. Cualquiera de las dos consultas siguientes buscar todos los libros sobre negocios y psicologa que no tengan un anticipo superior a $5500. Sin embargo, observe la diferencia en la posicin del operador lgico de negacin ( not ) y el operador de comparacin negativo ( !> ). select title_id, type, advance from titles where (type = "business" or type = "psychology") and not advance >5500 select title_id, type, advance from titles
Page 27 of 280

where (type = "business" or type = "psychology") and advance !>5500 title_id type advance -------- ------------------BU1032 business 5,000.00 BU1111 business 5,000.00 BU7832 business 5,000.00 PS2091 psychology 2,275.00 PS3333 psychology 2,000.00 PS7777 psychology 4,000.00 (6 rows affected) Mrgenes ( between y not between ) Utilice la palabra clave between para especificar un margen incluyente, en el que se busque el valor ms bajo y el ms alto, as como los valores comprendidos entre stos. Por ejemplo, para buscar todos los libros con ventas entre 4095 y 12000, ambas inclusive, puede escribir esta consulta: select title_id, total_sales from titles where total_sales between 4095 and 12000 title_id total_sales ----------------BU1032 4095 BU7832 4095 PC1035 8780 PC8888 4095 TC7777 4095 (5 rows affected) Observe que los libros con ventas de 4095 se incluyen en los resultados. Si hay alguno con ventas de 12000, tambin se incluye. Puede especificar un margen excluyente con los operadores mayor que (>) y menor que (<). La misma consulta con los operadores mayor que y menor que devuelve los siguientes resultados, ya que estos operadores no son incluyentes: select title_id, total_sales from titles where total_sales > 4095 and total_sales < 12000 title_id total_sales ---------------PC1035 8780 (1 row affected) not between busca todas las filas que no estn dentro del margen. Para buscar todos los libros con ventas fuera del margen de 4095 a 12000, escriba: select title_id, total_sales from titles where total_sales not between 4095 and 12000 title_id total_sales -----------------BU1111 3876 BU2075 18722 MC2222 2032 MC3021 22246 PS1372 375 PS2091 2045 PS2106 111 PS3333 4072 PS7777 3336 TC3218 375 TC4203 15096 (11 rows affected) Listas ( in y not in )
Page 28 of 280

La palabra clave in permite seleccionar valores que coincidan con los de una lista de valores. Por ejemplo, si no usa in y desea obtener una lista con los nombres y los estados de todos los autores que viven en California, Indiana o Maryland, puede escribir esta consulta: select au_lname, state from authors where state = 'CA' or state = 'IN' or state = 'MD' Sin embargo, para obtener el mismo resultado sin teclear tanto se usa in . Los elementos que siguen a la palabra clave in deben separarse mediante comas e incluirse entre parntesis. select au_lname, state from authors where state in('CA', 'IN', 'MD') Estos son los resultados de ambas consultas: au_lname ----------White Green Carson O'Leary Straight Bennet Dull Gringlesby Locksley Yokomoto DeFrance Stringer MacFeather Karsen Panteley Hunter McBadden state ----CA CA CA CA CA CA CA CA CA CA IN CA CA CA MD CA CA

(17 rows affected) Quizs el uso ms importante para la palabra clave in sea en las consultas anidadas, tambin llamadas subconsultas. Para obtener informacin completa sobre las subconsultas, consulte el Captulo 5, "Subconsultas: uso de consultas dentro de otras consultas". Sin embargo, el siguiente ejemplo proporciona una idea de lo que puede hacer con las consultas anidadas y la palabra clave in . Suponga que desea saber los nombres de los autores que reciben menos del 50 por cien de los derechos totales de autor de los libros de los que son coautores. La tabla authors contiene los nombres de los autores y la tabla titleauthor proporciona informacin sobre los derechos de autor. Uniendo ambas tablas con in , pero sin enumerarlas en la misma clusula from , es posible extraer la informacin necesaria. La siguiente consulta se traduce de esta manera: buscar todos los cdigos de ID ( au_id s) de la tabla titleauthor en que el autor obtenga menos del 50 por cien de los derechos de autor por cualquier libro. Luego, seleccionar en la tabla authors todos los nombres de autores cuyas au_id s coincidan con los resultados de la consulta titleauthor . Los resultados muestran que hay varios autores incluidos en la categora inferior al 50 por cien. select au_lname, au_fname from authors where au_id in (select au_id from titleauthor where royaltyper <50) au_lname au_fname ------------------------Green Marjorie O'Leary Michael O'Leary Michael Gringlesby Burt Yokomoto Akiko MacFeather Stearns Ringer Anne (7 rows affected)
Page 29 of 280

not in busca los autores que no coinciden con los elementos de la lista. La siguiente consulta busca los nombres de los autores que no obtienen menos del 50 por cien de los derechos de autor en al menos un libro. select au_lname, au_fname from authors where au_id not in (select au_id from titleauthor where royaltyper <50) au_lname au_fname -------------------------White Johnson Carson Cheryl Straight Dick Smith Meander Bennet Abraham Dull Ann Locksley Chastity Greene Morningstar Blotchet-Halls Reginald del Castillo Innes DeFrance Michel Stringer Dirk Karsen Livia Panteley Sylvia Hunter Sheryl McBadden Heather Ringer Albert (17 rows affected) Bsqueda de cadenas de caracteres: like Utilice la palabra clave like para seleccionar las filas con campos que coincidan con partes especficas de cadenas de caracteres. like se usa con los tipos de datos char , varchar , nchar , nvarchar , binary , varbinary , text y datetime . La columna de datos puede compararse con una "cadena de bsqueda" que puede incluir estos smbolos especiales: Tabla 2-3: Smbolos especiales para la bsqueda de cadenas de caracteres Smbolos % _ Significado Busca cualquier cadena de cero o ms caracteres. Busca cualquier carcter individual. Los corchetes incluyen mrgenes o conjuntos, como [a-f] o [abcdef]. El especificador ( specifier ) acepta dos formatos:

rangespec1 - rangespec2 : rangespec1 indica el comienzo de un margen de caracteres.


[ specifier ] - es un carcter especial, que indica un margen.

rangespec2 indica el final de un margen de caracteres. set :


puede estar compuesto por cualquier conjunto discreto de valores, en cualquier orden, como [a2bR]. Observe que el margen [a-f] y los conjuntos [abcdef] y [fcbdae] devolvern el mismo conjunto de valores. [^ specifier El acento circunflejo (^) delante de un especificador indica exclusin. [^a-f] significa "no dentro del margen a-f"; ] [^a2bR] significa "ni a, ni 2, ni b ni R". Los datos de las columnas pueden coincidir con constantes, variables u otras columnas que contengan estos caracteres comodn . Cuando use constantes, incluya las cadenas de bsqueda y las cadenas de caracteres entre parntesis. Por ejemplo, si usa like con los datos de la tabla authors :
Page 30 of 280

like "Mc%" busca todos los nombres que comiencen con las letras ''Mc'' (McBadden). l ike "%inger" busca todos los nombres que terminen con ''inger'' (Ringer, Stringer). like "%en%" busca todos los nombres que incluyan las letras ''en'' (Bennet, Green, McBadden). like "_heryl" busca todos los nombres de seis letras que terminen con ''heryl'' (Cheryl). like "[CK]ars[eo]n" busca ''Carsen'', '' Karsen'', ''Carson'' y ''Karson'' (Carson). like "[M-Z]inger" busca todos los nombres que terminen con ''inger'' y que comiencen con cualquier letra de la M a la Z (Ringer). like "M[^c]%" busca todos los nombres que empiecen con ''M'' y no tengan ''c'' como segunda letra.

Esta consulta busca todos los nmeros de telfono de la tabla authors cuyo prefijo sea 415: select phone from authors where phone like "415%" not like se puede usar con los mismos caracteres comodn. Para buscar todos los nmeros de telfono de la tabla authors cuyo prefijo no sea 415, puede utilizar cualquiera de las siguientes consultas: select phone from authors where phone not like "415%" select phone from authors where not phone like "415%" La nica condicin where que puede usarse en columnas de tipo text es like . Esta consulta busca todas las filas de la tabla blurbs cuya columna copy mencione la palabra "computer": select * from blurbs where copy like "%computer%" Los caracteres comodn utilizados sin like se interpretan como literales y no como un patrn; representan exactamente sus propios valores. La siguiente consulta trata de encontrar los nmeros de telfono compuestos exclusivamente por los cuatro caracteres "415%". No busca los nmeros de telfono que comienzan por 415. select phone from authors where phone = "415%" Uso de caracteres comodn como caracteres literales Se pueden buscar caracteres comodn propiamente dichos convirtindolos en caracteres de escape y buscndolos como literales. Existen dos formas de utilizar los caracteres comodn como literales en una cadena de bsqueda like : corchetes y la clusula escape . La cadena de bsqueda tambin puede ser una variable o un valor de una tabla que contenga un carcter comodn. Para ms informacin sobre like y los caracteres comodn (incluido el uso de like con juegos de caracteres multibyte y criterios de ordenacin que no distingan las maysculas de las minsculas), consulte el Manual de Referencia de SQL Server . Corchetes (extensin Transact-SQL) Utilice los corchetes como caracteres para el signo de porcentaje, el carcter de subrayado y el corchete inicial. El corchete final no precisa carcter de escape, puede usarse solo. Para buscar un guin, en lugar de emplearlo para especificar un margen de bsqueda, selo como primer carcter dentro de los corchetes. Tabla 2-4: Uso de corchetes para la bsqueda de caracteres comodn Predicado like like "5%" like "5[%]" like "_n" like "[_]n" Significado 5 seguido por cualquier cadena de 0 o ms caracteres 5% an, in, on, etc. _n
Page 31 of 280

like "[a-cdf]" like "[-acdf]" like "[[ ]" like "]"

a, b, c, d, o bien f -, a, c, d, o bien f [ ]

Clusula escape (compatible con la norma SQL) Use la clusula escape para especificar un carcter de escape en el predicado like : Tabla 2-5: Uso de la clusula escape Predicado l ike like "5@%" escape "@" like "*_n" escape "*" like "%80@%%" escape "@" like "*_sql**%" escape "*" Significado 5% _n cadena que contiene 80% cadena que contiene _sql*

like "%#####_#%%" escape "#" cadena que contiene ##_%

Un carcter de escape debe ser una cadena de un solo carcter. Es posible utilizar cualquier carcter del juego de caracteres predeterminado del servidor. La especificacin de ms de un carcter de escape genera una condicin de error SQLSTATE y SQL Server muestra un mensaje de error.Por ejemplo, las siguientes clusulas de escape originan esta condicin de error: like "%XX_%" escape "XX" like "%XX%X_%" escape "XX"

Los caracteres de escape slo son vlidos dentro de su predicado like y no tienen ningn efecto sobre otros predicados like contenidos en la misma instruccin. Los nicos caracteres que son vlidos tras un carcter de escape son los caracteres comodn ( _, %, [, ] o [^] ) y el propio carcter de escape. El carcter de escape afecta slo al carcter que le sigue, y no a los caracteres subsiguientes. Si el patrn contiene dos apariciones literales de un carcter que resulta ser un carcter de escape, la cadena debe contener cuatro caracteres de escape consecutivos (consulte el quinto ejemplo de la Tabla 2-5: Uso de la clusula escape). De lo contrario, SQL Server genera una condicin de error SQLSTATE y muestra un mensaje de error.Por ejemplo, las siguientes clusulas de escape originan esta condicin de error: like like like like "P%X%%X" escape "X" "%X%%Xd_%" escape "X" "%?X%" escape "?" "_e%&u%" escape "&"

Interaccin de los corchetes y la clusula escape El carcter de escape conserva su significado especial dentro de los corchetes, a diferencia de lo que ocurre con los caracteres comodn, como el carcter de subrayado, el signo de porcentaje y el corchete inicial. Conviene no utilizar los caracteres comodn existentes como caracteres de escape por las siguientes razones:

Si especifica el carcter de subrayado ( _ ) o el signo de porcentaje (%) como caracteres de escape, ambos pierden su significado especial dentro de ese predicado like y slo actan como caracteres de escape. Si especifica el corchete inicial o el final ( [ o ] ) como caracteres de escape, el significado del corchete para TransactSQL queda desactivado dentro de ese predicado like . Si especifica - o [^] como caracteres de escape, ambos pierden el significado especial que suelen tener dentro de los corchetes y slo actan como caracteres de escape.

Espacios finales en blanco y % Los espacios finales en blanco que siguen al signo "%" de una clusula like se truncan a un solo espacio en blanco. like ''% '' (porcentaje seguido de 2 espacios) coincide con ''X '' (un espacio), ''X '' (dos espacios), ''X '' (tres espacios) o cualquier nmero de espacios finales.
Page 32 of 280

Uso de caracteres comodn en columnas Es posible usar caracteres comodn en las columnas, y los nombres de columnas, a su vez, en las clusulas like . Puede crearse una tabla special_discounts en la base de datos pubs2 para ejecutar una proyeccin de precios para una venta especial: id_type discount ------- ----------BU% 10 PS% 12 MC% 15 La siguiente consulta usa los caracteres comodn de id_type en la clusula where : select title_id, discount, price, price - (price*discount/100) from special_discounts, titles where title_id like id_type Los resultados de esa consulta son: title_id discount price -------- ----------- -------------- -------------BU1032 10 19.99 17.99 BU1111 10 11.95 10.76 BU2075 10 2.99 2.69 BU7832 10 19.99 17.99 PS1372 12 21.59 19.00 PS2091 12 10.95 9.64 PS2106 12 7.00 6.16 PS3333 12 19.99 17.59 PS7777 12 7.99 7.03 MC2222 15 19.99 16.99 MC3021 15 2.99 2.54 MC3026 15 NULL NULL (12 rows affected) Esto permite la bsqueda de patrones sofisticados sin tener que crear una serie de clusulas or . Cadenas de caracteres y comillas Cuando se introducen o buscan datos de caracteres y de fecha (tipos de datos char , nchar, varchar, nvarchar , datetime y smalldatetime ), es necesario incluirlos entre comillas simples o dobles. Note: Si la opcin quoted_identifier est definida como on, no utilice comillas dobles con datos de caracteres ni de fecha. Use comillas simples, ya que, de lo contrario, SQL Server considerar los datos como identificadores. Existen dos formas de especificar comillas literales dentro de una entrada de datos de caracteres. El primer mtodo consiste en usar dos comillas consecutivas. Por ejemplo, si comenz la introduccin de datos de caracteres con una sola comilla y desea incluir una comilla simple como parte de la entrada, use dos comillas simples seguidas: 'I dont understand.' Con comillas dobles: "He said, ""It is not really confusing."""

El segundo mtodo consiste en encerrar una comilla en el otro tipo de comilla. En otras palabras, incluya una entrada que contenga comillas dobles entre comillas simples, o viceversa. He aqu algunos ejemplos: 'George said, "There must be a better way."' "Isn't there a better way?" 'George asked, "Isnt there a better way?"'
Page 33 of 280

Para continuar una cadena de caracteres que sobrepase el final de una lnea de la pantalla, introduzca una barra invertida (\) antes de pasar a la siguiente lnea. Valores "desconocidos": NULL Cuando aparece NULL en una columna, significa que ni el usuario ni la aplicacin han realizado ninguna entrada en esa columna. El valor de datos de esa columna es "desconocido" o "no disponible". NULL no es sinnimo de "cero" (valores numricos) ni de "espacio en blanco" (valores de caracteres). Los valores nulos permiten establecer una distincin entre introducir deliberadamente un cero para las columnas numricas o un espacio en blanco para las columnas de caracteres, y no introducir nada, lo cual tiene el valor NULL tanto para las columnas numricas como para las de caracteres. NULL puede introducirse en una columna que admite valores nulos, segn se haya especificado en la instruccin create table , de dos formas:

Si no se introducen datos, SQL Server introduce de forma automtica el valor NULL. El usuario puede introducir explcitamente el valor NULL tecleando la palabra "NULL" o "null" sin comillas simples ni dobles.

Si la palabra "NULL" se teclea en una columna de caracteres con comillas simples o dobles, se tratar como datos y no como un valor nulo. Cuando se recuperan valores nulos, la presentacin de los resultados de las consultas muestran la palabra NULL en la posicin adecuada. Por ejemplo, la columna advance de la tabla titles permite valores nulos. Si examina los datos de dicha columna, podr determinar si un libro no ha tenido ningn pago anticipado porque as se ha acordado (cero en la columna advance como en la fila correspondiente a MC2222), o bien si el importe del anticipo no se conoca cuando se introdujeron los datos (NULL en la columna advance, como en la fila correspondiente a MC3026). select title_id, type, advance from titles where pub_id = "0877" title_id type advance ------------------------MC2222 mod_cook 0.00 MC3021 mod_cook 15,000.00 MC3026 UNDECIDED NULL PS1372 psychology 7,000.00 TC3218 trad_cook 7,000.00 TC4203 trad_cook 4,000.00 TC7777 trad_cook 8,000.00 (7 rows affected) Transact-SQL trata los valores nulos de diversas formas, segn los operadores que se utilicen y el tipo de valores que se est comparando. Los siguientes operadores devolvern resultados cuando se usen con un valor NULL:

= devuelve todas las filas que contienen NULL. != o <> devuelve todas las filas que no contienen NULL.

Sin embargo, cuando set ansinull est definido como on para cumplir con la norma SQL, los operadores = y != no devolvern ningn resultado cuando se usen con un valor NULL. Cualquiera que sea el valor de la opcin set ansinull , los siguientes operadores nunca devolvern valores cuando se utilicen con NULL: <, <=, !<, >, >=, !>. SQL Server puede determinar si un valor de columna es NULL. As: column1 = NULL puede considerarse verdadero. Sin embargo, la comparacin: where column1 > null

Page 34 of 280

nunca puede determinarse, ya que NULL significa "tener valor desconocido". No hay ningn motivo para suponer que dos valores desconocidos son iguales. Esta lgica es tambin aplicable cuando se usan dos nombres de columnas en una clusula where , es decir, cuando se combinan dos tablas. Una clusula como "where column1 = column2" nunca devuelve filas en las que las columnas contengan valores nulos. Tambin puede buscar valores nulos o valores no nulos en la base de datos con este patrn: where column_name is [not] null

Si trata de buscar valores nulos en columnas definidas como NOT NULL, SQL Server muestra un mensaje de error. Algunas de las filas de la tabla titles contienen datos incompletos. Por ejemplo, se ha propuesto un libro titulado The Psychology of Computer Cooking y se han introducido su ttulo, nmero de identificacin de ttulo y editor probable. Sin embargo, dado que el autor todava no tiene un contrato como tal y an hay algunos detalles por determinar, aparecen valores nulos en las columnas price , advance , royalty , total_sales y notes . Como los valores nulos no coinciden con nada en una comparacin, una consulta para todos los nmeros de identificacin de ttulos y los anticipos por libros con anticipos moderados (inferiores a $5000) no encontrar la fila de The Psychology of Computer Cooking que tiene el nmero de identificacin MC3026. select title_id, advance from titles where advance < $5000 title_id advance ---------- -------MC2222 0.00 PS2091 2,275.00 PS3333 2,000.00 PS7777 4,000.00 TC4203 4,000.00 (5 rows affected) A continuacin se muestra una consulta para libros que tengan un anticipo inferior a $5000 o un valor nulo en la columna advance : select title_id, advance from titles where advance < $5000 or advance is null title_id advance ---------- -------MC2222 0.00 MC3026 NULL PC9999 NULL PS2091 2,275.00 PS3333 2,000.00 PS7777 4,000.00 TC4203 4,000.00 (7 rows affected) Consulte el Captulo 7, "Creacin de bases de datos y tablas", para obtener informacin sobre NULL en la instruccin create table , y sobre la relacin existente entre NULL y los valores predeterminados. Consulte el Captulo 8, "Adicin, modificacin y eliminacin de datos", para obtener informacin sobre la insercin de valores nulos en una tabla. Consulte la seccin sobre valores nulos del Manual de Referencia de SQL Server para obtener ms informacin al respecto. Conexin de condiciones con operadores lgicos Los operadores lgicos and , or y not se utilizan para conectar condiciones de bsqueda en las clusulas where . and combina dos o ms condiciones y devuelve resultados slo cuando todas las condiciones se cumplen. Por ejemplo, la siguiente consulta busca slo las filas en las que el apellido del autor es Ringer y el nombre es Anne. No encontrar la fila correspondiente a Albert Ringer.

Page 35 of 280

select * from authors where au_lname = 'Ringer' and au_fname = 'Anne' or tambin conecta dos o ms condiciones, pero devuelve resultados cuando se cumple cualquiera de las condiciones. La siguiente consulta busca filas que contengan Anne o Ann en la columna au_fname. select * from authors where au_fname = 'Anne' or au_fname = 'Ann' not niega la expresin a la que precede. La siguiente consulta selecciona todos los autores que no viven en California: select * from authors where not state = "CA" Precedencia de los operadores lgicos Los operadores aritmticos y basados en bits se evalan antes que los lgicos. Cuando se usa ms de un operador lgico en una instruccin, not se evala primero, luego and , y, por ltimo, or . Consulte el Manual de Referencia de SQL Server para obtener informacin sobre los operadores basados en bits. Por ejemplo, la siguiente consulta busca todos los libros de negocios de la tabla titles, independientemente de sus anticipos, as como todos los libros de psicologa cuyo anticipo sea superior a $5500. La condicin del anticipo corresponde a libros de psicologa y no de negocios porque el operador and se evala antes que el operador or . select title_id, type, advance from titles where type = "business" or type = "psychology" and advance >5500 title_id type advance ---------- -----------------BU1032 BU1111 BU2075 BU7832 PS1372 PS2106 business business business business psychology psychology 5,000.00 5,000.00 10,125.00 5,000.00 7,000.00 6,000.00

(6 rows affected) Es posible cambiar el significado de la consulta aadiendo parntesis para forzar la evaluacin de or en primer lugar. Esta consulta encuentra todos los libros de negocios y de psicologa cuyo avance sea superior a $5500: select title_id, type, advance from titles where (type = "business" or type = "psychology") and advance >5500 title_id type advance -------- -----------------BU2075 business 10,125.00 PS1372 psychology 7,000.00 PS2106 psychology 6,000.00 (3 rows affected) Chapter 3

Cmo resumir, agrupar y ordenar resultados de consultas


Los resultados de consultas se pueden resumir, agrupar y ordenar utilizando funciones agregadas y las clusulas group by , having y order by con la instruccin select . Tambin se puede usar la clusula compute (una extensin Transact-SQL) con funciones agregadas para generar un informe con filas detalladas y resumidas. El operador union permite combinar los resultados de las consultas.
Page 36 of 280

En este captulo se trata lo siguiente:

Cmo resumir resultados de consultas mediante funciones agregadas Organizacin de resultados de consultas en grupos Seleccin de grupos de datos Ordenacin de resultados de consultas Cmo resumir grupos de datos Combinacin de resultados de consultas

Si el SQL Server que utiliza no distingue maysculas de minsculas, consulte group by y compute en el Manual de Referencia de SQL Server para obtener ejemplos de cmo la distincin entre maysculas y minsculas afecta a los datos devueltos por estas clusulas. Cmo resumir resultados de consultas mediante funciones agregadas Organizacin de resultados de consultas en grupos: la clusula group by Seleccin de grupos de datos: la clusula having Ordenacin de resultados de consultas: la clusula order by Cmo resumir grupos de datos: la clusula compute Combinacin de consultas: el operador union

Cmo resumir resultados de consultas mediante funciones agregadas Las funciones agregadas calculan valores sumarios a partir de datos de una columna concreta. Las funciones agregadas pueden aplicarse a todas las filas de una tabla, a un subconjunto de la tabla especificada por una clusula where o a uno o ms grupos de filas de la tabla. De cada conjunto de filas al que se aplica una funcin agregada se genera un solo valor. Este ejemplo calcula la suma de ventas anuales hasta la fecha para todos los libros de la tabla titles : select sum(total_sales) from titles ------------97446 (1 row affected) Observe que para utilizar las funciones agregadas hay que proporcionar el nombre de la funcin seguido del nombre de la columna cuyos valores sern objeto de la funcin. Incluya el nombre de columna, que es el argumento de la funcin, entre parntesis. Esta es la sintaxis general de las funciones agregadas: aggregate_function ([all|distinct] expression)

Los operadores agregados son sum , avg , max , min , count y count(*) . La palabra clave opcional distinct puede utilizarse con sum , avg y count para eliminar valores duplicados antes de aplicar la funcin agregada. No se permite el uso de distinct con max , min ni count (*). Para sum , avg y count , el valor predeterminado es all , que realiza la operacin en todas las filas. La palabra clave all es opcional. La "expresin" a la que hace referencia la instruccin de sintaxis es generalmente un nombre de columna. Tambin puede ser una constante, una funcin o cualquier combinacin de nombres de columna, constantes y funciones conectadas por operadores aritmticos o basados en bits. Una expresin tambin puede ser una subconsulta. Por ejemplo, podra calcular el precio promedio de todos los libros si se duplicaran los precios con esta instruccin: select avg(price * 2) from titles ------------29.53
Page 37 of 280

(1 row affected) La sintaxis y los resultados de las funciones agregadas son: Tabla 3-1: Sintaxis y resultados de las funciones agregadas Funcin agregada sum([all | distinct] expression ) avg([all | distinct] expression ) count(*) max( expression ) min( expression ) Resultado Total de los valores (distintos) de la expresin Promedio de los valores (distintos) de la expresin Nmero de filas seleccionadas Valor mximo de la expresin Valor mnimo de la expresin

count([all | distinct] expression ) Nmero de valores (distintos) no nulos de la expresin

Las funciones agregadas pueden utilizarse en una lista de seleccin, como en los ejemplos anteriores, o en la clusula having de una instruccin select que incluya una clusula group by . Para obtener informacin sobre la clusula having , consulte "Seleccin de grupos de datos: la clusula having". Las funciones agregadas no pueden utilizarse en una clusula where . Sin embargo, una instruccin select con funciones agregadas en su lista de seleccin incluye con frecuencia una clusula where que restringe las filas a las que se aplica la funcin agregada. En los ejemplos anteriores, cada funcin agregada generaba un solo valor sumario para toda la tabla. Si una instruccin select incluye una clusula where , pero no una clusula group by , una funcin agregada genera un solo valor para el subconjunto de filas especificado por la clusula where . Sin embargo, select tambin puede incluir una columna en su lista de seleccin (una extensin Transact-SQL), que repetira el valor nico para cada fila en la tabla de resultados. En ese caso, es posible calificar las filas con la clusula having , que se describe en "Seleccin de grupos de datos: la clusula having". Esta consulta devuelve el promedio de anticipos y la suma de ventas anuales hasta la fecha slo para libros de negocios: select avg(advance), sum(total_sales) from titles where type = "business" ------------- --------6,281.25 30788 (1 row affected) Cuando una funcin agregada se utiliza en una instruccin select que no incluye una clusula group by , se genera un solo valor. Esto se cumple tanto si la funcin se aplica a todas las filas de una tabla o a un subconjunto de filas definidas por una clusula where . En este caso, el valor se denomina agregado escalar . Observe que puede utilizar ms de una funcin agregada en la misma lista de seleccin y generar ms de un agregado escalar en una sola instruccin select . Funciones agregadas y tipos de datos sum y avg slo pueden utilizarse con columnas numricas: int , smallint , tinyint, decimal, numeric, float y money . min y max no pueden usarse con tipos de datos bit . Las funciones agregadas distintas de count(*) no pueden utilizarse con los tipos de datos text e image . Con estas excepciones, las funciones agregadas pueden utilizarse con cualquier tipo de columna. Por ejemplo, puede emplear min (mnimo) para hallar el valor mnimo (el ms cercano al principio del alfabeto) de una columna de tipo de caracteres: select min(au_lname) from authors
Page 38 of 280

-------------------------Bennet (1 row affected) Uso de count (* ) count(*) no requiere ninguna expresin como argumento porque, por definicin, no emplea informacin sobre ninguna columna concreta. count(*) se utiliza para hallar el nmero total de filas de una tabla. Esta instruccin halla el nmero total de libros: select count(*) from titles -----------------18 (1 row affected) count(*) devuelve el nmero de filas de la tabla especificada sin eliminar las duplicadas. Cuenta cada fila de forma independiente, incluidas las que contienen valores nulos. Al igual que otras funciones agregadas, count(*) puede combinarse con otros agregados en la lista de seleccin, con clusulas where , etc.: select count(*), avg(price) from titles where advance > 1000 ---------- --------15 14.42 (1 row affected) Uso de funciones agregadas con distinct La palabra clave distinct es opcional con sum , avg y count , y no se permite con min , max ni count(*) . Cuando se utiliza distinct , los valores duplicados se eliminan antes de calcular la suma, el promedio o el conteo. Si utiliza distinct , el argumento no puede incluir una expresin aritmtica, slo debe componerse de un nombre de columna. Cuando se utiliza distinct , esta palabra clave aparece entre parntesis y antes del nombre de la columna. Por ejemplo, para hallar el nmero de ciudades diferentes en las que hay autores, escriba: select count(distinct city) from authors ------------16 (1 row affected) La siguiente instruccin devuelve el promedio de los distintos precios de los libros de negocios: select avg(distinct price) from titles where type = "business" ------------11.64 (1 row affected) Si hay dos o ms libros con el mismo precio y utiliza la palabra clave distinct , el precio compartido se incluye slo una vez en el clculo. Para obtener un clculo exacto del precio promedio de los libros de negocios, tendra que omitir distinct : select avg(price) from titles where type = "business"
Page 39 of 280

------------13.73 (1 row affected) Valores nulos y funciones agregadas Los valores nulos de las columnas donde se aplica la funcin agregada se ignoran para fines de la funcin. Si se defini ansinull como on , SQL Server mostrar un mensaje de error cada vez que se ignore un valor nulo. Para obtener ms informacin, consulte el comando set en el Manual de Referencia de SQL Server . Si todos los valores de una columna son nulos, count ( column_name ) devuelve cero. Por ejemplo, si solicita el conteo ( count ) de los anticipos de la tabla titles , la respuesta no ser la misma que si solicita el conteo de los nombres de ttulos, debido a los valores nulos de la columna advance : select count(advance) from titles ------------16 (1 row affected) select count(title) from titles ------------18 (1 row affected) La excepcin a esta regla es count(*) , que cuenta cada fila, aunque cada campo de la misma sea nulo (NULL). Si ninguna fila cumple las condiciones especificadas en la clusula where , count devolver un valor de cero. Todas las dems funciones devuelven NULL. A continuacin se muestran unos ejemplos: select count(distinct title) from titles where type = "poetry" ------------0 (1 row affected) select avg(advance) from titles where type = "poetry" ------------NULL (1 row affected)

Organizacin de resultados de consultas en grupos: la clusula group by La clusula group by se utiliza en las instrucciones select para dividir la salida de una tabla en grupos. Puede formar grupos segn uno o varios nombres de columna, o segn los resultados de las columnas calculadas utilizando tipos de datos numricos en una expresin. Para group by , el nmero mximo de columnas o expresiones es 16. Note: No es posible formar grupos por columnas con tipos de datos text o image . La clusula group by aparece casi siempre en instrucciones que tambin incluyen funciones agregadas, en cuyo caso el agregado genera un valor para cada grupo. A estos valores se les llama agregados vectoriales . No hay que olvidar que un agregado escalar es un solo valor generado por una funcin agregada sin una clusula group by . En este ejemplo de un agregado vectorial, la instruccin halla el promedio de anticipo y la suma de ventas anuales hasta la fecha para cada tipo de libro:

Page 40 of 280

select type, avg(advance), sum(total_sales) from titles group by type type -------------------------UNDECIDED NULL NULL business 6,281.25 30788 mod_cook 7,500.00 24278 popular_comp 7,500.00 12875 psychology 4,255.00 9939 trad_cook 6,333.33 19566 (6 rows affected) Los valores sumarios (agregados vectoriales) generados por las instrucciones select con agregados y una clusula group by aparecen como columnas en cada fila de los resultados. Por el contrario, los valores sumarios (agregados escalares) generados por las instrucciones select con agregados y sin clusulas group by tambin aparecen como columnas, pero slo en una fila. Por ejemplo: select avg(advance), sum(total_sales) from titles --------------5,962.50 97446 (1 row affected) Mientras sea posible utilizar group by sin agregados, dicha construccin tiene una funcionalidad muy limitada y algunas veces genera resultados confusos. El siguiente ejemplo intenta agrupar los resultados por tipo de ttulo: select type, advance from titles group by type type advance -------------------business 5,000.00 business 5,000.00 business 10,125.00 business 5,000.00 mod_cook 0.00 mod_cook 15,000.00 UNDECIDED NULL popular_comp 7,000.00 popular_comp 8,000.00 popular_comp NULL psychology 7,000.00 psychology 2,275.00 psychology 6,000.00 psychology 2,000.00 psychology 4,000.00 trad_cook 7,000.00 trad_cook 4,000.00 trad_cook 8,000.00 (18 rows affected) Sin un agregado para la columna advance , la consulta devuelve valores para cada fila de la tabla. Sintaxis de group by La sintaxis completa de la instruccin select se repite aqu para ilustrar la clusula group by en contexto: select [all | distinct] select_list [into [[ database .] owner .] table_name [from [[ database .] owner .]{ view_name [(index index_name [ prefetch size [holdlock | noholdlock] [shared] [,[[ database .] owner .]{ view_name [(index index_name [ prefetch size [holdlock | noholdlock] [shared]]... ]

] | table_name ][lru|mru])]} | table_name ][lru|mru])]}


Page 41 of 280

[where

search_conditions

[group by [all] aggregate_free_expression [, aggregate_free_expression ]... ] [having search_conditions ] [order by {[[[ database .] owner .]{ table_name .| view_name .}] column_name | select_list_number | expression [asc | desc] [,{[[[ database .] owner .]{ table_name | view_name .}] column_name | select_list_number | expression [asc | desc]]...] [compute row_aggregate ( column_name ) [, row_aggregate ( column_name )]... [by column_name [, column_name ]...]] [for {read only | update [of column_name_list ]}]

} }

[at isolation {read uncommitted | read committed | serializable}] [for browse] Recuerde que el orden de las clusulas en la instruccin select es importante. Se puede omitir cualquiera de las clusulas opcionales, pero cuando las utilice, deben aparecer en el orden mostrado aqu. Las normas SQL para group by son ms restrictivas de lo que parece en la sintaxis anterior. La norma exige que:

Las columnas de la lista de seleccin tambin deben aparecer en la expresin group by o ser argumentos de funciones agregadas. La expresin group by slo puede contener los nombres de columna especificados en la lista de seleccin, pero no los usados nicamente como argumentos de agregados vectoriales.

El resultado de una clusula group by estndar con funciones agregadas vectoriales es una fila y un valor sumario por grupo. Algunas extensiones Transact-SQL (descritas en las secciones siguientes) reducen estas restricciones, pero a costa de resultados ms complejos. Si prefiere no usar las extensiones, puede definir la opcin fipsflagger segn se indica a continuacin: set fipsflagger on Esta opcin muestra un mensaje de advertencia cada vez que se usan las extensiones Transact-SQL. Para obtener ms informacin sobre la opcin fipsflagger y el comando set , consulte el Manual de Referencia de SQL Server. Se puede incluir ms de una columna en la clusula group by a fin de anidar grupos, es decir, se puede agrupar una tabla mediante cualquier combinacin de columnas. Por ejemplo, a continuacin se muestra una instruccin que halla el precio promedio y la suma de las ventas anuales hasta la fecha, agrupados primero por nmero de ID del editor y luego por tipo: select pub_id, type, avg(price), sum(total_sales) from titles group by pub_id, type pub_id type ------ ------------ ------ ------0736 business 2.99 18722 0736 psychology 11.48 9564 0877 UNDECIDED NULL NULL 0877 mod_cook 11.49 24278 0877 psychology 21.59 375 0877 trad_cook 15.96 19566 1389 business 17.31 12066 1389 popular_comp 21.48 12875 (8 rows affected)

Page 42 of 280

Con group by , es posible anidar muchos grupos dentro de otros grupos, hasta un mximo de 16 columnas o expresiones especificadas. Referencia a otras columnas en consultas mediante group by Con las extensiones de las normas SQL, Transact-SQL no impone ninguna restriccin sobre lo que puede incluirse u omitirse en la lista de seleccin de una instruccin select que incluya la clusula group by : 1. 2. Las columnas de la lista de seleccin no se limitan a las columnas de agrupacin ni a columnas usadas con los agregados vectoriales. Las columnas especificadas por group by no se limitan a las columnas no agregadas de la lista de seleccin.

El agregado vectorial requiere que haya una o ms columnas en la clusula group by . Las normas SQL requieren que las columnas no agregadas de la lista de seleccin coincidan con las columnas de group by . Sin embargo, la primera extensin descrita con anterioridad permite especificar columnas "extendidas" adicionales en la lista de seleccin de la consulta. Por ejemplo, la inclusin de la columna extendida title_id en la lista de seleccin no se permitira en muchas versiones de SQL, pero es perfectamente vlida en Transact-SQL: select type, title_id, avg(price), avg(advance) from titles group by type type title_id ------------ -------- ----- --------business BU1032 13.73 6,281.25 business BU1111 13.73 6,281.25 business BU2075 13.73 6,281.25 business BU7832 13.73 6,281.25 mod_cook MC2222 11.49 7,500.00 mod_cook MC3021 11.49 7,500.00 UNDECIDED MC3026 NULL NULL popular_comp PC1035 21.48 7,500.00 popular_comp PC8888 21.48 7,500.00 popular_comp PC9999 21.48 7,500.00 psychology PS1372 13.50 4,255.00 psychology PS2091 13.50 4,255.00 psychology PS2106 13.50 4,255.00 psychology PS3333 13.50 4,255.00 psychology PS7777 13.50 4,255.00 trad_cook TC3218 15.96 6,333.33 trad_cook TC4203 15.96 6,333.33 trad_cook TC7777 15.96 6,333.33 (18 rows affected) El ejemplo anterior todava agrega las columnas price y advance , segn la columna type , pero sus resultados tambin muestran el nmero de ID del ttulo ( title_id ) de los libros incluidos en cada grupo. La segunda extensin descrita anteriormente permite agrupar columnas que no estn especificadas como tal en la lista de seleccin de la consulta. Estas columnas no aparecen en los resultados, pero los agregados vectoriales calculan sus valores sumarios. Por ejemplo: select state, count(au_id) from authors group by state, city state ----- -------AU 1 CA 2 CA 1 CA 5 CA 2 CA 1 CA 1 CA 1 CA 1
Page 43 of 280

IN KS MD MI OR TN UT

1 1 1 1 1 1 2

(16 rows affected) Este ejemplo agrupa los resultados de los agregados vectoriales por state y city , aunque no muestre qu ciudad pertenece a cada grupo. Como puede ver, los resultados de las consultas usadas con estas extensiones son ms complejos. Para realizar estas consultas, es necesario estar familiarizado con la forma en que SQL Server trata estas extensiones para poder entender los resultados. Por ejemplo, puede suponerse que la siguiente consulta generar resultados similares a los de la consulta anterior, ya que parece que slo el agregado vectorial registra el nmero de cada ciudad correspondiente a cada fila: select state, count(au_id) from authors group by city Sin embargo, sus resultados son muy distintos (y engaosos). Al no usar group by con ambas columnas ( state y city ), la consulta lleva la cuenta de cada ciudad, pero muestra la cuenta de cada fila de esa ciudad en authors en lugar de agruparla en una nica fila de resultados por ciudad. Cuando se usan las extensiones Transact-SQL en consultas complejas que incluyen la clusula where o combinaciones, los resultados pueden ser todava ms difciles de entender. Para evitar resultados confusos o engaosos con group by , no utilice la extensin con ligereza. Emplee la opcin fipsflagger (consulte la ) para identificar las consultas que usan estas extensiones. Para obtener ms informacin sobre estas extensiones Transact-SQL de group by y la forma en que funcionan, consulte el Manual de Referencia de SQL Server . Expresiones y group by Otra extensin Transact-SQL para SQL permite agrupar por expresiones que no incluyan funciones agregadas. Con SQL estndar slo es posible realizar agrupaciones por nombres de columna. Por ejemplo: select avg(total_sales), total_sales * price from titles group by total_sales * price ------------------------111 777.00 375 7,856.25 375 8,096.25 2045 22,392.75 3336 26,654.64 2032 40,619.68 3876 46,318.20 18722 55,978.78 4095 61,384.05 22246 66,515.54 4072 81,399.28 4095 81,859.05 4095 81,900.00 15096 180,397.20 8780 201,501.00 (15 rows affected) No es posible agrupar ( group by) por encabezados de columna ni alias , aunque pueden utilizarse alias en la lista de seleccin. Esta instruccin genera un mensaje de error: select Category = type, title_id, avg(price), avg(advance) from titles group by Category /* Uso incorrecto del encabezado ** de columna */
Page 44 of 280

Use group by type para corregir esta consulta. Anidacin de agregados mediante group by Otro tipo de anidacin, la anidacin de un agregado vectorial dentro de otro escalar, es una extensin Transact-SQL. Por ejemplo, para hallar el precio promedio de todos los tipos de libros, la consulta es: select avg(price) from titles group by type --------------NULL 13.73 11.49 21.48 13.50 15.96 (6 rows affected) El precio promedio mximo de un grupo de libros, agrupado por tipo, se puede establecer en una sola consulta anidando el precio promedio dentro la funcin max : select max(avg(price)) from titles group by type ------------21.48 (1 row affected) Por definicin, la clusula group by se aplica al agregado ms interno, que, en este caso, es avg . Valores nulos y group by Si la columna de agrupacin contiene un valor nulo, la fila pertinente se convierte en un grupo en los resultados. Si la columna de agrupacin contiene ms de un valor nulo, los valores nulos se ponen en un solo grupo. La columna advance de la tabla titles contiene algunos valores nulos. A continuacin se muestra un ejemplo que utiliza group by y la columna advance : select advance, avg(price * 2) from titles group by advance advance ------------------ ----------------NULL NULL 0.00 39.98 2,000.00 39.98 2,275.00 21.90 4,000.00 19.94 5,000.00 34.62 6,000.00 14.00 7,000.00 43.66 8,000.00 34.99 10,125.00 5.98 15,000.00 5.98 (11 rows affected) Si utiliza la funcin agregada count( column_name ) , la agrupacin por una columna que contenga valores nulos devolver un conteo de cero para la fila de agrupacin, ya que count( column_name ) no cuenta valores nulos. En la mayora de los casos, conviene utilizar count(*) . Este ejemplo aplica la agrupacin y el conteo a la columna price de la tabla titles , que contiene valores nulos, y muestra count(*) a ttulo de la comparacin:

Page 45 of 280

select price, count(price), count(*) from titles group by price price ------------- ----- ----NULL 0 2 2.99 2 2 7.00 1 1 7.99 1 1 10.95 1 1 11.95 2 2 14.99 1 1 19.99 4 4 20.00 1 1 20.95 1 1 21.59 1 1 22.95 1 1 (12 rows affected) Clusula where y group by En una instruccin con group by se puede utilizar una clusula where . Las filas que no cumplen las condiciones de la clusula where se eliminan antes de que se realice la agrupacin. Por ejemplo: select type, avg(price) from titles where advance > 5000 group by type type -------------------business 2.99 mod_cook 2.99 popular_comp 21.48 psychology 14.30 trad_cook 17.97 (5 rows affected) Slo las filas con anticipos superiores a $5000 se incluyen en los grupos usados para generar resultados de consultas. Los valores son muy diferentes cuando la consulta se ejecuta sin la clusula where . Sin embargo, la forma en que SQL Server manipula las columnas adicionales de la lista de seleccin y la clusula where , puede parecer contradictoria. Por ejemplo: select type, advance, avg(price) from titles where advance > 5000 group by type type advance ------------- --------- -------business 5,000.00 2.99 business 5,000.00 2.99 business 10,125.00 2.99 business 5,000.00 2.99 mod_cook 0.00 2.99 mod_cook 15,000.00 2.99 popular_comp 7,000.00 21.48 popular_comp 8,000.00 21.48 popular_comp NULL 21.48 psychology 7,000.00 14.30 psychology 2,275.00 14.30 psychology 6,000.00 14.30 psychology 2,000.00 14.30 psychology 4,000.00 14.30 trad_cook 7,000.00 17.97 trad_cook 4,000.00 17.97 trad_cook 8,000.00 17.97 (17 rows affected)
Page 46 of 280

Al observar los resultados de la columna (extendida) advance , parece que la consulta est ignorando la clusula where . SQL Server calcula el agregado vectorial a partir de las filas que satisfacen la clusula where , pero tambin muestra todas las filas de las columnas extendidas incluidas en la lista de seleccin. Para restringir el nmero de filas incluidas en los resultados, es necesario usar una clusula having (descrita ms adelante en este captulo). Para obtener informacin sobre la forma en que SQL Server manipula la clusula where y group by , consulte el Manual de Referencia de SQL Server .

group by y all
La palabra clave all en la clusula group by es una mejora de Transact-SQL para SQL. Slo es significativa si la instruccin select en la que se utiliza tambin incluye una clusula where . Si utiliza all , los resultados de la consulta incluirn todos los grupos generados por la clusula group by , aunque algunos de los grupos no tengan filas que cumplan con las condiciones de bsqueda. Sin all , una instruccin select que incluya group by no mostrar los grupos que carecen de filas calificadas. A continuacin se muestra un ejemplo: select type, avg(advance) from titles where advance > 1000 and advance < 10000 group by type type ------------ -----------------------business 5,000.00 popular_comp 7,500.00 psychology 4,255.00 trad_cook 6,333.33 (4 rows affected) select type, avg(advance) from titles where advance > 1000 and advance < 10000 group by all type type ------------ -----------------------UNDECIDED NULL business 5,000.00 mod_cook NULL popular_comp 7,500.00 psychology 4,255.00 trad_cook 6,333.33 (6 rows affected) La primera instruccin slo genera grupos para libros con anticipos superiores a $1000, pero inferiores a $10000. Dado que no hay ningn libro de cocina con un anticipo dentro de dicho margen, los resultados no muestran ningn grupo para el tipo mod_cook . La segunda instruccin genera grupos para todos los tipos, incluidos cocina moderna y "UNDECIDED", aunque el grupo de cocina moderna no incluya ninguna fila que cumpla con la calificacin especificada en la clusula where . SQL Server devuelve un valor NULL para dichas filas. La columna que contiene el valor agregado (el promedio de anticipos) es para los grupos que carecen de filas calificadas. Uso de agregados sin group by Por definicin, los agregados escalares se aplican a todas las filas de una tabla, generando un solo valor para toda la tabla, para cada funcin. La extensin Transact-SQL, que permite incluir columnas extendidas con agregados vectoriales, tambin lo permite con agregados escalares. Por ejemplo: select pub_id, count(pub_id) from publishers pub_id ---------- --------Page 47 of 280

0736 0877 1389 (3 rows affected)

3 3 3

SQL Server trata publishers como un grupo nico y el agregado escalar se aplica a la tabla (grupo nico). Los resultados muestran todas las filas de la tabla correspondientes a las columnas incluidas en la lista de seleccin en adicin al agregado escalar. La clusula where acta de la misma forma tanto para los agregados escalares como para los vectoriales. where restringe las columnas incluidas en los valores sumarios agregados, pero no tiene efecto sobre las filas que aparecen en los resultados para cada columna extendida especificada en la lista de seleccin. Por ejemplo: select pub_id, count(pub_id) from publishers where pub_id < "1000" pub_id -------------- ----------0736 2 0877 2 1389 2 (3 rows affected) Al igual que las dems extensiones Transact-SQL de group by , esta extensin de los agregados escalares proporciona resultados que pueden ser difciles de entender, sobre todo si se trata de consultas a tablas grandes o con combinaciones de varias tablas. Seleccin de grupos de datos: la clusula having La clusula having establece condiciones para la clusula group by similares al modo en que where establece condiciones para la clusula select . Las condiciones de bsqueda de having son idnticas a las de where , con una excepcin: las condiciones de bsqueda de where no pueden incluir agregados, mientras que las de having lo hacen a menudo. Las clusulas having pueden hacer referencia a cualquiera de los elementos que aparecen en la lista de seleccin. Existe un lmite de 128 condiciones que pueden incluirse en una clusula having . Esta instruccin es un ejemplo de una clusula having con una funcin agregada. Agrupa las filas de la tabla titles por tipo, pero elimina los grupos que slo incluyen un libro: select type from titles group by type having count(*) > 1 type ---------------business mod_cook popular_comp psychology trad_cook (5 rows affected) A continuacin se muestra un ejemplo de una clusula having sin agregados. Agrupa la tabla titles por tipo y elimina los tipos que no empiezan por la letra "p": select type from titles group by type having type like 'p%' type -----------popular_comp psychology
Page 48 of 280

(2 rows affected) Cuando se incluyen varias condiciones en la clusula having , stas se combinan con and , or o not . Por ejemplo, para agrupar la tabla titles por editor e incluir slo aquellos editores con nmeros de identificacin mayores que 0800, que han pagado ms de $15000 en anticipos totales y cuyos libros dan un promedio inferior a $18 en precio, la instruccin es: select pub_id, sum(advance), avg(price) from titles group by pub_id having sum(advance) > 15000 and avg(price) < 18 and pub_id > "0800" pub_id ------ ---------------- ---------------0877 41,000.00 15.41 (1 row affected) Interactuacin entre las clusulas having , group by y where Cuando se incluyen las clusulas having , group by y where en una consulta, la secuencia en que cada clusula afecta a las filas de la tabla es importante en la determinacin de los resultados finales:

La clusula where excluye las filas que no cumplen con sus condiciones de bsqueda. La clusula group by incluye las filas restantes en un grupo para cada valor nico de la expresin group by . Las funciones agregadas especificadas en la lista de seleccin calculan valores sumarios para cada grupo. La clusula having excluye de los resultados finales las filas que no cumplen con sus condiciones de bsqueda.

La siguiente consulta ilustra el uso de las clusulas where , group by y having en una instruccin select : select stor_id, title_id, sum(qty) from salesdetail where title_id like "PS%" group by stor_id, title_id having sum(qty) > 200 stor_id title_id ------- -------- ----------5023 PS1372 375 5023 PS2091 1845 5023 PS3333 3437 5023 PS7777 2206 6380 PS7777 500 7067 PS3333 345 7067 PS7777 250 (7 rows affected) La clusula where incluye slo las filas cuya title_id comience por "PS" (libros de psicologa), antes de que group by rena las filas con stor_id y title_id comunes. El agregado sum calcula el nmero total de libros vendidos para cada grupo y, a continuacin, la clusula having excluye de los resultados finales los grupo cuyos totales no sobrepasan los 200 libros. Todos los ejemplos anteriores de having satisfacen las normas SQL, que especifican que las columnas de una expresin having deben tener un solo valor y encontrarse en la lista de seleccin o la clusula group by . Sin embargo, las extensiones Transact-SQL para having permiten columnas o expresiones que no estn en la lista de seleccin ni en la clusula group by . El siguiente ejemplo utiliza esta extensin. Calcula el precio promedio para cada tipo de ttulo, pero excluye los tipos cuyas ventas totales no son superiores a 10000, aunque la funcin sum no aparezca en los resultados. select type, avg(price) from titles group by type having sum(total_sales) > 10000 type ------------ ---------business 13.73
Page 49 of 280

mod_cook popular_comp trad_cook (4 rows affected)

11.49 21.48 15.96

La extensin acta como si la columna o expresin formara parte de la lista de seleccin, pero no de los resultados mostrados. Si se incluye una columna no agregada con having , pero la columna no forma parte de la lista de seleccin ni de la clusula group by , la consulta genera resultados similares a la extensin de columna "extendida" descrita anteriormente en este captulo. Por ejemplo: select type, avg(price) from titles group by type having total_sales > 4000 type ------------ ---------business 13.73 business 13.73 business 13.73 mod_cook 11.49 popular_comp 21.48 popular_comp 21.48 psychology 13.50 trad_cook 15.96 trad_cook 15.96 (9 rows affected) A diferencia de la columna extendida, la columna total_sales no aparece en los resultados finales, aunque el nmero de filas mostradas para cada tipo depende de las ventas totales ( total_sales ) de cada ttulo. La consulta indica que 3 ttulos de business , 1 de mod_cook , 2 de popular_comp , 1 de psychology y 2 de trad_cook han tenido ventas totales superiores a 4000. Como se indic anteriormente, la forma en que SQL Server manipula las columnas extendidas puede hacer creer que la consulta est ignorando la clusula where en los resultados finales. Para que las condiciones de where tengan efecto sobre los resultados de la columna extendida, es necesario repetir las condiciones en la clusula having . Por ejemplo: select type, advance, avg(price) from titles where advance > 5000 group by type having advance > 5000 type advance ------------- --------- -------business 10,125.00 2.99 mod_cook 15,000.00 2.99 popular_comp 7,000.00 21.48 popular_comp 8,000.00 21.48 psychology 7,000.00 14.30 psychology 6,000.00 14.30 trad_cook 7,000.00 17.97 trad_cook 8,000.00 17.97 (8 rows affected) Uso de having sin group by Una consulta con una clusula having tambin debe tener una clusula group by . Si sta se omite, todas las filas no excluidas por la clusula where se consideran un solo grupo. Dado que no hay ninguna agrupacin entre las clusulas where y having , no pueden actuar independientemente una de la otra. having acta como where porque afecta a las filas de un solo grupo en lugar de varios grupos, salvo que la clusula having todava puede utilizar agregados. El siguiente ejemplo utiliza la clusula having para excluir de los resultados las filas de la tabla titles (grupo nico) cuyos precios no sobrepasen el precio promedio de todos los ttulos, despus de que la clusula where excluya los ttulos con anticipo superior a $4000 del clculo del precio promedio:
Page 50 of 280

select title_id, advance, price from titles where advance < 4000 having price > avg(price) title_id advance price ------------- --------- -------BU1032 5,000.00 19.99 BU7832 5,000.00 19.99 MC2222 0.00 19.99 PC1035 7,000.00 22.95 PC8888 8,000.00 20.00 PS1372 7,000.00 21.59 PS3333 2,000.00 19.99 TC3218 7,000.00 20.95 (8 rows affected) Tambin puede usar la clusula having con la extensin Transact-SQL que permite omitir la clusula group by de una consulta que incluye un agregado en su lista de seleccin. Estas funciones agregadas escalares calculan los valores para la tabla como un grupo nico, no para grupos de la tabla. En este ejemplo, la omisin de la clusula group by hace que la funcin agregada calcule un valor para toda la tabla. La clusula having excluye filas del grupo de resultados, filas de la tabla nica. select pub_id, count(pub_id) from publishers having pub_id < "1000" pub_id ------ ---------------0736 3 0877 3 (2 rows affected) Para obtener ms informacin sobre las consultas que utilizan having pero omiten group by , consulte el Manual de

Referencia de SQL Server.

Ordenacin de resultados de consultas: la clusula order by La clusula order by permite la ordenacin de resultados de consultas por una o ms columnas. El nmero mximo de columnas es 16. Cada ordenacin puede ser ascendente ( asc ) o descendente ( desc ). Si no se especifica ninguna, se utiliza la ascendente. La siguiente consulta devuelve resultados ordenados por pub_id : select pub_id, type, title_id from titles order by pub_id pub_id type title_id ------ ------------------0736 business BU2075 0736 psychology PS2091 0736 psychology PS2106 0736 psychology PS3333 0736 psychology PS7777 0877 UNDECIDED MC3026 0877 mod_cook MC2222 0877 mod_cook MC3021 0877 psychology PS1372 0877 trad_cook TC3218 0877 trad_cook TC4203 0877 trad_cook TC7777 1389 business BU1032 1389 business BU1111 1389 business BU7832 1389 popular_comp PC1035 1389 popular_comp PC8888 1389 popular_comp PC9999 (18 rows affected)
Page 51 of 280

Si se indica ms de una columna en la clusula order by , las ordenaciones quedan anidadas. La siguiente instruccin ordena las filas de la tabla titles primero por editor en orden descendente, despus por tipo (ascendente) dentro de cada editor y, finalmente, por nmero de ttulo (tambin ascendente, puesto que no se ha especificado desc). Los valores nulos se ordenan en primer lugar dentro de cualquier grupo. select pub_id, type, title_id from titles order by pub_id desc, type, title_id pub_id type title_id ---------------------1389 business BU1032 1389 business BU1111 1389 business BU7832 1389 popular_comp PC1035 1389 popular_comp PC8888 1389 popular_comp PC9999 0877 UNDECIDED MC3026 0877 mod_cook MC2222 0877 mod_cook MC3021 0877 psychology PS1372 0877 trad_cook TC3218 0877 trad_cook TC4203 0877 trad_cook TC7777 0736 business BU2075 0736 psychology PS2091 0736 psychology PS2106 0736 psychology PS3333 0736 psychology PS7777 (18 rows affected) El nmero de posicin de una columna en una lista de seleccin puede utilizarse en lugar del nombre de la columna. Los nombres de columnas y los nmeros de lista pueden mezclarse. Las siguientes instrucciones generan los mismos resultados que la anterior. select pub_id, type, title_id from titles order by 1 desc, 2, 3 select pub_id, type, title_id from titles order by 1 desc, type, 3 La mayora de las versiones de SQL requieren que los elementos de order by aparezcan en la lista de seleccin, pero TransactSQL no tiene esta restriccin. Los resultados de la consulta anterior podran ordenarse por title , aunque esta columna no aparezca en la lista de seleccin. Note: No es posible usar order by con columnas text o image . Las subconsultas, agregados, variables y expresiones constantes no se permiten en la lista order by . Los efectos de una clusula order by en datos con maysculas y minsculas mezcladas dependen del criterio de ordenacin instalado en SQL Server. Las opciones bsicas son binario, orden de diccionario y sin distincin de maysculas y minsculas. El procedimiento del sistema sp_helpsort muestra el criterio de ordenacin del servidor. Consulte order by en el Manual de Referencia de SQL Server para obtener informacin completa sobre los criterios de ordenacin.

order by y group by
Cuando desee ordenar los resultados de una clusula group by de un modo concreto, puede utilizar una clusula order by . Site la clusula order by despus de la clusula group by . Por ejemplo, para hallar el precio promedio de cada tipo de libro y ordenar los resultados por precio promedio, la instruccin es: select type, avg(price) from titles group by type order by avg(price)
Page 52 of 280

type ---------- -----------UNDECIDED NULL mod_cook 11.49 psychology 13.50 business 13.73 trad_cook 15.96 popular_comp 21.48 (6 rows affected) Cmo resumir grupos de datos: la clusula compute La clusula compute es una extensin Transact-SQL de SQL. Utilcela con agregados de fila para generar informes que totalicen valores siempre que cambie el valor de una columna especificada. Tales informes, normalmente creados por un generador de informes, se llaman informes de cortes de control, ya que los valores sumarios aparecen en el informe, bajo el control de las agrupaciones ("cortes") especificadas en la clusula compute . Estos valores sumarios aparecen como filas adicionales en los resultados de consultas, a diferencia de los resultados agregados de una clusula group by , que aparecen como columnas nuevas. Una clusula compute permite ver las filas detalladas y resumidas con una instruccin select . Es posible calcular valores sumarios para subgrupos y calcular ms de un agregado de fila para el mismo grupo. Esta es la sintaxis general de compute : compute row_aggregate ( column_name ) [, row_aggregate ( column_name )]... [by column_name [, column_name ]...] Los agregados de fila que pueden utilizarse con compute son sum , avg , min , max y count . sum y avg slo se emplean con columnas numricas. A diferencia de la clusula order by , no es posible usar el nmero de posicin de una columna de la lista de seleccin en lugar del nombre de la columna. Note: No se pueden utilizar columnas text o image en una clusula compute . A continuacin se muestran dos consultas y sus resultados. La primera utiliza group by y agregados. La segunda utiliza compute y agregados de fila. Observe las diferencias: select type, sum(price), sum(advance) from titles group by type type --------------------------UNDECIDED NULL NULL business 54.92 25,125.00 mod_cook 22.98 15,000.00 popular_comp 42.95 15,000.00 psychology 67.52 21,275.00 trad_cook 47.89 19,000.00 (6 rows affected) select type, price, advance from titles order by type compute sum(price), sum(advance) by type type price advance --------------------------------UNDECIDED NULL NULL sum sum --------------------NULL NULL type price advance --------------------------------business 2.99 10,125.00 business 11.95 5,000.00 business 19.99 5,000.00 business 19.99 5,000.00
Page 53 of 280

sum -----------54.92 type price -----------------------mod_cook 2.99 mod_cook 19.99 sum -----------22.98 type price -----------------------popular_comp NULL popular_comp 20.00 popular_comp 22.95 sum -----------42.95 type price -----------------------psychology 7.00 psychology 7.99 psychology 10.95 psychology 19.99 psychology 21.59 sum -----------67.52 type price -----------------------trad_cook 11.95 trad_cook 14.99 trad_cook 20.95 sum -----------47.89 (24 rows affected)

sum --------25,125.00 advance --------15,000.00 0.00 sum --------15,000.00 advance --------NULL 8,000.00 7,000.00 sum --------15,000.00 advance --------6,000.00 4,000.00 2,275.00 2,000.00 7,000.00 sum --------21,275.00 advance --------4,000.00 8,000.00 7,000.00 sum --------19,000.00

Los valores sumarios se tratan como filas nuevas, razn por la cual el mensaje de SQL Server dice "24 rows affected". Agregados de fila y compute Los agregados de fila usados con compute se enumeran en la siguiente tabla: Tabla 3-2: Agregados de fila usados con instrucciones compute Agregado de fila sum avg max min count Resultado Total de los valores de la expresin Promedio de los valores de la expresin Valor mximo de la expresin Valor mnimo de la expresin Nmero de filas seleccionadas

Estos agregados de fila son los mismos agregados que pueden utilizarse con group by , excepto que no hay ninguna funcin agregada de fila que equivalga a count(*) . Para obtener la informacin sumaria generada por group by y count(*) , emplee una clusula compute sin by . Reglas para las clusulas compute

La palabra clave distinct no est permitida con los agregados de fila. Las columnas de la clusula compute deben aparecer en la lista de seleccin de la instruccin. No es posible utilizar select into en la misma instruccin que una clusula compute porque las instrucciones que incluyen compute no generan filas normales. Si utiliza compute con la palabra clave by , tambin deber usar una clusula order by . Las columnas mostradas despus de by deben ser idnticas a, o un subconjunto de, las que aparecen despus de order by , y adems estar
Page 54 of 280

en el mismo orden de izquierda a derecha, empezar con la misma expresin y no omitir ninguna expresin. Por ejemplo, suponga que sta es la clusula order by : order by a, b , c

La clusula compute puede ser cualquiera o todas las que aparecen a continuacin: compute compute compute row_aggregate row_aggregate row_aggregate ( ( ( column_name column_name column_name ) by ) by ) by a, b, c a, b a

La clusula compute no puede ser ninguna de las siguientes: compute compute compute row_aggregate row_aggregate row_aggregate ( ( ( column_name column_name column_name ) by ) by ) by b, c a, c c

Debe utilizar un nombre de columna o una expresin en la clusula order by ; no es posible ordenar por encabezado de columna.

La palabra clave compute puede utilizarse sin by para generar totales generales, conteos generales, etc.. order by es opcional si la palabra clave compute se usa sin by . compute sin by se explica ms adelante.

Especificacin de ms de una columna despus de compute La inclusin de ms de una columna despus de la palabra clave by divide un grupo en subgrupos y aplica el agregado de fila especificado en cada nivel de agrupacin. Por ejemplo, a continuacin se muestra una consulta que halla la suma de los precios de los libros de psicologa de cada editor: select type, pub_id, price from titles where type = "psychology" order by type, pub_id, price compute sum(price) by type, pub_id type pub_id price ----------- ------- ------------psychology 0736 7.00 psychology 0736 7.99 psychology 0736 10.95 psychology 0736 19.99 sum -----------45.93 type pub_id price ----------- ------- ------------psychology 0877 21.59 sum -----------21.59 (7 rows affected) Uso de ms de una clusula compute Se pueden utilizar agregados diferentes en la misma instruccin, incluyendo ms de una clusula compute . A continuacin se muestra una consulta similar a la anterior que halla la suma de los precios de todos los libros de psicologa, as como la suma de los precios de los libros de psicologa por editor: select type, pub_id, price from titles where type = "psychology" order by type, pub_id, price compute sum(price) by type, pub_id compute sum(price) by type type pub_id price ----------- ------- -------------Page 55 of 280

psychology psychology psychology psychology

0736 0736 0736 0736

7.00 7.99 10.95 19.99

sum ------------45.93 type pub_id price ---------- ------- -------------psychology 0877 21.59 sum ------------21.59 sum ------------67.52 (8 rows affected) Aplicacin de un agregado a ms de una columna Una clusula compute puede aplicar el mismo agregado a varias columnas. Esta consulta halla la suma de los precios y los anticipos para cada tipo de libro de cocina: select type, price, advance from titles where type like "%cook" order by type compute sum(price), sum(advance) by type type price advance --------- ---------------- --------------mod_cook 2.99 15,000.00 mod_cook 19.99 0.00 sum sum ---------------- --------------22.98 15,000.00 type price advance --------- ---------------- --------------trad_cook 11.95 4,000.00 trad_cook 14.99 8,000.00 trad_cook 20.95 7,000.00 sum sum ---------------- --------------47.89 19,000.00 (7 rows affected) No hay que olvidar que las columnas a las que se aplican los agregados tambin deben estar en la lista de seleccin. Uso de agregados diferentes en la misma clusula compute Se pueden utilizar agregados diferentes en la misma clusula compute : select type, pub_id, price from titles where type like "%cook" order by type, pub_id compute sum(price), max(pub_id) by type type pub_id price ----------- ------- -------------mod_cook 0877 2.99 mod_cook 0877 19.99 sum -------------22.98 max ----0877 type pub_id price
Page 56 of 280

----------trad_cook trad_cook trad_cook

------- -------------0877 11.95 0877 14.99 0877 20.95 sum -------------47.89 max ----0877

(7 rows affected) Valores generales: compute sin by La palabra clave compute puede utilizarse sin by para generar totales generales, conteos generales, etc.. Esta instruccin halla el total general de los precios y los anticipos de todos los tipos de libros por encima de $20: select type, price, advance from titles where price > $20 compute sum(price), sum(advance) type price advance ------------ ---------------- ------------popular_comp 22.95 7,000.00 psychology 21.59 7,000.00 trad_cook 20.95 7,000.00 sum sum =============== ============== 65.49 21,000.00 (4 rows affected) Se puede utilizar una palabra clave compute con by y otra sin by en la misma consulta. La siguiente consulta halla la suma de los precios y los anticipos por tipo, y despus calcula el total general de los precios y los anticipos para todos los tipos de libros. select type, price, advance from titles where type like "%cook" order by type compute sum(price), sum(advance) by type compute sum(price), sum(advance) type price advance ----------- ---------------------------mod_ cook 2.99 15,000.00 mod_cook 19.99 0.00 sum sum ---------------------------22.98 15,000.00 type ----------trad_cook trad_cook trad_cook price ----------------11.95 14.99 20.95 sum ----------------47.89 sum ================= 70.87 advance -----------4,000.00 8,000.00 7,000.00 sum -----------19,000.00 sum ============ 34,000.00

(8 rows affected) Combinacin de consultas: el operador union El operador union de Transact-SQL permite manipular los resultados de dos o ms consultas mediante la combinacin de los resultados de cada consulta en un solo conjunto de resultados. La sintaxis es la siguiente:
Page 57 of 280

query1 [union [all] queryN [order by clause] [compute clause] donde query1 es: select select_list [into clause ] [from clause ] [where clause ] [group by clause ] [having clause ] y queryN es: select select_list [from clause ] [where clause ] [group by clause ] [having clause ]

] ...

Por ejemplo, suponga que tiene las siguientes dos tablas con estos

datos: La siguiente consulta crea una union entre las dos tablas: select * from T1 union select * from T2 El conjunto de resultados es el siguiente: a abc def ghi jkl mno b 1 2 3 4 5

char(4) int

Observe que, de forma predeterminada, el operador union quita filas duplicadas del conjunto de resultados. Si utiliza la opcin all , se incluyen todas la filas en los resultados; las duplicadas no se quitan. Observe tambin que las columnas del conjunto de resultados tienen los mismos nombres que las columnas de T1 . En una instruccin Transact-SQL puede aparecer cualquier nmero de operadores union . Por ejemplo: x union y union z
Page 58 of 280

De forma predeterminada, SQL Server evala una instruccin con operadores union de izquierda a derecha. Es posible usar parntesis para especificar el orden de la evaluacin. Por ejemplo, las expresiones: x y: ( x union all y ) union z union all ( y union z )

no son equivalentes. En el primer ejemplo, los duplicados se eliminan de la unin entre y y z . Despus, en la unin entre dicho conjunto y x , los duplicados no se eliminan. En el segundo ejemplo, los duplicados se incluyen en la unin entre x e y , pero despus se eliminan en la unin posterior con z ; all no tienen ningn efecto en el resultado final de esta instruccin. Directrices para consultas con union A continuacin se indican las directrices que deben tenerse en cuenta al usar instrucciones union :

Todas las listas de seleccin de la instruccin union deben tener el mismo nmero de expresiones (como los nombres de columnas, expresiones aritmticas y funciones agregadas). La siguiente instruccin no es vlida porque la primera lista de seleccin tiene una longitud superior a la segunda: select stor_id, date, ord_num from stores union select stor_id, ord_num from stores_east

Las columnas correspondientes de todas las tablas, o cualquier subconjunto de columnas utilizadas en las consultas individuales, deben ser del mismo tipo de datos, o una conversin de datos implcita debe ser posible entre los dos tipos de datos, o se debe facilitar una conversin explcita. Por ejemplo, no es posible establecer una unin ( union) entre una columna de tipo de datos char y otra de tipo de datos int , a menos que se facilite una conversin explcita. Sin embargo, es posible realizar una unin entre una columna de tipo de datos money y otra de tipo de datos int . Consulte union y "Funciones de conversin de tipos de datos" en el Manual de Referencia de SQL Server para obtener ms informacin sobre la comparacin de tipos de datos en una instruccin union . Las columnas correspondientes en las consultas individuales de una instruccin union deben estar en el mismo orden, porque union compara las columnas una a una en el orden dado en las consultas individuales. Por ejemplo, suponga que tiene estas

tablas: siguiente consulta: select a, b from T3 union select b, a from T4 genera este conjunto de resultados: a b 1 abc 2 def 3 ghi

La

Page 59 of 280

La siguiente consulta: select a, b from T3 union select a, b from T4 genera un mensaje de error, porque los tipos de datos de las columnas correspondientes no son compatibles. Cuando se combinan distintos tipos de datos (pero compatibles), como float e int , en una instruccin union , se convierten al tipo de datos que tenga la mayor precisin.

Los nombres de columnas de la tabla resultante de union se toman de la primera consulta individual de la instruccin union . Por lo tanto, si quiere definir un nuevo encabezado de columna para el conjunto de resultados, debe hacerlo en la primera consulta. Adems, si quiere hacer referencia a una columna del conjunto de resultados utilizando un nombre nuevo, por ejemplo, en una instruccin order by , debe hacerlo de este modo en la primera instruccin select . La siguiente consulta es correcta: select Cities = city from stores union select city from authors order by Cities

Uso de union con otros comandos Transact-SQL A continuacin se muestran algunas directrices que deben tenerse en cuenta al usar las instrucciones union con otros comandos Transact-SQL:

La primera consulta de la instruccin union puede contener una clusula into que cree una tabla para el conjunto de resultados finales. Por ejemplo, la siguiente instruccin crea una tabla llamada results que contiene la unin de tablas publishers , stores y salesdetail: select pub_id, pub_name, city into results from publishers union select stor_id, stor_name, city from stores union select stor_id, title_id, ord_num from salesdetail La clusula into slo puede utilizarse en la primera consulta; si aparece en cualquier otro lugar, se muestra un mensaje de error.

Las clusulas order by y compute slo se permiten al final de la instruccin union para definir el orden de los resultados finales o para calcular valores sumarios. No pueden utilizarse dentro de las consultas individuales que conforman la instruccin union . Las clusulas group by y having slo pueden usarse dentro de consultas individuales; no pueden utilizarse para afectar al conjunto de resultados final. El operador union tambin puede utilizarse dentro de una instruccin insert . Por ejemplo: insert into tour select city, state from stores union select city, state from authors

El operador union no puede utilizarse dentro de una instruccin create view . La clusula for browse no puede utilizarse en instrucciones que incluyan el operador union .

Chapter 4

Combinaciones: recuperacin de datos de varias tablas


Este captulo inicia la explicacin sobre las operaciones de recuperacin de datos de dos o ms tablas. Estas tablas pueden estar en la misma base de datos o en bases de datos diferentes. Hasta ahora, la explicacin se ha limitado a ejemplos de recuperacin de datos de una sola tabla.
Page 60 of 280

La operacin multitabla explicada en este captulo es la combinacin. Las subconsultas, que tambin pueden incluir dos o ms tablas, se tratan en el Captulo 5, "Subconsultas: uso de consultas dentro de otras consultas". Muchas combinaciones pueden considerarse como subconsultas. En este captulo se trata lo siguiente:

Introduccin general a las operaciones de combinacin Combinacin de tablas en una consulta Modo en que SQL Server procesa las combinaciones Modo en que los valores afectan a las combinaciones Modo de determinar las columnas que deben combinarse Definicin de combinacin Combinacin de tablas en las consultas Procesamiento de combinaciones Efecto de los valores nulos sobre las combinaciones Determinacin de las columnas de tabla que deben combinarse

Definicin de combinacin La combinacin de dos o ms tablas es un proceso que compara los datos de campos especificados y usa los resultados de la comparacin para crear una tabla nueva a partir de las filas que cumplen los requisitos de calificacin. Una instruccin de combinacin especifica una columna de cada tabla, compara los valores de dichas columnas fila a fila y combina las filas calificadas en filas nuevas. La comparacin es generalmente de igualdad (valores totalmente coincidentes), pero pueden especificarse otros tipos de combinaciones. Si una combinacin ha de tener resultados significativos, las columnas que van a compararse deben tener valores similares, es decir, valores que puedan compararse porque sus tipos de datos son iguales o similares. La operacin de combinacin tiene una jerga propia. La palabra "join" (combinacin) se utiliza como verbo y como nombre, en referencia a la operacin en s, a la consulta o a sus resultados. Existen diversas variedades de combinaciones: equicombinaciones, combinaciones naturales, combinaciones externas, etc.. La variedad ms comn es la combinacin basada en la igualdad. A continuacin se muestra un ejemplo de una combinacin que busca los nombres de autores y editores ubicados en la misma ciudad: select au_fname, au_lname, pub_name from authors, publishers where authors.city = publishers.city au_fname au_lname pub_name ---------------------------------Cheryl Carson Algodata Infosystems Abraham Bennet Algodata Infosystems (2 rows affected) Dado que la consulta se realiza a partir de informacin contenida en dos tablas distintas, publishers y authors , se precisa una combinacin para recuperar la informacin solicitada. Las combinaciones y el modelo relacional La operacin de combinacin es el sello del modelo relacional de administracin de bases de datos. Ms que ninguna otra funcin, la combinacin distingue los sistemas de administracin de bases de datos relacionales de otros tipos de DBMS. En los sistemas de administracin de bases de datos estructurados, a menudo conocidos como sistemas de redes y jerrquicos, las relaciones entre los valores de datos estn predefinidas. Una vez que se ha configurado una base de datos, es difcil realizar consultas sobre relaciones no anticipadas entre los datos. Por otro lado, en un sistema de administracin de bases de datos relacionales, las relaciones entre los valores de datos quedan sin determinar en la definicin de una base de datos y pasan a ser explcitas cuando los datos se manipulan, es decir, cuando la
Page 61 of 280

base de datos se consulta , no cuando se crea. El usuario puede realizar cualquier pregunta que se le ocurra sobre los datos almacenados en la base de datos, independientemente de lo previsto al configurar la base de datos. Segn las reglas de buen diseo de bases de datos, llamadas reglas de normalizacin , cada tabla debe describir un tipo de entidad: una persona, lugar, evento o cosa. Este es el motivo por el que, al comparar informacin sobre dos o ms tipos de entidades, se necesita la operacin de combinacin. Las relaciones entre los datos almacenados en tablas diferentes se descubren al combinar las tablas. Un corolario de esta regla es que la operacin de combinacin proporciona una flexibilidad ilimitada al aadir nuevos tipos de datos a la base de datos. Siempre se puede crear una tabla nueva que contenga datos sobre un tipo de entidad distinto. Si la tabla nueva tiene un campo con valores similares a los de otro campo de una tabla o tablas existentes, puede vincularse a las tablas existentes mediante una combinacin. Combinacin de tablas en las consultas La instruccin de combinacin, al igual que la instruccin de seleccin, comienza con la palabra clave select . Las columnas incluidas despus de select son las columnas que deben insertarse en los resultados de la consulta, en el orden deseado. El ejemplo anterior especificaba las columnas que contenan los nombres de autores y editores. Las columnas pub_name , au_lname y au_fname no tenan que calificarse mediante un nombre de tabla, dado que no hay ninguna ambigedad sobre la tabla a la que pertenecen. Pero la columna city utilizada para la comparacin de combinacin s tena que calificarse, ya que las tablas publishers y authors tambin contienen columnas con ese nombre . Aunque en este ejemplo ninguna de las columnas city aparece en los resultados, SQL Server necesita el nombre de la tabla a fin de realizar la comparacin. Al igual que en la instruccin select , se puede especificar que todas las columnas de las tablas usadas en la consulta se incluyan en los resultados con la abreviatura " * ". Por ejemplo, para incluir todas las columnas de publishers y authors en la consulta de combinacin anterior, la instruccin es: select * from authors, publishers where authors.city = publishers.city au_id au_lname au_fname phone address city state postalcode contract pub_id pub_name city state ----------- -------- -------- ------------ ------------------------------ ----- ---------- -------- ------ ----------------------------- ----238-95-7766 Carson Cheryl 415 548-7723 589 Darwin Ln. Berkeley CA 94705 1 1389 Algodata Infosystems Berkeley CA 409-56-7008 Bennet Abraham 415 658-9932 223 Bateman St Berkeley CA 94705 1 1389 Algodata Infosystems Berkeley CA (2 rows affected) La pantalla muestra un total de dos filas con trece columnas cada una. Debido a su longitud, cada fila ocupa varias lneas horizontales. Siempre que se utilice "*", las columnas de resultados aparecen en el orden de la instruccin create de la tabla. La lista de seleccin y los resultados de una combinacin no tienen que incluir necesariamente columnas de las dos tablas de la combinacin. Por ejemplo, para encontrar los nombres de los autores que viven en la misma ciudad de uno de los editores, no es necesario que la consulta incluya columnas de la tabla publishers : select au_lname, au_fname from authors, publishers where authors.city = publishers.city No hay que olvidar, que al igual que en cualquier instruccin select , los nombres de columna de la lista de seleccin y los nombres de tabla de la clusula from deben estar separados por comas. La clusula from La clusula from de una instruccin de combinacin contiene todas las tablas o vistas implicadas en la combinacin. Esta es la clusula que realmente indica a SQL Server que se desea una combinacin. Las tablas o vistas pueden especificarse en
Page 62 of 280

cualquier orden. El orden de las tablas afecta a los resultados mostrados slo cuando se utiliza select * para especificar la lista de seleccin. Es posible especificar ms de dos tablas o vistas en la clusula from . Como mximo, una consulta puede hacer referencia a 16 tablas. Este mximo incluye:

Tablas (o vistas de tablas) especificadas en la clusula from Cada ejemplo de referencias mltiples a la misma tabla (autocombinaciones) Tablas referenciadas en subconsultas Tablas base referenciadas por las vistas especificadas en la clusula from

Las combinaciones que implican el uso de ms de dos tablas o vistas se explican ms adelante en este captulo en "Combinacin de ms de dos tablas". Tal como se explic en el Captulo 2, "Consultas: seleccin de datos de una tabla", los nombres de tabla o vista pueden calificarse con los nombres del propietario y la base de datos, y puede asignrseles nombres de correlacin segn se considere conveniente. Las vistas pueden combinarse exactamente del mismo modo que las tablas y utilizarse dondequiera se usen tablas. En el Chapter 9 se explican las vistas; este captulo slo emplea tablas en sus ejemplos. La clusula where La clusula where especifica la conexin entre las tablas especificadas en la clusula from , restringiendo las filas que deben incluirse en los resultados. where proporciona los nombres de las columnas que van a combinarse, calificados por nombres de tablas si fuera necesario y el operador de combinacin, a menudo de igualdad y a veces "mayor que" o "menor que". Para obtener ms detalles sobre la sintaxis de la clusula where , consulte el Chapter 2 de esta gua o la seccin "Clusula where" del Manual de Referencia de SQL Server . Note: Si no se incluye la clusula where , los resultados de una combinacin sern imprevistos. Sin una clusula where , cualquiera de las consultas de combinacin explicadas hasta ahora generar 27 filas en lugar de 2. En la siguiente seccin se explica por qu ocurre tal cosa. Las combinaciones que comparan columnas segn igualdad reciben el nombre de equicombinaciones . Ms adelante en este captulo encontrar una definicin ms precisa de equicombinacin, junto con ejemplos de combinaciones no basadas en igualdad. Los operadores de combinacin que determinan la base de comparacin de las columnas son los operadores relacionales: Tabla 4-1: Operadores de combinacin Operador = > >= < <= != !> !< Significado Igual que Mayor que Mayor o igual que Menor que Menor o igual que Distinto de Menor o igual que Mayor o igual que

Las combinaciones que usan operadores relacionales se denominan colectivamente combinaciones theta . Otro conjunto de operadores de combinacin se utiliza para combinaciones externas , tambin explicadas en detalle ms adelante en este captulo. Los operadores de combinacin externa son: Tabla 4-2: Operaciones de combinacin externa Operador Accin *= Incluye en los resultados todas las filas de la primera tabla, no slo las filas donde coinciden las
Page 63 of 280

columnas combinadas. =* Incluye en los resultados todas las filas de la segunda tabla, no slo las filas donde coinciden las columnas combinadas.

Las columnas que van a combinarse no necesitan tener el mismo nombre, aunque a menudo lo tengan. Adems, tampoco necesitan tener el mismo tipo de datos (consulte el Chapter 7). Sin embargo, si los tipos de datos no son idnticos, deben ser compatibles , es decir, tipos que SQL Server pueda convertir de forma automtica. Por ejemplo, SQL Server convierte automticamente cualquiera de las columnas de tipo numrico ( int, smallint, tinyint, decimal o float ) y cualquiera de las columnas de tipo de caracteres y de fecha ( char, varchar, nchar, nvarchar y datetime ). Para obtener informacin detallada sobre la conversin de tipo de datos, consulte el Captulo 10, "Uso de funciones incorporadas en consultas", y la seccin "Funciones de conversin de tipos de datos"del Manual de Referencia de SQL

Server.

Note: No pueden combinarse tablas a partir de columnas text o image . Sin embargo, se pueden comparar las longitudes de columnas de texto de dos tablas con una clusula where , como: where datalength(textab_1.textcol) > datalength(textab_2.textcol) La clusula where de una instruccin de combinacin puede incluir otras condiciones adems de la que enlaza columnas de tablas diferentes. En otras palabras, es posible incluir una operacin de combinacin y una operacin select en la misma instruccin SQL. Encontrar un ejemplo ms adelante en este captulo. Procesamiento de combinaciones Conocer el modo en que se procesan las combinaciones ayuda a entenderlas y a descubrir el motivo, cuando se define una combinacin de forma incorrecta, por el que a veces se obtienen resultados imprevistos. En esta seccin se describe el procesamiento de combinaciones en trminos conceptuales. El procedimiento real de SQL Server es ms sofisticado. En trminos conceptuales, el primer paso del procesamiento de una combinacin es formar el producto cartesiano de las tablas, es decir, todas las combinaciones posibles de las filas de cada una de las tablas. El nmero de filas de un producto cartesiano de dos tablas es igual al nmero de filas de la primera tabla por el nmero de filas de la segunda tabla. El producto cartesiano de la tabla authors y la tabla publishers es 69 (23 autores multiplicados por 3 editores). Se puede ver un producto cartesiano con cualquier consulta que incluya columnas de ms de una tabla en la lista de seleccin, ms de una tabla en la clusula from y ninguna clusula where . Por ejemplo si se omite la clusula where de la combinacin utilizada en los ejemplos anteriores, SQL Server combinar cada uno de los 23 autores con cada uno de los 3 editores, y devolver 69 filas. Este producto cartesiano no contiene ninguna informacin particularmente til. De hecho, llevara a una conclusin totalmente errnea, puesto que parece implicar que cada autor de la base de datos tiene una relacin con cada editor de la base de datos, lo cual no es cierto en absoluto. Este es el motivo por el que una combinacin debe incluir una clusula where , que especifica las columnas que deben compararse y en base a qu compararlas. Tambin pueden incluirse otras restricciones. Una vez obtenido el producto cartesiano, las filas que no se ajustan a la combinacin se eliminan segn las condiciones de la clusula where . La clusula where incluida en el ejemplo anterior elimina de los resultados todas las filas en las que la ciudad del autor no coincide con la del editor. Equicombinaciones y combinaciones naturales Una equicombinacin es una combinacin en la que los valores de las columnas combinadas se comparan para establecer su igualdad, y todas las columnas de las tablas de la combinacin se incluyen en los resultados. La consulta anterior: select * from authors, publishers where authors.city = publishers.city es una ejemplo de equicombinacin. En los resultados de esta instruccin, la columna city aparece dos veces. Por definicin, los resultados de una equicombinacin contienen dos columnas idnticas. Puesto que generalmente no tiene ningn sentido repetir
Page 64 of 280

la misma informacin, una de estas columnas pueden eliminarse volvindose a definir la consulta. El resultado se llama combinacin natural . La consulta que da como resultado la combinacin natural de publishers y authors a partir de la columna city es: select publishers.pub_id, publishers.pub_name, publishers.state, authors.* from publishers, authors where publishers.city = authors.city La columna publishers.city no aparece en los resultados. Combinaciones con condiciones adicionales La clusula where de una consulta de combinacin puede incluir criterios de seleccin, as como especificar la condicin de combinacin. Por ejemplo, para recuperar los nombres y editores de todos los libros cuyos anticipos pagados son superiores a $7500, la instruccin es: select title, pub_name, advance from titles, publishers where titles.pub_id = publishers.pub_id and advance > $7500 title pub_name advance ------------------------------------------------ --------You Can Combat Computer Stress! New Age Books 10,125.00 The Gourmet Microwave Binnet & Hardley 15,000.00 Secrets of Silicon Valley Algodata Infosystems 8,000.00 Sushi, Anyone? Binnet & Hardley 8,000.00 (4 rows affected) Observe que las columnas combinadas no necesitan aparecer en la lista de seleccin y, por lo tanto, no aparecen en los resultados. En una instruccin de combinacin se pueden incluir tantos criterios de seleccin como se deseen. El orden de los criterios de seleccin y la condicin de combinacin no es importante. Combinaciones no basadas en la igualdad La condicin para combinar los valores de dos columnas no tiene que ser necesariamente la de igualdad. Es posible utilizar cualquiera de los dems operadores de comparacin: distinto de (!=), mayor que (>), menor que (<), mayor o igual que (>=) y menor o igual que (<=). Transact-SQL tambin proporciona los operadores !> y !<, que son equivalentes a <= y >=, respectivamente. Este ejemplo de una combinacin mayor que (>) busca autores de New Age que vivan en estados que correspondan al estado de New Age Books , Massachusetts, en orden alfabtico. select pub_name, publishers.state, au_lname, au_fname, authors.state from publishers, authors where authors.state > publishers.state and pub_name = "New Age Books" pub_name state au_lname ------------------ -------------New Age Books MA Greene New Age Books MA Blotchet-Halls New Age Books MA del Castillo New Age Books MA Panteley New Age Books MA Ringer New Age Books MA Ringer (6 rows affected) El siguiente ejemplo utiliza una combinacin ">=" y otra "<" para buscar el royalty correcto de la tabla roysched , basndose en las ventas totales del libro.
Page 65 of 280

au_fname ----------Morningstar Reginald Innes Sylvia Anne Albert

state ----TN OR MI MD UT UT

select t.title_id, t.total_sales, r.royalty from titles t, roysched r where t.title_id = r.title_id and t.total_sales >= r.lorange and t.total_sales < r.hirange title_id total_sales royalty -----------------------BU1032 4095 10 BU1111 3876 10 BU2075 1872 24 BU7832 4095 10 MC2222 2032 12 MC3021 22246 24 PC1035 8780 16 PC8888 4095 10 PS1372 375 10 PS2091 2045 12 PS2106 111 10 PS3333 4072 10 PS7777 3336 10 TC3218 375 10 TC4203 15096 14 TC7777 4095 10 (16 rows affected) Autocombinaciones y nombres de correlacin Se pueden comparar los valores de la columna de una tabla con la autocombinacin . Por ejemplo, se puede hacer una autocombinacin para averiguar qu autores de Oakland, California, tienen el mismo cdigo postal. Dado que esta consulta implica una combinacin de la tabla authors consigo misma, esta tabla aparece en dos roles. Para distinguir estos roles, pueden asignarse temporal y arbitrariamente dos nombres de correlacin diferentes a la tabla authors , como au1 y au2 , en la clusula from . Estos nombres de correlacin se utilizan para calificar los nombres de columna del resto de la consulta. La instruccin de autocombinacin tiene el siguiente aspecto: select au1.au_fname, au1.au_lname, au2.au_fname, au2.au_lname from authors au1, authors au2 where au1.city = "Oakland" and au2.city = "Oakland" and au1.state = "CA" and au2.state = "CA" and au1.postalcode = au2.postalcode au_fname au_lname au_fname au_lname ------------------- --------------Marjorie Green Marjorie Green Dick Straight Dick Straight Dick Straight Dirk Stringer Dick Straight Livia Karsen Dirk Stringer Dick Straight Dirk Stringer Dirk Stringer Dirk Stringer Livia Karsen Stearns MacFeather Stearns MacFeather Livia Karsen Dick Straight Livia Karsen Dirk Stringer Livia Karsen Livia Karsen (11 rows affected) Para eliminar las filas de los resultados donde los autores coinciden consigo mismos y eliminar las filas que son idnticas, pero con el orden de los autores invertido, puede realizar esta adicin a la consulta de autocombinacin: select au1.au_fname, au1.au_lname, au2.au_fname, au2.au_lname from authors au1, authors au2 where au1.city = "Oakland" and au2.city = "Oakland" and au1.state = "CA" and au2.state = "CA" and au1.postalcode = au2.postalcode and au1.au_id < au2.au_id au_fname au_lname au_fname au_lname ------------------- ----------------Page 66 of 280

Dick Dick Dirk

Straight Straight Stringer

Dirk Livia Livia

Stringer Karsen Karsen

(3 rows affected) Ahora est claro que Dick Straight, Dirk Stringer y Livia Karsen tienen el mismo cdigo postal. La combinacin de desigualdad La combinacin de desigualdad es particularmente til para restringir filas devueltas por una autocombinacin. Por ejemplo, una combinacin de desigualdad y una autocombinacin se utiliza para hallar las categoras donde haya dos o ms libros baratos (menos de $15) de diferentes precios: select distinct t1.type, t1.price from titles t1, titles t2 where t1.price <$15 and t2.price <$15 and t1.type = t2.type and t1.price != t2.price type price ---------- ----business 2.99 business 11.95 psychology 7.00 psychology 7.99 psychology 10.95 trad_cook 11.95 trad_cook 14.99 (7 rows affected) Note: La expresin "not column_name = column_name" equivale a "column_name != column_name". El siguiente ejemplo utiliza una combinacin de desigualdad con una autocombinacin: busca todas las filas de la tabla titleauthor donde hay dos o ms filas con el mismo cdigo title_id , pero con nmeros de au_id diferentes, es decir, libros que tienen ms de un autor. select distinct t1.au_id, t1.title_id from titleauthor t1, titleauthor t2 where t1.title_id = t2.title_id and t1.au_id != t2.au_id order by t1.title_id au_id title_id -----------------213-46-8915 BU1032 409-56-7008 BU1032 267-41-2394 BU1111 724-80-9391 BU1111 722-51-5454 MC3021 899-46-2035 MC3021 427-17-2319 PC8888 846-92-7186 PC8888 724-80-9391 PS1372 756-30-7391 PS1372 899-46-2035 PS2091 998-72-3567 PS2091 267-41-2394 TC7777 472-27-2349 TC7777 672-71-3249 TC7777 (15 rows affected) Combinaciones de desigualdad y subconsultas Algunas veces una consulta de combinacin de desigualdad no es suficientemente restrictiva y necesita ser sustituida por una subconsulta. Por ejemplo, suponga que quiere enumerar los nombres de los autores que viven en una ciudad en la que no hay ningn editor. Para mayor claridad, podemos restringir la consulta a los autores cuyos apellidos empiecen con "A", "B" o "C". Una consulta de combinacin de desigualdad podra ser:

Page 67 of 280

select distinct au_lname, authors.city from publishers, authors where au_lname like "[ABC]%" and publishers.city != authors.city Pero los resultados no responden a la pregunta formulada. au_lname ---------------Bennet Carson Blotchet-Halls (3 rows affected) El sistema interpreta esta versin de la instruccin SQL con el siguiente significado: "buscar los nombres de los autores que vivan en una ciudad donde no hay ningn editor". Todos los autores excluidos cumplen con esta condicin, incluidos los que viven en Berkeley, sede de la editorial Algodata Infosystems. En este caso, el modo en que el sistema manipula las combinaciones (buscando todas las combinaciones seleccionables antes de evaluar otras condiciones) hace que la consulta devuelva resultados no deseados. En estos casos, es necesario utilizar una subconsulta para obtener los resultados deseados. Una subconsulta puede eliminar primero las filas no seleccionables y despus realizar las restantes restricciones. A continuacin se muestra la instruccin correcta: select distinct au_lname, city from authors where au_lname like "[ABC]%" and city not in (select city from publishers where authors.city = publishers.city) Ahora los resultados son los deseados: au_lname ------------Blotchet-Halls (1 row affected) Las subconsultas se explican con mayor detalle en el Chapter 5. Combinacin de ms de dos tablas La tabla titleauthor de pubs2 ofrece un buen ejemplo de una situacin en la que resulta til la combinacin de ms de dos tablas. Para buscar los ttulos de todos los libros de un tipo concreto y los nombres de sus autores, la consulta es: select au_lname, au_fname, title from authors, titles, titleauthor where authors.au_id = titleauthor.au_id and titles.title_id = titleauthor.title_id and titles.type = "trad_cook" au_lname au_fname title -------------- ----------- -----------------------Panteley Sylvia Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean Blotchet-Halls Reginald Fifty Years in Buckingham Palace Kitchens O'Leary Michael Sushi, Anyone? Gringlesby Burt Sushi, Anyone? Yokomoto Akiko Sushi, Anyone? (5 rows affected) city -----------Corvallis city -----------Berkeley Berkeley Corvallis

Page 68 of 280

Observe que una de las tablas de la clusula from , titleauthor , no contribuye ninguna columna a los resultados. Ni tampoco ninguna de las columnas que se combinan, au_id y title_id , aparecen en los resultados. No obstante, esta combinacin es posible nicamente mediante el uso de titleauthor como tabla intermedia. Tambin pueden combinarse ms de dos pares de columnas en la misma instruccin. Por ejemplo, a continuacin se muestra una consulta que indica la title_id , sus ventas totales y el margen al que corresponden, y los derechos de autor resultantes. select titles.title_id, total_sales, lorange, hirange, royalty from titles, roysched where titles.title_id = roysched.title_id and total_sales >= lorange and total_sales < hirange title_id total_sales lorange hirange royalty ------------------------ ------- ------BU1032 4095 0 5000 10 BU1111 3876 0 4000 10 BU2075 18722 14001 50000 24 BU7832 4095 0 5000 10 MC2222 2032 2001 4000 12 MC3021 2224 12001 50000 24 PC1035 8780 4001 10000 16 PC8888 4095 0 5000 10 PS1372 375 0 10000 10 PS2091 2045 1001 5000 12 PS2106 111 0 2000 10 PS3333 4072 0 5000 10 PS7777 3336 0 5000 10 TC3218 375 0 2000 10 TC4203 15096 8001 16000 14 TC7777 4095 0 5000 10 (16 rows affected) Cuando hay varios operadores de combinacin en la misma instruccin, para combinar ms de dos tablas o ms de dos pares de columnas, las "expresiones de combinacin" estn casi siempre conectadas por and , como en los ejemplos anteriores. Sin embargo, tambin es legal conectarlas mediante or. Combinaciones externas En las combinaciones que se han explicado, slo las filas coincidentes, es decir, las filas con valores en las columnas especificadas que satisfacen la condicin de combinacin, se incluyen en los resultados. En cierto modo, estas operaciones de combinacin eliminan la informacin contenida en las filas que no coinciden. Algunas veces es preferible conservar dicha informacin mediante la inclusin de filas no coincidentes en los resultados de una combinacin. En tales ocasiones, la combinacin externa es la operacin de eleccin. Transact-SQL es una de las pocas versiones de SQL que soporta la combinacin externa. Estos son los operadores de combinacin externa proporcionados por Transact-SQL: Tabla 4-3: Resumen de los operadores de combinacin externa Operador Accin *= =* Incluye todas las filas de la primera tabla especificada Incluye todas las filas de la segunda tabla especificada

Recuerde que la consulta sobre autores que viven en la misma ciudad que un editor devuelve dos nombres: Abraham Bennett y Cheryl Carson. Para incluir todos los autores en los resultados, independientemente de si un editor est ubicado en la misma ciudad, utilice una combinacin externa. A continuacin se muestra la consulta y los resultados de la combinacin externa: select au_fname, au_lname, pub_name from authors, publishers where authors.city *= publishers.city au_fname au_lname pub_name -----------------------------------Johnson White NULL Marjorie Green NULL Cheryl Carson Algodata Infosystems
Page 69 of 280

Michael Dick Meander Abraham Ann Burt Chastity Morningstar Reginald Akiko Innes Michel Dirk Stearns Livia Sylvia Sheryl Heather Anne Albert

O'Leary Straight Smith Bennet Dull Gringlesby Locksley Greene Blotche-Halls Yokomoto del Castillo DeFrance Stringer MacFeather Karsen Panteley Hunter McBadden Ringer Ringer

NULL NULL NULL Algodata Infosystems NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL

(23 rows affected) El operador de comparacin "*=" distingue la combinacin externa de una ordinaria. Esta combinacin externa "izquierda" indica a SQL Server que incluya todas las filas de la tabla authors en los resultados, exista o no una coincidencia en la columna city de la tabla publishers . Observe que en los resultados no existen datos coincidentes para la mayora de los autores mostrados, por lo que estas filas contienen NULL en la columna pub_name . Note: Dado que las columnas de bits no permiten valores nulos, cuando no existe correspondencia para una columna de bits en la tabla interna, aparece un valor de "0" en una combinacin externa. La combinacin externa "derecha" se especifica con el operador de comparacin "=*", que indica que en los resultados deben incluirse todas las filas de la segunda tabla, independientemente de si existen datos coincidentes en la primera tabla. La sustitucin de este operador en la consulta de combinacin externa anterior da este resultado: select au_fname, au_lname, pub_name from authors, publishers where authors.city =* publishers.city au_fname au_lname pub_name ------------------------------NULL NULL New Age Books NULL NULL Binnet & Hardley Cheryl Carson Algodata Infosystems Abraham Bennet Algodata Infosystems (4 rows affected) Una combinacin externa puede restringirse todava ms si se compara con una constante. Esto significa que puede enfocarse de forma precisa en el valor o valores realmente deseados y utilizar la combinacin externa para mostrar las filas que no entraron en el corte. Primero observe la equicombinacin y luego comprela con la combinacin externa. Por ejemplo, si desea averiguar qu ttulos vendieron ms de 500 copias en cualquier librera, tendra que usar esta consulta: elect distinct salesdetail.stor_id, title from titles, salesdetail where qty > 500 and salesdetail.title_id = titles.title_id stor_id title -------------------------------------------------5023 Sushi, Anyone? 5023 Is Anger the Enemy? 5023 The Gourmet Microwave 5023 But Is It User Friendly? 5023 Secrets of Silicon Valley 5023 Straight Talk About Computers 5023 You Can Combat Computer Stress! 5023 Silicon Valley Gastronomic Treats 5023 Emotional Security: A New Algorithm 5023 The Busy Executive's Database Guide
Page 70 of 280

5023 5023 5023 7067

Fifty Years in Buckingham Palace Kitchens Prolonged Data Deprivation: Four Case Studies Cooking with Computers: Surreptitious Balance Sheets Fifty Years in Buckingham Palace Kitchens

(14 rows affected) Para mostrar, adems, los ttulos que no vendieron ms de 500 copias en cualquier librera, puede utilizar una consulta de combinacin externa: select distinct salesdetail.stor_id, title from titles, salesdetail where qty > 500 and salesdetail.title_id =* titles.title_id stor_id title ------------------------------------------------NULL Net Etiquette NULL Life Without Fear 5023 Sushi, Anyone? 5023 Is Anger the Enemy? 5023 The Gourmet Microwave 5023 But Is It User Friendly? 5023 Secrets of Silicon Valley 5023 Straight Talk About Computers 5023 You Can Combat Computer Stress! 5023 Silicon Valley Gastronomic Treats 5023 Emotional Security: A New Algorithm 5023 The Busy Executive's Database Guide 5023 Fifty Years in Buckingham Palace Kitchens 7067 Fifty Years in Buckingham Palace Kitchens 5023 Prolonged Data Deprivation: Four Case Studies 5023 Cooking with Computers: Surreptitious Balance Sheets NULL Computer Phobic and Non-Phobic Individuals: Behavior Variations NULL Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean (18 rows affected) Restricciones de las combinaciones externas En Transact-SQL, una tabla no puede participar en una clusula de combinacin externa y en otra de combinacin regular. La siguiente consulta fracasa porque se pide a la tabla salesdetail que realice una doble tarea: select distinct sales.stor_id, stor_name, title from sales, stores, titles, salesdetail where qty > 500 and salesdetail.title_id =* titles.title_id and sales.stor_id = salesdetail.stor_id and sales.stor_id = stores.stor_id Msg 303, Level 16, State 1: Server 'RAW', Line 1: La tabla 'salesdetail' es un miembro interno de una clusula de combinacin externa. Esto no se permite si la tabla participa adems en una clusula de combinacin normal. Si quisiera saber el nombre de la librera que vendi ms de 500 copias de algn libro, tendra que utilizar una segunda consulta. Si ejecuta una consulta con una combinacin externa y una calificacin en una columna de la tabla interna de la combinacin externa, los resultados pueden ser distintos de los esperados. La calificacin de la consulta no restringe el nmero de filas devueltas, sino que afecta a las filas que contienen el valor nulo. Para las filas que no cumplen la calificacin, aparece un valor nulo en las columnas de la tabla interna de dichas filas. Efecto de los valores nulos sobre las combinaciones Si las columnas de las tablas combinadas contienen valores nulos, stos nunca pueden coincidir. Adems, el resultado de una combinacin de NULL con cualquier otro valor, es NULL. Dado que los valores nulos representan valores desconocidos o inaplicables, Transact-SQL no tiene ningn motivo para creer que un valor desconocido coincide con otro.

Page 71 of 280

Slo se puede detectar la presencia de valores nulos en una columna de una de las tablas de la combinacin si se usa una combinacin externa. A continuacin se muestran dos tablas, cada una de las cuales tiene un valor NULL en la columna que va a formar parte de la combinacin. Una combinacin externa izquierda muestra el valor NULL en la primera tabla. Tabla 1: a --------1 NULL 4 Tabla 2: c --------NULL 4 d -----two four b -----one three join4

Combinacin externa izquierda:

select * from t1, t2 where a *= c a ----------1 NULL 4

b -----one three join4

c ----------NULL NULL 4

d -----NULL NULL four

Observe que los resultados no facilitan la distincin entre un valor NULL en los datos y uno NULL que representa un fallo de la combinacin. Cuando hay valores nulos en los datos que van a combinarse, generalmente es preferible omitirlos de los resultados mediante el uso de una combinacin regular. Determinacin de las columnas de tabla que deben combinarse El procedimiento del sistema sp_helpjoins muestra las columnas de dos tablas o vistas que son posibles candidatos a la combinacin. Su sintaxis es: sp_helpjoins table1 , table2

Por ejemplo, a continuacin se muestra cmo utilizar sp_helpjoins para localizar las columnas posibles de combinar entre titleauthor y titles : sp_helpjoins titleauthor, titles Los pares de columnas que sp_helpjoins muestra proceden de dos fuentes. Primero sp_helpjoins verifica la tabla syskeys de la base de datos actual para ver si se defini alguna clave externa en las dos tablas con sp_foreignkeye y despus comprueba si se defini alguna clave comn en las dos tablas con sp_commonkey . Si no encuentra ninguna clave comn, el procedimiento aplica criterios menos restrictivos para proponer cualquier clave que pueda combinarse de forma razonable; busca las claves con los mismos tipos de datos de usuario y, si falla, busca las columnas con el mismo nombre y tipo de datos. Para obtener informacin completa sobre los procedimientos del sistema, consulte el Manual de Referencia de SQL Server . Chapter 5

Subconsultas: uso de consultas dentro de otras consultas


Una subconsulta es una instruccin select anidada dentro de otra instruccin select , insert , update o delete , dentro de una instruccin condicional o dentro de otra subconsulta. En este captulo se trata lo siguiente:
Page 72 of 280

Definicin de consulta Tipos de subconsultas Subconsultas de expresin Subconsultas de predicado cuantificado Subconsultas correlacionadas Definicin de subconsulta Tipos de subconsultas Subconsultas de expresin Subconsultas de predicado cuantificado Uso de subconsultas correlacionadas

Definicin de subconsulta Las subconsultas son consultas que aparecen en la clusula where o having de otra instruccin SQL o en la lista de seleccin de una instruccin. Las subconsultas pueden utilizarse para manipular las solicitudes de consulta que se expresan como el resultado de otras consultas. Las instrucciones que incluyen subconsultas operan sobre las filas de una tabla, de acuerdo a su evaluacin de la lista select de la subconsulta, que puede hacer referencia a la misma tabla como una consulta externa, o bien a una tabla distinta. En Transact-SQL, una subconsulta puede usarse prcticamente en cualquier lugar donde se permita una expresin, siempre que la subconsulta devuelva un valor nico. Las instrucciones select que contienen una o ms subconsultas a veces se denominan consultas anidadas o instrucciones select anidadas. La prctica de anidar una instruccin select en otra explica que se incluya el trmino "structured" (estructurado) en SQL (Structured Query Language). Muchas instrucciones SQL que incluyen subconsultas, tambin llamadas consultas internas , pueden formularse alternativamente como combinaciones. Otras preguntas slo pueden formularse con subconsultas. Algunos prefieren las subconsultas a las formulaciones alternativas porque son ms fciles de entender. Otros usuarios de SQL evitan las consultas siempre que sea posible. Usted puede elegir la formulacin que prefiera (SQL Server convierte algunas subconsultas en combinaciones antes de procesarlas). Ejemplo del uso de una subconsulta Si desea encontrar todos los libros con el mismo precio que Straight Talk About Computers , puede hacerlo en dos pasos. En primer lugar, busque el precio de Straight Talk : select price from titles where title = "Straight Talk About Computers" price ------------$19.99 (1 row affected) Ahora use dicho resultado en otra consulta para buscar todos los libros cuyo precio sea idntico al de Straight Talk : select title, price from titles where price = $19.99 title price ---------------------------------------------The Busy Executive's Database Guide 19.99 Straight Talk About Computers 19.99 Silicon Valley Gastronomic Treats 19.99 Prolonged Data Deprivation: Four Case Studies 19.99 (4 rows affected) La subconsulta resuelve el problema con una sola instruccin: select title, price from titles where price =
Page 73 of 280

(select price from titles where title = "Straight Talk About Computers") title price ------------------------------------------The Busy Executive's Database Guide 19.99 Straight Talk About Computers 19.99 Silicon Valley Gastronomic Treats 19.99 Prolonged Data Deprivation: Four Case Studies 19.99 (4 rows affected) Sintaxis y reglas generales de las subconsultas Incluya siempre la instruccin select de una subconsulta entre parntesis. La instruccin select de la consulta tiene una sintaxis select algo restringida, como puede verse en este ejemplo. (select [distinct] subquery_select_list [from [[ database .] owner .]{ table_name | view_name } [({index index_name | prefetch size |[lru|mru]})]} [holdlock | noholdlock] [shared] [,[[ database .] owner .]{ table_name | view_name } [({index index_name | prefetch size |[lru|mru]})]} [holdlock | noholdlock] [shared]]... ] [where search_conditions ] [group by aggregate_free_expression [, aggregate_free_expression ]... ] [having search_conditions ]) Las subconsultas pueden anidarse dentro de la clusula where o having de una instruccin externa select , insert , update o delete , dentro de otra subconsulta, o en una lista de seleccin. En Transact-SQL, una subconsulta puede aparecer prcticamente en cualquier lugar donde pueda usarse una expresin, siempre que devuelva un solo valor. Restricciones de las subconsultas Las subconsultas estn sujetas a estas restricciones:

Las subconsultas no pueden usarse en una lista order by , group by ni compute by . Las subconsultas no pueden incluir clusulas for browse ni uniones ( union ). La lista de seleccin de una subconsulta interna con un operador de comparacin puede incluir slo una expresin o nombre de columna, y la subconsulta debe devolver un solo valor. La columna especificada en la clusula where de la instruccin externa debe ser compatible en cuanto a sus combinaciones con la columna especificada en la lista de seleccin de la subconsulta. No se permiten tipos de datos text e image en las subconsultas. Las subconsultas no pueden manipular sus resultados internamente, es decir, una subconsulta no puede incluir la clusula order by, la clusula compute ni la palabra clave into . Las subconsultas correlacionadas (repetidas) no se permiten en la clusula select de un cursor actualizable definido por declare cursor . Hay un lmite de 16 niveles de anidacin. El nmero mximo de subconsultas a cada lado de una unin es de 16.

Calificacin de nombres de columna En el siguiente ejemplo, la columna pub_id de la clusula where , de la consulta externa, est implcitamente calificada por el nombre de tabla publishers de la clusula from , de la consulta externa. La referencia a pub_id en la lista de seleccin de la subconsulta est calificada por la clusula from de la subconsulta, es decir, por la tabla titles : select pub_name from publishers where pub_id in (select pub_id from titles where type = "business")
Page 74 of 280

La regla general es que los nombres de columna de una instruccin estn implcitamente calificados por la tabla referenciada en la clusula from del mismo nivel. Este es el aspecto de la consulta cuando se detallan todas estas suposiciones implcitas: select pub_name from publishers where publishers.pub_id in (select titles.pub_id from titles where type = "business") Nunca es incorrecto indicar explcitamente el nombre de una tabla, y siempre es posible ignorar las suposiciones implcitas relativas a los nombres de las tablas calificando dichos nombres de forma explcita. Subconsultas con nombres de correlacin Como se explic en el Captulo 4, "Combinaciones: recuperacin de datos de varias tablas", los nombres de correlacin de tabla en las autocombinaciones son necesarios porque la tabla autocombinada aparece en dos roles distintos. Los nombres de correlacin tambin pueden emplearse en consultas anidadas que hacen referencia a la misma tabla en una consulta interna y en otra externa. Por ejemplo, los autores que viven en la misma ciudad que Livia Karsen pueden encontrarse mediante esta subconsulta: select au1.au_lname, au1.au_fname, au1.city from authors au1 where au1.city in (select au2.city from authors au2 where au2.au_fname = "Livia" and au2.au_lname = "Karsen") au_lname au_fname city ----------- --------------Green Marjorie Oakland Straight Dick Oakland Stringer Dirk Oakland MacFeather Stearns Oakland Karsen Livia Oakland (5 rows affected) Los nombres de correlacin explcita dejan claro que la referencia a authors en la subconsulta no tiene el mismo significado que la referencia a authors en la consulta externa. Sin la correlacin explcita, la subconsulta tiene este aspecto: select au_lname, au_fname, city from authors where city in (select city from authors where au_fname = "Livia" and au_lname = "Karsen") La consulta anterior, y otras instrucciones en las que la subconsulta y la consulta externa hacen referencia a la misma tabla, puede definirse de forma alternativa como una autocombinacin: select au1.au_lname, au1.au_fname, au1.city from authors au1, authors au2 where au1.city = au2.city and au2.au_lname = "Karsen" and au2.au_fname = "Livia" Es posible que los resultados de una subconsulta redefinida como una combinacin no aparezcan en el mismo orden, y la combinacin puede necesitar la palabra clave distinct para eliminar los duplicados.
Page 75 of 280

Niveles mltiples de anidacin Una subconsulta puede incluir otra subconsulta o varias. En una instruccin es posible anidar hasta 16 subconsultas. Un ejemplo de problema que puede resolverse usando una instruccin con mltiples niveles de consultas anidadas es "buscar los nombres de los autores que hayan participado en la redaccin de al menos un libro conocido de informtica". select au_lname, au_fname from authors where au_id in (select au_id from titleauthor where title_id in (select title_id from titles where type = "popular_comp") ) au_lname au_fname ---------------------- -----------Carson Cheryl Dull Ann Hunter Sheryl Locksley Chastity (4 rows affected) La consulta ms externa selecciona los nombres de todos los autores, la siguiente busca las IDs de los autores y la ms interna devuelve los nmeros de ID de ttulo PC1035, PC8888 y PC9999. Esta consulta tambin puede expresarse como una combinacin: select au_lname, au_fname from authors, titles, titleauthor where authors.au_id = titleauthor.au_id and titles.title_id = titleauthor.title_id and type = "popular_comp" Subconsulta en instrucciones update , delete e insert Las subconsultas pueden anidarse en instrucciones update , delete e insert , as como en instrucciones select . Note: La ejecucin de estos ejemplos de consulta cambiar la base de datos pubs2 . Para obtener una copia limpia de la base de datos de muestra, es necesario solicitarla al administrador del sistema. La siguiente consulta dobla el precio de todos los libros publicados por New Age Books. La instruccin actualiza la tabla titles ; su subconsulta hace referencia a la tabla publishers . update titles set price = price * 2 where pub_id in (select pub_id from publishers where pub_name = "New Age Books") Una instruccin update equivalente que usa una combinacin es: update titles set price = price * 2 from titles, publishers where titles.pub_id = publishers.pub_id and pub_name = "New Age Books" Con esta instruccin select anidada pueden quitarse todos los registros de ventas de libros de negocios: delete salesdetail where title_id in (select title_id
Page 76 of 280

from titles where type = "business") Una instruccin delete equivalente que usa una combinacin es: delete salesdetail from salesdetail, titles where salesdetail.title_id = titles.title_id and type = "business" Subconsultas en instrucciones condicionales Las subconsultas tambin pueden utilizarse en instrucciones condicionales. La subconsulta anterior que elimin todos los registros de ventas de libros de negocios podra volver a escribirse, como se muestra en el ejemplo siguiente, para verificar los registros antes de eliminarlos: if exists (select title_id from titles where type = "business") begin delete salesdetail where title_id in (select title_id from titles where type = "business") end Uso de subconsultas en lugar de una expresin En Transact-SQL, una subconsulta puede usarse prcticamente en cualquier lugar que permita una expresin en las instrucciones select , update , insert o delete . No es posible utilizar subconsultas en una lista order by . A continuacin se ofrecen algunos ejemplos que ilustran el modo en que puede utilizarse esta mejora de Transact-SQL. La siguiente instruccin busca los ttulos y tipos de libros escritos por autores residentes en California y publicados en ese mismo estado: select title, type from titles where title in (select title from titles, titleauthor, authors where titles.title_id = titleauthor.title_id and titleauthor.au_id = authors.au_id and authors.state = "CA") and title in (select title from titles, publishers where titles.pub_id = publishers.pub_id and publishers.state = "CA") title type -------------------------------------------The Busy Executive's Database Guide business Cooking with Computers: Surreptitious Balance Sheets business Straight Talk About Computers business But Is It User Friendly? popular_comp Secrets of Silicon Valley popular_comp Net Etiquette popular_comp (6 rows affected) La siguiente instruccin selecciona los ttulos de libros que vendieron ms de 5000 copias, muestra sus precios y el precio del libro ms caro: select title, price, (select max(price) from titles)
Page 77 of 280

from titles where total_sales > 5000 title ----------------------------------You Can Combat Computer Stress! The Gourmet Microwave But Is It User Friendly? Fifty Years in Buckingham Palace Kitchens Tipos de subconsultas Existen dos tipos bsicos de subconsultas:

price ----2.99 2.99 22.95 11.95

-----22.95 22.95 22.95 22.95

Las subconsultas introducidas con un operador de comparacin sin modificar y que deben devolver un solo valor se conocen como subconsultas de expresin . Las subconsultas que operan en listas introducidas con in o con un operador de comparacin modificado por any o all , o bien las subconsultas que constituyen una prueba de existencia, introducidas con exists , se conocen como subconsultas de predicado cuantificado .

Las subconsultas de ambos tipos pueden ser correlacionadas (repetidas) o no correlacionadas.

Una subconsulta no correlacionada puede evaluarse como una consulta independiente. En trminos conceptuales, los resultados de la subconsulta se usan en la instruccin principal, o consulta externa. Esta no es la forma real en que SQL Server procesa las instrucciones con subconsultas. Las subconsultas no correlacionadas pueden definirse alternativamente como combinaciones y SQL Server las procesa como combinaciones. Una subconsulta correlacionada no puede evaluarse como una consulta independiente, pero puede hacer referencia a las columnas de la tabla especificada en la lista from de la consulta externa. Las subconsultas correlacionadas se explican en detalle al final de este captulo.

Las siguientes secciones explican los distintos tipos de subconsultas. Subconsultas de expresin Las subconsultas de expresin se introducen con uno de los operadores de comparacin = , != , <> , > , >= , < , !> , !< o < , y su formato general es el siguiente: [Comienzo de instruccin o subconsulta select , insert , update , delete ] where expression comparison_operator ( subquery )

[Fin de instruccin o subconsulta select , insert , update , delete ] Las subconsultas introducidas con un operador de comparacin sin modificar, es decir, un operador de comparacin que no va seguido de any ni all , deben tener como resultado un solo valor. Si una subconsulta de este tipo devuelve ms de un valor, SQL Server genera un mensaje de error. Lo ideal es que, para usar una subconsulta introducida con un operador de comparacin sin modificar, el usuario est suficientemente familiarizado con sus datos y con la naturaleza del problema para tener la certeza de que la subconsulta va a devolver un valor. Por ejemplo, supongamos que cada editor est ubicado en una sola ciudad. Para buscar los nombres de los autores que viven en la ciudad donde se encuentra Algodata Infosystems, escribiremos una instruccin con una subconsulta introducida con el operador de comparacin = : select au_lname, au_fname from authors where city = (select city from publishers where pub_name = "Algodata Infosystems") au_lname au_fname -------------- -------------Carson Cheryl
Page 78 of 280

Bennet

Abraham

(2 rows affected) Uso de funciones agregadas escalares para garantizar un solo valor Las subconsultas introducidas con operadores de comparacin sin modificar incluyen frecuentemente funciones agregadas escalares, ya que las mismas devuelven un solo valor. Por ejemplo, esta instruccin busca los nombres de todos los libros cuyo precio es superior al precio mnimo actual: select title from titles where price > (select min(price) from titles) title --------------------------------------------------The Busy Executive's Database Guide Cooking with Computers: Surreptitious Balance Sheets Straight Talk About Computers Silicon Valley Gastronomic Treats But Is It User Friendly? Secrets of Silicon Valley Computer Phobic and Non-Phobic Individuals: Behavior Variations Is Anger the Enemy? Life Without Fear Prolonged Data Deprivation: Four Case Studies Emotional Security: A New Algorithm Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean Fifty Years in Buckingham Palace Kitchens Sushi, Anyone? (14 rows affected)

group by y having en subconsultas de expresin


Dado que las subconsultas introducidas con operadores de comparacin sin modificar deben devolver un solo valor, no pueden incluir clusulas group by y having , a no ser que se sepa con certeza que estas clusulas devolvern un valor nico. Por ejemplo, esta consulta busca los libros cuyo precio es superior al del libro con el precio ms bajo dentro de la categora trad_cook : select title from titles where price > (select min(price) from titles group by type having type = "trad_cook") Uso de distinct con subconsultas de expresin Las subconsultas introducidas con operadores de comparacin sin modificar, a menudo incluyen la palabra clave distinct para devolver un solo valor. Por ejemplo, sin distinct , la siguiente subconsulta no se ejecutara de forma correcta porque devolvera ms de un valor: select pub_name from publishers where pub_id = (select distinct pub_id from titles where pub_id = publishers.pub_id)
Page 79 of 280

Subconsultas de predicado cuantificado Las subconsultas de predicado cuantificado, que devuelven 0 o un valor superior, son subconsultas en una clusula where o having que estn conectadas por any , all , in o exists . Los operadores de subconsulta any o all modifican los operadores de comparacin.

Las subconsultas introducidas con un operador de comparacin modificado, que pueden incluir una clusula group by o having , tienen este formato general: [Comienzo de instruccin o subconsulta select , insert , update , delete ] where ( expression subquery ) comparison_operator [any | all]

[Final de instruccin o subconsulta select , insert , update , delete ]

Las subconsultas introducidas con in o not in tienen este formato general:[Comienzo de instruccin o subconsulta select , insert , update , delete ] where expression [not] in ( subquery )

[Final de instruccin o subconsulta select , insert , update , delete ]

Las subconsultas introducidas con exists o not exists constituyen pruebas de existencia cuyo formato general es el siguiente: [Comienzo de instruccin o subconsulta select , insert , update , delete ] where [not] exists ( subquery )

[Final de instruccin o subconsulta select , insert , update , delete ] Aunque las subconsultas de predicado cuantificado permiten el uso de la palabra clave distinct , la subconsulta siempre se procesa como si distinct no estuviera incluido. Subconsultas con any y all Las palabras clave all y any modifican un operador de comparacin que introduce una subconsulta. Tomando el operador de comparacin > como ejemplo:

>all significa mayor que todos los valores o mayor que el valor mximo. Por ejemplo, >all (1, 2, 3) significa mayor que 3. >any significa mayor que algn valor o mayor que el valor mnimo. Por ejemplo, >any (1, 2, 3) significa mayor que 1.

Si una subconsulta se introduce con all y un operador de comparacin no devuelve ningn valor, toda la consulta fracasa. El uso de all y any puede resultar complicado porque las computadoras no toleran la ambigedad que estas palabras a veces tienen en ingls. Por ejemplo, podra formularse la pregunta "Qu libros tuvieron un anticipo superior al de cualquier libro editado por New Age Books?". Esta pregunta puede parafrasearse para que su "traduccin" en SQL sea ms clara: "Qu libros tuvieron un anticipo superior al mximo anticipo pagado por New Age Books?". En este caso se necesita la palabra clave all , y no any : select title from titles where advance > all (select advance from publishers, titles where titles.pub_id = publishers.pub_id and pub_name = "New Age Books") title ---------------------------------------The Gourmet Microwave
Page 80 of 280

(1 row affected) Para cada ttulo, la consulta externa obtiene los ttulos y anticipos de la tabla titles y los compara con los anticipos pagados por New Age Books devueltos por la subconsulta. La consulta externa examina el valor mximo de la lista y determina si el ttulo en cuestin ha tenido un anticipo todava mayor. > all significa mayor que todos los valores En el contexto de una subconsulta, >all significa que, para que una fila cumpla una condicin especfica en la consulta externa, el valor de la columna que introduce la subconsulta debe ser mayor que todos los valores devueltos por la subconsulta. Por ejemplo, para buscar los libros cuyo precio es superior al del libro con el precio mximo dentro de la categora mod_cook : select title from titles where price > all (select price from titles where type = "mod_cook") title --------------------------------------------------But Is It User Friendly? Secrets of Silicon Valley Computer Phobic and Non-Phobic Individuals: Behavior Variations Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean (4 rows affected) Sin embargo, si el conjunto devuelto por la consulta interna contiene un valor NULL, la consulta devuelve 0 filas. Esto se debe a que NULL significa "valor desconocido", y es imposible saber si el valor que se est comparando es mayor que un valor desconocido. Por ejemplo, intente encontrar aquellos libros cuyo precio es superior al del libro con el precio mximo dentro de la categora popular_comp : select title from titles where price > all (select price from titles where title_id = "popular_comp") title --------------------------------------------------(0 rows affected) El resultado es 0 filas porque la subconsulta encontr un libro, Net Etiquette , con precio nulo. =all significa igual a todos los valores El operador =all significa igual a todos los valores. Para que una fila cumpla con la condicin especificada en la consulta externa, el valor de la columna que introduce la subconsulta debe ser igual a todos los valores de la lista devuelta por la subconsulta. Por ejemplo, la siguiente consulta busca los autores que viven en la misma ciudad examinando el cdigo postal: select au_fname, au_lname, city from authors where city = all (select city from authors where postalcode like "946%") > any significa mayor que algn valor >any significa que, para que una fila cumpla la condicin especificada en la consulta externa, el valor de la columna que introduce la subconsulta debe ser mayor que al menos uno de los valores de la lista de valores devueltos por la subconsulta.
Page 81 of 280

La siguiente consulta proporciona un ejemplo de una subconsulta introducida por un operador de comparacin modificado por any . La consulta busca todos los ttulos con anticipo superior a los importes pagados en concepto de anticipos por New Age Books. select title from titles where advance > any (select advance from titles, publishers where titles.pub_id = publishers.pub_id and pub_name = "New Age Books") title --------------------------------------------------Sushi, Anyone? Life Without Fear Is Anger the Enemy? The Gourmet Microwave But Is It User Friendly? Secrets of Silicon Valley Straight Talk About Computers You Can Combat Computer Stress! Emotional Security: A New Algorithm The Busy Executive's Database Guide Fifty Years in Buckingham Palace Kitchens Cooking with Computers: Surreptitious Balance Sheets Computer Phobic and Non-Phobic Individuals: Behavior Variations Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean (14 rows affected) Por cada ttulo seleccionado por la consulta externa, la consulta interna busca una lista de importes de los anticipos pagados por New Age Books. La consulta externa examina todos los valores de la lista y determina si el ttulo en cuestin ha recibido un anticipo superior a cualquiera de dichos valores. En otras palabras, el ejemplo busca los ttulos con anticipos iguales o superiores al valor mnimo pagado por New Age Books. Si la subconsulta no devuelve ningn valor, toda la consulta fracasa. =any significa igual que alguno de los valores El operador =any es una verificacin de existencia que equivale a in . Por ejemplo, para buscar los autores que viven en la misma ciudad que cualquier editor, puede usar =any o in : select au_lname, au_fname from authors where city = any (select city from publishers) select au_lname, au_fname from authors where city in (select city from publishers) au_lname au_fname -------------- -------------Carson Cheryl Bennet Abraham (2 rows affected) Sin embargo, el operador !=any es diferente a not in . !=any significa "no = a o no = b o no = c". not in significa "no = a y no = b y no = c". Por ejemplo, digamos que se desea buscar todos los autores que viven en una ciudad donde no hay ningn editor. En tal caso, podra probarse con esta consulta:

Page 82 of 280

select au_lname, au_fname from authors where city != any (select city from publishers) Los resultados incluyen los 23 autores. Esto se debe a que todos los autores viven en alguna ciudad en la que no hay ningn editor, y cada autor vive en una sola ciudad. Lo que ocurre es que la consulta interna busca todas las ciudades donde hay editores y luego, para cada ciudad, la consulta externa busca los autores que no viven ah. A continuacin se ilustra lo que ocurre cuando se usa not in en la misma consulta: select au_lname, au_fname from authors where city not in (select city from publishers) au_lname au_fname -------------- -----------del Castillo Innes Blotchet-Halls Reginald Gringlesby Burt DeFrance Michel Smith Meander White Johnson Greene Morningstar Green Marjorie Straight Dick Stringer Dirk MacFeather Stearns Karsen Livia Dull Ann Hunter Sheryl Panteley Sylvia Ringer Anne Ringer Albert Locksley Chastity O'Leary Michael McBadden Heather Yokomoto Akiko (21 rows affected) Estos son los resultados deseados. Incluyen todos los autores, excepto Cheryl Carson y Abraham Bennet, que viven en Berkeley, donde est la sede de Algodata Infosystems. Los resultados son los mismos que en el ejemplo anterior si se usa el operador !=all , que equivale a not in : select au_lname, au_fname from authors where city != all (select city from publishers) Uso de subconsultas con in Las subconsultas introducidas con la palabra clave in devuelven una lista con 0 y valores superiores. Por ejemplo, esta consulta busca los nombres de los editores que publicaron libros de negocios: select pub_name from publishers where pub_id in (select pub_id from titles where type = "business")
Page 83 of 280

pub_name ---------------------------------------New Age Books Algodata Infosystems (2 rows affected) Esta instruccin se evala en dos pasos. En primer lugar, la consulta interna devuelve los nmeros de identificacin de los editores que publicaron libros de negocios, 1389 y 0736. En segundo lugar, estos valores se usan en la consulta externa, que busca los nombres correspondientes a los nmeros de identificacin en la tabla publishers . Este es el aspecto de la consulta: select pub_name from publishers where pub_id in ("1389", "0736") Esta es otra manera de formular la consulta mediante una subconsulta: select pub_name from publishers where "business" in (select type from titles where pub_id = publishers.pub_id) Tenga presente que la expresin que sigue a la palabra clave where de la consulta externa puede ser una constante, adems de un nombre de columna. Es posible utilizar otros tipos de expresiones, como las combinaciones de constantes y nombres de columna. Las consultas anteriores, al igual que muchas otras subconsultas, pueden formularse alternativamente como consultas de combinacin: select distinct pub_name from publishers, titles where publishers.pub_id = titles.pub_id and type = "business" Tanto esta consulta como las versiones de subconsulta encuentran editores que publicaron libros de negocios. Todas son correctas y generan los mismos resultados, pero quizs sea necesario usar la palabra clave distinct para eliminar los duplicados. Sin embargo, una ventaja del uso de una consulta de combinacin, para este problema y otros similares, en lugar de una subconsulta, es que la consulta de combinacin muestra columnas de varias tablas en los resultados. Por ejemplo, para incluir los ttulos de los libros de negocios en el resultado, tendra que emplear esta combinacin: select pub_name, title from publishers, titles where publishers.pub_id = titles.pub_id and type = "business" pub_name title ----------------------------------------------------------Algodata Infosystems The Busy Executive's Database Guide Algodata Infosystems Cooking with Computers: Surreptitious Balance Sheets New Age Books You Can Combat Computer Stress! Algodata Infosystems Straight Talk About Computers (4 rows affected) El siguiente es otro ejemplo de instruccin que puede formularse con una subconsulta o con una consulta de combinacin. La versin de la consulta es: "buscar los nombres de todos los autores secundarios que vivan en California y reciban menos del 30 por cien de los derechos de autor por un libro". Con una subconsulta, la instruccin es: select au_lname, au_fname from authors where state = "CA" and au_id in (select au_id
Page 84 of 280

from titleauthor where royaltyper < 30 and au_ord = 2) au_lname au_fname ------------------------ -----------MacFeather Stearns (1 row affected) La consulta externa genera una lista de los 15 autores que viven en California. A continuacin, se evala la consulta interna que genera una lista con las IDs de los autores que cumplen con las calificaciones. Observe que es posible incluir ms de una condicin en la clusula where , tanto de la consulta interna como de la externa. Con una combinacin, la consulta se expresa de esta manera: select au_lname, au_fname from authors, titleauthor where state = "CA" and authors.au_id = titleauthor.au_id and royaltyper < 30 and au_ord = 2 Una combinacin siempre puede expresarse como una subconsulta. Una subconsulta puede expresarse frecuentemente como una combinacin. Uso de subconsultas con not in Las subconsultas introducidas por la frase de palabras clave not in tambin devuelven una lista con 0 y valores superiores. not in significa "no = a y no = b y not = c". Esta consulta busca los nombres de los editores que no han editado libros de negocios, lo contrario del ejemplo de "Uso de subconsultas con in": select pub_name from publishers where pub_id not in (select pub_id from titles where type = "business") pub_name ---------------------------------------Binnet & Hardley (1 row affected) La consulta es exactamente igual a la anterior, con la excepcin de que not in sustituye a in . S in embargo, esta instruccin no puede convertirse en una combinacin. La combinacin anloga "no igual" tiene un significado diferente: busca los nombres de los editores que publicaron algn libro que no sea de negocios. Las dificultades para interpretar el significado de las combinaciones no basadas en la igualdad se explican con ms detalle en el Captulo 4, "Combinaciones: recuperacin de datos de varias tablas". Uso de subconsultas con not in y NULL Una subconsulta que utiliza not in devuelve un conjunto de valores para cada fila de la consulta externa. Si el valor de esta consulta no se encuentra en el conjunto devuelto por la consulta interna, not in da como resultado TRUE (verdadero) y la consulta externa sita el registro en cuestin en los resultados. Sin embargo, si el conjunto devuelto por la consulta interna no contiene ningn valor coincidente, pero contiene uno NULL, not in devuelve UNKNOWN (desconocido). Esto se debe a que NULL significa "valor desconocido" y es imposible saber si el valor que se est buscando se encuentra en un conjunto con un valor desconocido. La consulta externa omite la fila. Por ejemplo, si se usa la base de datos pubs2 : select pub_name from publishers
Page 85 of 280

where $100.00 not in (select price from titles where titles.pub_id = publishers.pub_id) el resultado es: pub_name -----New Age Books New Age Books es el nico editor que no publica libros cuyo precio es de $100. Binnet & Handley y Algodata Infosystems no aparecen en los resultados de la consulta porque ambos publican un libro cuyo precio no est decidido. Uso de subconsultas con exists Una subconsulta introducida con la palabra clave exists funciona como una prueba de existencia . En otras palabras, la clusula where de la consulta externa comprueba la existencia de las filas devueltas por la subconsulta. La subconsulta no genera datos reales, sino que devuelve un valor TRUE (verdadero) o FALSE (falso). Por ejemplo, la siguiente consulta busca los nombres de todos los editores que publican libros de negocios: select pub_name from publishers where exists (select * from titles where pub_id = publishers.pub_id and type = "business") pub_name ---------------------------------------New Age Books Algodata Infosystems (2 rows affected) Para conceptualizar la solucin de esta consulta, tenga en cuenta el nombre de cada editor. Este valor, hace que la subconsulta devuelva al menos una fila?. En otras palabras, hace que la prueba de existencia de como resultado TRUE?. En los resultados de la consulta anterior, el segundo nombre de editor es Algodata Infosystems, cuyo nmero de identificacin es 1389. Hay alguna fila en la tabla titles en la que pub_id sea 1389 y type sea "business"?. En caso afirmativo, "Algodata Infosystems" debera ser uno de los valores seleccionados. El mismo proceso se repite con los nombres de cada uno de los dems editores. Las subconsultas introducidas por exists se diferencian de otras subconsultas en lo siguiente:

La palabra clave exists no va precedida de nombres de columna, constantes ni otras expresiones. La subconsulta exists da como resultado TRUE o FALSE en lugar de devolver datos. La lista de seleccin de la subconsulta consiste generalmente de un asterisco (*). No es necesario especificar nombres de columna, ya que simplemente se est comprobando la existencia o inexistencia de filas que cumplen las condiciones especificadas en la subconsulta. De lo contrario, las reglas de lista de seleccin de una subconsulta introducida con exists son idnticas a las de una lista de seleccin estndar.

La palabra clave exists es muy importante, porque a menudo no hay ninguna formulacin alternativa de no subconsulta. En la prctica, una subconsulta introducida con exists siempre es una subconsulta correlacionada (consulte "Uso de subconsultas correlacionadas"). Aunque algunas consultas formuladas con exists no pueden expresarse de ninguna otra forma, todas las consultas que utilizan in o un operador de comparacin modificado por any o all pueden expresarse con exists . A continuacin se muestran algunos ejemplos de instrucciones que usan exists y sus alternativas equivalentes. He aqu dos formas de buscar los autores que viven en la misma ciudad que un editor:

Page 86 of 280

select au_lname, au_fname from authors where city =any (select city from publishers) select au_lname, au_fname from authors where exists (select * from publishers where authors.city = publishers.city) au_lname au_fname --------------------------Carson Cheryl Bennet Abraham (2 rows affected) He aqu dos consultas que buscan los ttulos de libros publicados por cualquier editor ubicado en una ciudad cuya inicial sea "B": select title from titles where exists (select * from publishers where pub_id = titles.pub_id and city like "B%") select title from titles where pub_id in (select pub_id from publishers where city like "B%") title --------------------------------------------------The Busy Executive's Database Guide Cooking with Computers: Surreptitious Balance Sheets You Can Combat Computer Stress! Straight Talk About Computers But Is It User Friendly? Secrets of Silicon Valley Net Etiquette Is Anger the Enemy? Life Without Fear Prolonged Data Deprivation: Four Case Studies Emotional Security: A New Algorithm (11 rows affected) Uso de subconsultas con not exist s not exists es exactamente igual que exists , con la excepcin de que la clusula where donde se usa acepta que la subconsulta no devuelva ninguna fila. Por ejemplo, para buscar los nombres de los editores que no publican libros de negocios, la consulta es: select pub_name from publishers where not exists (select * from titles where pub_id = publishers.pub_id and type = "business") pub_name ---------------------------------------Binnet & Hardley (1 row affected)
Page 87 of 280

Esta consulta busca los ttulos que no registran ninguna venta: select title from titles where not exists (select title_id from salesdetail where title_id = titles.title_id) title ----------------------------------------The Psychology of Computer Cooking Net Etiquette (2 rows affected) Bsqueda de intersecciones y diferencias con exists Las subconsultas introducidas con exists y not exists pueden usarse para dos operaciones de la teora de conjuntos: interseccin y diferencia. La interseccin de dos conjuntos contiene todos los elementos pertenecientes a los dos conjuntos originales. La diferencia contiene los elementos pertenecientes slo al primero de los dos conjuntos. La interseccin de authors y publishers en la columna city es el conjunto de ciudades en las que hay un autor y un editor: select distinct city from authors where exists (select * from publishers where authors.city = publishers.city) city -------------------Berkeley (1 row affected) La diferencia entre authors y publishers en la columna city es el conjunto de ciudades donde vive un autor pero no hay ningn editor, es decir, todas las ciudades excepto Berkeley: select distinct city from authors where not exists (select * from publishers where authors.city = publishers.city) city -------------------Gary Covelo Oakland Lawrence San Jose Ann Arbor Corvallis Nashville Palo Alto Rockville Vacaville Menlo Park Walnut Creek San Francisco Salt Lake City (15 rows affected) Uso de subconsultas correlacionadas Muchas de las consultas anteriores podran evaluarse ejecutando la subconsulta una vez, y usando los valores resultantes en la clusula where de la consulta externa; se trata de subconsultas no correlacionadas. En las consultas que incluyen una
Page 88 of 280

subconsulta repetida, o subconsulta correlacionada , la subconsulta depende de la consulta externa para obtener sus valores. Esto significa que la subconsulta se ejecuta de forma iterativa, una vez para cada una de las filas seleccionadas por la consulta externa. Con esta consulta pueden buscarse los nombres de todos los autores que ganan un 100% de derechos de autor sobre un libro: select au_lname, au_fname from authors where 100 in (select royaltyper from titleauthor where au_id = authors.au_id) au_lname au_fname -------------- ---------Carson Cheryl Ringer Albert Straight Dick White Johnson Green Marjorie Panteley Sylvia Locksley Chastity del Castillo Innes Blotchet-Hall Reginald (9 rows affected) Al contrario de lo que ocurre en la mayor parte de las subconsultas anteriores, la subconsulta de esta instruccin no puede resolverse de forma independiente con respecto a la consulta principal. Dicha subconsulta precisa un valor para authors . au_id , pero este valor es una variable: cambia a medida que SQL Server examina las distintas filas de la tabla authors . Este es el modo en que se evala la consulta anterior: Transact-SQL tiene en cuenta todas las filas de la tabla authors para su inclusin en los resultados utilizando el valor de cada fila para la consulta interna. Por ejemplo, supongamos que Transact-SQL examina primero la fila de Cheryl Carson. A continuacin, authors.au_id toma el valor "238-95-7766", que Transact-SQL usa para la consulta interna: select royaltyper from titleauthor where au_id = "238-95-7766" El resultado es 100, de forma que la consulta externa evala como: select au_lname, au_fname from authors where 100 in (100) Dado que la condicin where es verdadera, la fila de Cheryl Carson se incluye en los resultados. Si se realiza el mismo procedimiento con la fila de Abraham Bennet, observar que esta fila no aparece en los resultados. Subconsultas correlacionadas con nombres de correlacin Una subconsulta correlacionada puede usarse para buscar los tipos de libros publicados por ms de un editor: select distinct t1.type from titles t1 where t1.type in (select t2.type from titles t2 where t1.pub_id != t2.pub_id) type -------------------business psychology (2 rows affected) Para distinguir los dos roles donde aparece la tabla titles , son necesarios los nombres de correlacin en la consulta siguiente. Esta consulta anidada equivale a la consulta de autocombinacin:
Page 89 of 280

select distinct t1.type from titles t1, titles t2 where t1.type = t2.type and t1.pub_id != t2.pub_id Subconsultas correlacionadas con operadores de comparacin Las subconsultas de expresin pueden ser subconsultas correlacionadas. Por ejemplo, para buscar las ventas de libros de psicologa donde la cantidad es menor que el promedio de ventas de ese ttulo: select s1.ord_num, s1.title_id, s1.qty from salesdetail s1 where title_id like "PS%" and s1.qty < (select avg(s2.qty) from salesdetail s2 where s2.title_id = s1.title_id) A continuacin se muestran los resultados de esta consulta: ord_num -----------------91-A-7 91-A-7 55-V-7 AX-532-FED-452-2Z7 BA71224 NB-3.142 NB-3.142 NB-3.142 ZD-123-DFG-752-9G8 91-A-7 356921 (11 rows affected) La consulta externa selecciona las filas de la tabla sales (o "s1" ) una a una. La subconsulta calcula la cantidad promedio de cada venta considerada para su seleccin en la consulta externa. Por cada valor posible de s1 , Transact-SQL evala la subconsulta e incluye el registro considerado en los resultados, si la cantidad es inferior al promedio calculado. En algunos casos una subconsulta correlacionada es como una instruccin group by . Para buscar los ttulos cuyo precio es mayor que el promedio correspondiente a los libros de su mismo tipo, esta sera la consulta: select t1.type, t1.title from titles t1 where t1.price > (select avg(t2.price) from titles t2 where t1.type = t2.type) type title ---------------------------------------------business The Busy Executive's Database Guide business Straight Talk About Computers mod_cook Silicon Valley Gastronomic Treats popular_comp But Is It User Friendly? psychology Computer Phobic and Non-Phobic Individuals: Behavior Variations psychology Prolonged Data Deprivation: Four Case Studies trad_cook Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean (7 rows affected) Por cada valor posible de t1 , Transact-SQL evala la subconsulta e incluye la fila en los resultados, si el valor del precio correspondiente a esa fila es mayor que el promedio calculado. No es necesario agrupar por tipos explcitamente, porque las filas para las que se calcula el promedio del precio estn restringidas por la clusula where de la subconsulta.
Page 90 of 280

title_id -------PS3333 PS2106 PS2106 PS7777 PS7777 PS2091 PS7777 PS3333 PS3333 PS7777 PS3333

qty --90 30 31 125 200 200 250 345 750 180 200

Subconsultas correlacionadas en una clusula having Las subconsultas de predicado cuantificado pueden ser subconsultas correlacionadas. Este ejemplo de una subconsulta correlacionada en la clusula having de una consulta externa busca los tipos de libros cuyo mximo anticipo es ms del doble del promedio de un grupo dado: select t1.type from titles t1 group by t1.type having max(t1.advance) >=any (select 2 * avg(t2.advance) from titles t2 where t1.type = t2.type) type ---------mod_cook (1 row affected) En este caso, la subconsulta se evala una vez para cada grupo definido en la consulta externa, es decir, una vez para cada tipo de libro. Chapter 6

Uso y creacin de tipos de datos


Es posible utilizar los tipos de datos del sistema SQL Server al definir una columna en las instrucciones create table o alter table , una variable en la instruccin declare , o un parmetro en la instruccin create procedure . Dichos comandos se describen ms adelante en este manual. Tambin es posible crear y utilizar tipos de datos definidos por el usuario en esos comandos. Este captulo trata lo siguiente:

Introduccin general a los tipos de datos Los distintos tipos de datos del sistema suministrados por SQL Server Cmo realizar conversiones entre tipos de datos Cmo funciona la aritmtica de modo mixto en la jerarqua de tipos de datos Cmo crear tipos de datos definidos por el usuario Cmo obtener informacin acerca de un tipo de datos Qu son los tipos de datos Transact-SQL? Uso de tipos de datos suministrados por el sistema Conversin de tipos de datos Aritmtica de modo mixto y jerarqua de tipos de datos Creacin de tipos de datos definidos por el usuario Obtencin de informacin sobre tipos de datos

Qu son los tipos de datos Transact-SQL? En Transact-SQL, los tipos de datos especifican el tipo de informacin, tamao y formato de almacenamiento de columnas de tablas, parmetros de procedimientos almacenados y variables locales. Por ejemplo, el tipo de datos entero ( int ) se emplea para guardar nmeros enteros que pertenezcan al margen de ms o menos 2 31, y el tipo de datos entero diminuto ( tinyint ) almacena slo los nmeros enteros comprendidos entre 0 y 255. SQL Server suministra algunos tipos de datos del sistema y dos tipos de datos definidos por el usuario: timestamp y sysname . Es posible utilizar el procedimiento del sistema sp_addtype para crear tipos de datos definidos por el usuarios en base a los tipos de datos del sistema (los tipos de datos definidos por el usuario se describen en "Creacin de tipos de datos definidos por el usuario").

Page 91 of 280

Es preciso especificar un tipo de datos del sistema o uno definido por el usuario al declarar una columna, una variable local o un parmetro. En el siguiente ejemplo, se utilizan los tipos de datos del sistema char , numeric y money para definir las columnas en la instruccin create table : create table sales_daily (stor_id char(4) ord_num numeric(10,0) ord_amt money) En el ejemplo siguiente, se utiliza el tipo de datos del sistema bit para definir la variable local en la instruccin declare : declare @switch bit En captulos posteriores se describe con ms detalle cmo declarar columnas, variables locales y parmetros utilizando los tipos de datos descritos en este captulo. Para determinar los tipos de datos definidos para las columnas de tablas existentes, use el procedimiento del sistema sp_help . Uso de tipos de datos suministrados por el sistema La tabla siguiente enumera los tipos de datos suministrados por el sistema para distintos tipos de informacin, los sinnimos reconocidos por SQL Server, y el margen y tamao de almacenamiento de cada uno. Los tipos de datos del sistema se imprimen en minsculas, aunque SQL Server permite introducirlos en maysculas o en minsculas. ( timestamp y sysname , como todos los tipos de datos definidos por el usuario, pueden utilizarse en maysculas o minsculas.) La mayora de los tipos de datos suministrados por SQL Server no son palabras reservadas y pueden utilizarse para asignar nombre a otros objetos. Tabla 6-1: Tipos de datos del sistema SQL Server Tipos de datos por categora Sinnimos Margen Bytes de almacenamiento

Numricos exactos: enteros

tinyint smallint int


Numricos exactos: decimales

0 a 255

1 2 4

integer

215 -1 (32.767) a -215 (-32.768) 231 -1 (2.147.483.647) a -231 (-2.147.483.648) 1038 -1 a -1038

numeric (p, s) dec decimal (p, s)


Numricos aproximados

2 a 17 2 a 17 4u8 8 4

1038 -1 a -1038 dependiente de la mquina dependiente de la mquina dependiente de la mquina 214.748,3647 a -214.748,3648 922.337.203.685.477,5807 a -922.337.203.685.477,5808 Del 1 de enero de 1900 al 6 de junio de 2079 Del 1 de enero de 1753 al 31 de diciembre de 9999

float (precision) double precision real


Monetarios

smallmoney money
Fecha/hora

4 8

smalldatetime datetime
Caracteres

4 8

Page 92 of 280

char(n) varchar(n) nchar(n) nvarchar(n) text


Binarios

character character varying, char varying national character, national char nchar varying, national char varying, national character varying

255 caracteres o menos 255 caracteres o menos 255 caracteres o menos 255 caracteres o menos 231 -1 (2.147.483.647) bytes o menos

n
longitud de entrada real

n * @@ncharsize @@ncharsize * nmero de


caracteres

0 o mltiplo de 2K 255 bytes o menos 255 bytes o menos

binary(n) varbinary(n) image


Bit

n
longitud de entrada real

231 -1 (2.147.483.647) bytes o menos 0 o mltiplo de 2K 1 (un byte contiene hasta 8 columnas bit )

bit

0o1

A continuacin, se describe cada tipo de datos. Tipos numricos exactos: enteros SQL Server proporciona tres tipos de datos, tinyint , smallint e int para almacenar enteros (nmeros enteros). Estos tipos son numricos exactos, ya que mantienen su precisin durante las operaciones aritmticas. Elija el tipo de entero en base al tamao previsto de los nmeros que van a almacenarse. El tamao de almacenamiento interno vara en funcin del tipo de datos. Tabla 6-2: Tipos de datos enteros Tipo de datos Almacena Nmeros enteros entre 0 y 255, ambos incluidos. (No se admiten nmeros negativos.) Nmeros enteros entre 215 -1 y -215 (32.767 y -32.768), ambos incluidos. Nmeros enteros entre 231 - 1 y -231 (2.147.483.647 y -2.147.483.648), ambos incluidos. Bytes de almacenamiento 1 2 4

tinyint smallint int

Tipos numricos exactos: nmeros decimales SQL Server proporciona dos tipos de datos numricos exactos adicionales: numeric y decimal , para nmeros que incluyen comas decimales. Los datos almacenados en las columnas numeric y decimal se comprimen para ahorrar espacio en disco, y conservan su precisin hasta el dgito de menor significacin despus de realizar operaciones aritmticas. Los tipos numeric y decimal son idnticos en todos los aspectos, excepto uno: slo los tipos numeric con una escala de 0 pueden utilizarse para la columna IDENTITY. Los tipos numricos exactos aceptan dos parmetros opcionales: p recision y scale , incluidos entre parntesis y separados por una coma: datatype [( precision [, scale ])]

SQL Server define cada combinacin de precisin y escala como un tipo de datos distinto. Por ejemplo, numeric (10,0) y numeric (5,0) son dos tipos de datos diferentes. La precisin y la escala determinan el margen de valores que puede almacenarse en una columna decimal o numeric :
Page 93 of 280

La precisin especifica el nmero mximo de dgitos decimales que pueden almacenarse en la columna e incluye todos los dgitos a la derecha o a la izquierda de la coma decimal. Es posible especificar una precisin de 1 a 38 dgitos, o utilizar la precisin predeterminada de 18 dgitos. La escala especifica el nmero mximo de dgitos que pueden almacenarse a la derecha de la coma decimal. Observe que la escala debe ser menor o igual que la precisin. Es posible especificar una escala de 0 a 38 dgitos, o utilizar la escala predeterminada de 0 dgitos.

Los tipos numricos exactos con una escala de 0 se muestran sin coma decimal. Si se introduce un valor que supera la precisin o la escala para la columna, SQL Server seala la entrada como un error. El tamao de almacenamiento para una columna numeric o decimal depende de su precisin. El requisito mnimo de almacenamiento es de 2 bytes para una columna de 1 o 2 dgitos. El tamao de almacenamiento aumenta 1 byte por cada 2 dgitos adicionales de precisin, hasta un mximo de 17 bytes. Tipos de datos numricos aproximados SQL Server proporciona tres tipos numricos aproximados: float , double precision y real , para datos numricos que pueden tolerar el redondeo durante operaciones aritmticas. Utilice los tipos de datos numricos aproximados para datos que cubran un amplio margen de valores. Estos admiten todas las funciones agregadas y todas las operaciones aritmticas, excepto mdulo (%). Los tipos de datos real y double precision se crean en base a tipos suministrados por el sistema operativo. El tipo float acepta una precisin opcional entre parntesis. Las columnas float con una precisin de 1-15 se almacenan como real ; las que tienen una precisin superior se almacenan como double precision . La precisin de margen y almacenamiento para los tres tipos depende de la mquina. En la tabla siguiente se muestra el margen, la precisin de visualizacin y el tamao de almacenamiento para cada tipo numrico aproximado. Observe que isql slo muestra seis nmeros significativos despus de la coma decimal y que redondea el resto: Tabla 6-3: Tipos de datos numricos aproximados Tipo de datos Bytes de almacenamiento 4 para d efault precision < 16, 8 para d efault precision >= 16 8 4

float [( default precision )] double precision real

Tipos de datos de caracteres Utilice los tipos de datos de caracteres para almacenar cadenas compuestas de letras, nmeros y smbolos incluidos entre comillas simples o dobles . La palabra clave like puede utilizarse para buscar determinados caracteres en estas cadenas y las funciones de cadena incorporadas a fin de manipular su contenido. Las cadenas compuestas de nmeros pueden convertirse a tipos de datos numricos exactos y aproximados con la funcin convert , y utilizarse posteriormente en operaciones aritmticas. El tipo de datos char ( n ) almacena cadenas de longitud fija y el tipo de datos varchar ( n ) almacena cadenas de longitud variable, en juegos de caracteres de un solo byte, como English. Sus parejas de caracteres nacionales, nchar ( n ) y nvarchar ( n ) , almacenan cadenas de longitud fija y variable en juegos de caracteres multibyte, como Japanese . Es posible especificar el nmero mximo de caracteres con n , o utilizar la longitud de columna predeterminada de un carcter. Para cadenas ms largas que bytes, utilice el tipo de datos text . Tabla 6-4: Tipos de datos de caracteres Tipo de datos Almacena Datos de longitud fija, como nmeros de seguridad social o cdigos postales Datos, como nombres, cuya longitud puede variar considerablemente Datos de longitud fija en juegos de caracteres multibyte Bytes de almacenamiento

char(n) varchar(n) nchar(n)

n
Nmero real de caracteres introducidos

n * @@ncharsize
Page 94 of 280

nvarchar(n) text

Datos de longitud variable en juegos de caracteres multibyte Hasta 2.147.483.647 bytes de caracteres imprimibles en listas enlazadas de pginas de datos

Nmero real de caracteres * @@ncharsize 0 sin inicializar; un mltiplo de 2K despus de la inicializacin

SQL Server trunca las entradas segn la longitud de columna especificada sin indicar ningn mensaje de advertencia o error, a menos que se defina string_rtruncation on . Consulte el comando set en el Manual de Referencia de SQL Server para obtener ms informacin. La cadena vaca , "" or '' , se almacena como un espacio nico en lugar de como NULL. De este modo, "abc" + "" + "def" es equivalente a "abc def", no a "abcdef". El comportamiento de las columnas de longitud fija y variable es algo distinto:

Los datos de las columnas de longitud fija se rellenan con espacios en blanco hasta la longitud de columna. Para el tipo de datos char , el tamao de almacenamiento es n bytes; para el tipo de datos nchar , es n veces la longitud de caracteres nacionales promedio ( @@ncharsize ). Al crear una columna char o nchar que permite valores nulos, SQL Server la convierte automticamente en una columna varchar o nvarchar y utiliza las reglas de almacenamiento para dichos tipos de datos. (No ocurre as para las variables y parmetros char y nchar .) Los datos de las columnas de longitud variable se despojan de los espacios en blanco posteriores; el tamao de almacenamiento es la longitud real de los datos. Para columnas varchar , es el nmero de caracteres; para columnas nvarchar , es el nmero de caracteres por la longitud de caracteres promedio. Los datos de caracteres de longitud variable necesitan menos espacio que los de longitud fija, pero el acceso a ellos es algo ms lento.

El tipo de datos text almacena hasta 2.147.483.647 bytes de caracteres imprimibles en listas enlazadas de pginas de datos independientes. Para ahorrar espacio de almacenamiento, defina las columnas text como NULL. Al inicializar una columna text con un comando insert o update no nulo, SQL Server asigna un puntero de texto y una pgina completa de datos de 2K para contener el valor. Cada pgina almacena un mximo de 1.800 bytes de datos. Para aadir datos sin guardar grandes bloques de texto en el diario de transacciones, utilice writetext . Consulte el Manual de Referencia de SQL Server para obtener informacin detallada. Tipos de datos binarios Los tipos de datos binarios almacenan datos binarios en bruto, como imgenes, en una notacin semejante a la hexadecimal. Los datos binarios comienzan con los caracteres "0x" e incluyen cualquier combinacin de dgitos, as como las letras A-F maysculas y minsculas. Note: SQL Server manipula los tipos binarios segn el tipo especfico de plataforma. Para datos hexadecimales reales, utilice las funciones hextoint y inttohex . Consulte el Captulo 10, "Uso de funciones incorporadas en consultas". Utilice los tipos de datos binary(n) y varbinary(n) para almacenar datos de hasta 255 bytes de longitud. Cada byte de almacenamiento contiene 2 dgitos binarios. Especifique la longitud de columna con n , o utilice la longitud predeterminada de un byte. Si introduce un valor superior a n , SQL Server trunca la entrada en la longitud especificada sin emitir ningn mensaje de advertencia o de error.

Utilice el tipo binario de longitud fija binary(n) , para datos donde se espera que todas las entradas tengan una longitud similar. Debido a que las entradas de las columnas binary se rellenan con ceros en toda la longitud de la columna, es posible que necesiten ms espacio de almacenamiento que las de las columnas varbinary , pero el acceso a stas ltimas ser algo ms rpido. Utilice el tipo binario de longitud variable varbinary(n) , para datos cuya longitud se espera que vare en gran medida. El tamao de almacenamiento es el tamao real de los valores de datos introducidos, y no la longitud de columna. Los ceros posteriores se truncan.

Al crear una columna binary que admite valores nulos, SQL Server la convierte automticamente en una columna varbinary y utiliza las reglas de almacenamiento para dicho tipo de datos. Es posible buscar cadenas de caracteres binarios con la palabra clave like y realizar operaciones con ellas mediante las funciones de cadena incorporadas. Debido a que el formato exacto donde se introduce un valor determinado depende del hardware que est utilizndose , los clculos en los que se utilizan datos binarios pueden producir resultados distintos en plataformas diferentes. Utilice el tipo de datos image para almacenar bloques mayores de datos binarios en pginas de datos externas. Una columna image puede almacenar hasta 2.147.483.647 bytes de datos en listas enlazadas de pginas de datos, aparte de otros datos para la tabla. Al inicializar una columna i mage con un comando insert o update no nulo, SQL Server asigna un puntero de texto y una pgina completa de datos de 2K para contener el valor. Cada pgina almacena un mximo de 1.800 bytes.
Page 95 of 280

Para ahorrar espacio de almacenamiento, defina las columnas image como NULL. Para aadir datos image sin guardar grandes bloques de texto en el diario de transacciones, utilice writetext . Consulte el Manual de Referencia de SQL Server para obtener informacin detallada. En la tabla siguiente se resumen los requisitos de almacenamiento para tipos de datos binarios: Tabla 6-5: Tipos de datos binarios Tipo de datos Bytes de almacenamiento

binary(n) varbinary(n) image

n
Longitud real de entrada 0 sin inicializar; un mltiplo de 2K despus de la inicializacin

Tipos de datos monetarios Los tipos de datos monetarios money y smallmoney , almacenan datos monetarios. Estos tipos de datos pueden utilizarse para dlares U.S. y para otras monedas decimales, aunque SQL Server no proporciona medios para convertir una moneda a otra. Pueden utilizarse todas las operaciones aritmticas, excepto mdulo, y todas las funciones agregadas, con datos money y smallmoney . La precisin de money y de smallmoney es de hasta 1/10000 de una unidad monetaria, pero los valores se redondean hasta dos posiciones decimales por razones de visualizacin. El formato de impresin predeterminado coloca un punto detrs de cada tres dgitos. En la siguiente tabla se resumen los requisitos de margen y almacenamiento para los tipos de datos monetarios: Tabla 6-6: Tipos de datos monetarios Tipo de datos Margen Bytes de almacenamiento 8 Valores monetarios entre +922.337.203.685.477,5807 y -922.337.203.685.477,5808

money smallmoney

Valores monetarios entre +214.748,3647 y -214.748,3648 4

Tipos de datos de fecha y hora Utilice los tipos de datos datetime y smalldatetime para almacenar informacin de fecha y hora desde el 1 de enero de 1753 hasta el 31 de diciembre de 9999. Las fechas que no estn comprendidas en este margen deben introducirse, almacenarse y manipularse como valores char o varchar .

Las columnas datetime contienen fechas comprendidas entre el 1 de enero de 1753 y el 31 de diciembre de 9999. Los valores datetime tienen una precisin de hasta 1/300 de segundo en plataformas que admiten este nivel de granularidad. El tamao de almacenamiento es de 8 bytes: 4 bytes para el nmero de das desde la fecha base del 1 de enero de 1900, y 4 bytes para la hora del da. Las columnas smalldatetime contienen fechas comprendidas entre el 1 de enero de 1900 y el 6 de junio de 2079, y su precisin de hasta un minuto. Su tamao de almacenamiento es de 4 bytes: 2 bytes para el nmero de das despus del 1 de enero de 1900, y 2 bytes para el nmero de minutos desde medianoche.

La informacin de fecha y hora debe incluirse entre comillas simples o dobles. Puede introducirse en maysculas o en minsculas, y puede contener espacios entre las partes de los datos. SQL Server reconoce una amplia variedad de formatos de entrada de datos, que se describen en el Captulo 8. Los valores como cero o 00/00/00, que no se reconocen como fechas, se rechazan. El formato de visualizacin predeterminado para las fechas es "Apr 15 1987 10:23PM". Es posible utilizar la funcin convert para unificar ms estilos de visualizacin de fechas. Tambin es posible realizar algunos clculos aritmticos con valores datetime mediante las funciones de fecha incorporadas. En la tabla siguiente se resumen los requisitos de margen y de almacenamiento para los tipos de datos de fecha: Tabla 6-7: Tipos de datos de fecha
Page 96 of 280

Tipo de datos Margen

Bytes de almacenamiento 4

datetime smalldatetime

Del 1 de enero de 1753 al 31 de diciembre de 9999 8 Del 1 de enero de 1900 al 6 de junio de 2079

Tipo de datos bit Utilice columnas bit para tipos de datos verdadero/falso o s/no. Las columnas bit contienen los valores 0 o 1. Se admiten los valores enteros distintos de 0 o 1, pero siempre se interpretan como 1. El tamao de almacenamiento es de 1 byte. Los tipos de datos bit mltiples de una tabla se agrupan en bytes. Por ejemplo, 7 columnas bit caben en 1 byte; 9 columnas bit necesitan 2 bytes. Las columnas de tipo de datos bit no pueden ser NULL y no pueden tener ndices. La columna status de la tabla del sistema syscolumns indica la posicin de desplazamiento exclusiva para las columnas bit. Tipo de datos timestamp SQL Server tambin suministra el tipo de datos definido por el usuario timestamp . Las columnas timestamp son necesarias en tablas a examinarse en aplicaciones Open Client(TM) DB-Library(TM). Cada vez que se inserta o actualiza una fila con una columna timestamp , la columna timestamp se actualiza automticamente. Una tabla slo puede tener una columna del tipo de datos timestamp . Una columna llamada timestamp tendr automticamente el tipo de datos del sistema timestamp . Su definicin es varbinary (8) NULL. Debido a que timestamp es un tipo de datos definido por el usuario, no puede utilizarse para definir otros tipos de datos definidos por el usuario. Es preciso introducirlo como "timestamp", con todas las letras en minsculas. Tipo de datos sysname

sysname es un tipo de datos definido por el usuario incluido en la cinta de instalacin de SQL Server y se utiliza en las tablas del
sistema. Su definicin es:

varchar(30) "not null" No es posible utilizar el tipo de datos sysname para crear una columna. Sin embargo, se puede crear un tipo de datos definido por el usuario con un tipo base de sysname y, luego, se puede emplear el tipo de datos definido por el usuario para crear columnas. Para obtener ms informacin acerca de los tipos de datos definidos por el usuario, consulte "Creacin de tipos de datos definidos por el usuario". Conversin de tipos de datos SQL Server maneja automticamente muchas conversiones de un tipo de datos a otro. Estas conversiones se denominan implcitas. Es posible solicitar explcitamente otras conversiones con las funciones convert , inttohex y hextoint . Sin embargo, no es posible realizar otras conversiones, ni explcita ni automticamente, debido a incompatibilidades entre los tipos de datos. Por ejemplo, SQL Server convierte automticamente expresiones char en datetime por razones de comparacin, si pueden interpretarse como valores datetime , pero es necesario utilizar la funcin convert para convertir char en int . De forma similar, si desea que SQL Server trate los datos enteros como datos de caracteres, hay que usar convert para poder emplear la palabra clave like con ellos. La sintaxis de la funcin convert es: convert ( Por ejemplo: select title, total_sales from titles where convert (char(20), total_sales) like "2%" datatype , expression , [ style ])

Page 97 of 280

El parmetro style opcional se utiliza para convertir valores datetime en tipos de datos char o varchar , a fin de obtener una amplia variedad de formatos de visualizacin de fecha. Consulte el Captulo 10 para obtener informacin detallada sobre las funciones convert , inttohex y hextoint . Aritmtica de modo mixto y jerarqua de tipos de datos Al realizar operaciones aritmticas con valores de distintos tipos de datos, SQL Server debe determinar el tipo de datos y, en algunos casos, la longitud y precisin del resultado. Cada tipo de datos del sistema tiene una jerarqua de tipos de datos , que se almacena en la tabla del sistema systypes . Los tipos de datos definidos por el usuario heredan la jerarqua del tipo del sistema en el que estn basados. La siguiente consulta establece una jerarqua de los tipos de datos de una base de datos. Adems de la informacin que se muestra a continuacin, los resultados de la consulta incluirn informacin sobre cualquier tipo de datos definido por el usuario de la base de datos: select name,hierarchy from systypes order by hierarchy name hierarchy ------------------------------ ------floatn 1 float 2 datetimn 3 datetime 4 real 5 numericn 6 numeric 7 decimaln 8 decimal 9 moneyn 10 money 11 smallmoney 12 smalldatetime 13 intn 14 int 15 smallint 16 tinyint 17 bit 18 varchar 19 sysname 19 nvarchar 19 char 20 nchar 20 varbinary 21 timestamp 21 binary 22 text 23 image 24 (28 rows affected) La jerarqua de tipos de datos determina el resultado de los clculos en que se utilizan distintos tipos de datos. Al valor resultante se le asigna el tipo de datos ms cercano al principio de la lista. En el ejemplo siguiente, qty de la tabla sales se multiplica por royalty de la tabla roysched . qty es del tipo de datos smallint , cuya jerarqua es 16; royalty es del tipo de datos int , cuya jerarqua es 15. De este modo, el tipo de datos del resultado es int . smallint(qty) * int(royalty) = int Uso de tipos de datos money Si est combinando money junto con literales o variables, y necesita obtener resultados del tipo money , emplee literales o variables money : select moneycol * $2.5 from mytable
Page 98 of 280

Si est combinando m oney con tipos de datos float o numeric de valores de columna, utilice la funcin convert : select convert (money, moneycol * percentcol) from debts, interest Determinacin de la precisin y la escala Para los tipos numeric y decimal , cada combinacin de precisin y escala es un tipo de datos de SQL Server distinto. Si realiza operaciones aritmticas con dos valores numeric o decimal , n1 con la precisin p1 y la escala s1, y n2 con la precisin p2 y la escala s2, SQL Server determina la precisin y escala de los resultados como se indica a continuacin: Tabla 6-8: Precisin y escala despus de realizar operaciones aritmtica Operacin Precisin n1 + n2 n1 - n2 n1 * n2 n1 / n2 mx(s1, s2) + mx(p1 -s1, p2 - s2) + 1 mx(s1, s2) + mx(p1 -s1, p2 - s2) + 1 s1 + s2 + (p1 - s1) + (p2 - s2) + 1 mx(s1 + p2 + 1, 6) + p1 - s1 + p2 Escala mx(s1, s2) mx(s1, s2) s1 + s2 mx(s1 + p2 -s2 + 1, 6)

Creacin de tipos de datos definidos por el usuario Si se mejora Transact-SQL al nivel de SQL se puede poner nombre y disear tipos de datos propios para complementar los tipos de datos del sistema. Un tipo de datos definido por el usuario se define en funcin de los tipos de datos del sistema. Es posible asignar un nombre a una definicin de tipo de datos de uso frecuente. Esto facilita la adaptacin personalizada de tipos de datos a las columnas. Note: Para utilizar un tipo de datos definido por el usuario en ms de una base de datos, crelo en la base de datos m odel . De este modo todas las bases de datos creadas reconocern la definicin del tipo de datos definido por el usuario. Al definir un tipo de datos, puede utilizarse como el tipo de datos para cualquier columna de la base de datos. Por ejemplo, tid se emplea como el tipo de datos para columnas de varias tablas de pubs2 : titles . title_id , titleauthor.title_id , sales . title_id y

roysched.title_id.

La ventaja de los tipos de datos definidos por el usuario reside en que es posible vincularles reglas y valores predeterminados para utilizarlos en varias tablas. Para obtener ms informacin sobre este tema, consulte el Captulo 12. El procedimiento del sistema sp_addtype se utiliza para crear tipos de datos de usuario. Toma como parmetros el nombre del tipo de datos de usuario que est crendose, el tipo de datos suministrado por SQL Server a partir del que est crendose, y una especificacin NULL, NOT NULL o IDENTITY opcional. Se puede crear un tipo de datos definido por el usuario utilizando cualquier tipo de datos del sistema menos t imestamp . Los tipos de datos definidos por el usuario tienen la misma jerarqua de tipos de datos que los tipos de datos del sistema en que estn basados. Pero, a diferencia de los tipos de datos suministrados por SQL Server, los nombres de los tipos de datos definidos por el usuario distinguen entre maysculas y minsculas. Sintaxis de sp_addtype : sp_addtype datatypename , phystype [(length) | (precision [, scale])] [, "identity" | nulltype ]

tid se ha definido de la siguiente forma:


sp_addtype tid, "char(6)", "not null" Es preciso incluir un parmetro entre comillas simples o dobles, si contiene un espacio en blanco o algn signo de puntuacin, o si es una palabra clave distinta de null (por ejemplo, identity o sp_helpgroup ). En este ejemplo, es necesario incluir char(6 ) entre comillas debido al parntesis, as como NOT NULL, debido al espacio en blanco. No es preciso incluir tid entre comillas. Especificacin de la longitud, precisin y escala
Page 99 of 280

Al crear un tipo de datos definido por el usuario basado en determinados tipos de datos de SQL Server, es necesario especificar parmetros adicionales:

Para los tipos de datos char , nchar , varchar , nvarchar , binary y varbinary , puede suministrarse un valor de longitud entre parntesis. Si no se suministra, SQL Server utiliza la longitud predeterminada de un carcter. Para el tipo de datos float , puede suministrarse un valor de precisin entre parntesis. Si no se suministra, SQL Server utiliza la precisin predeterminada para la plataforma. Para los tipos de datos numeric y decimal , pueden suministrarse valores de precisin y de escala entre parntesis, separados por una coma. Si no se suministran, SQL Server utiliza la precisin y escala predeterminadas de 18 y 0.

No es posible cambiar la especificacin de longitud, precisin o escala al incluir el tipo definido por el usuario en una instruccin create table . Especificacin del tipo nulo El tipo nulo determina cmo el tipo de datos definido por el usuario trata los valores nulos. Es posible crear un tipo de datos definido por el usuario con un tipo nulo "null", "NULL", "nonull", "NONULL", " not null " o " NOT NULL". Por definicin, los tipos bit e IDENTITY no admiten valores nulos. Si se excluye el tipo nulo, SQL Server emplea el modo nulo definido por la base de datos (de forma predeterminada, NOT NULL). Por razones de compatibilidad con las normas SQL, utilice el procedimiento del sistema sp_dboption para definir la opcin allow nulls by default como true . Es posible escribir sobre el tipo nulo al incluir el tipo de datos definido por el usuario en una instruccin create table . Asociacin de reglas y valores predeterminados con tipos de datos definidos por el usuario Una vez creado un tipo de datos definido por el usuario, es posible utilizar los procedimientos del sistema sp_bindrule y sp_bindefault para asociar reglas y valores predeterminados con el tipo de datos. Con el procedimiento del sistema sp_help , se puede imprimir un informe que enumere las reglas, valores predeterminados e informacin adicional asociados con el tipo de datos. Las reglas y los valores predeterminados se describen en el Captulo 12. Para obtener informacin completa sobre los procedimientos del sistema, consulte el Manual de Referencia de SQL Server . Omisin de un tipo de datos definido por el usuario Para omitir un tipo de datos definido por el usuario, ejecute sp_droptype : sp_droptype typename Note: No es posible omitir un tipo de datos que est en uso en alguna tabla.

Obtencin de informacin sobre tipos de datos Utilice el procedimiento del sistema sp_help para mostrar informacin sobre las propiedades de un tipo de datos del sistema o de uno definido por el usuario. El informe indica el tipo base a partir del que se ha creado el tipo de datos, si admite o no valores nulos, los nombres o cualquier regla o valor predeterminado vinculados al tipo de datos, y si dispone de la propiedad IDENTITY. En los ejemplos siguientes, se muestra informacin sobre el tipo de datos del sistema money y el tipo de datos definido por el usuario tid : sp_help money Type_name Storage_type Length Prec Scale ---------- ------------ ------ ----- ----money money 8 NULL NULL Nulls Default_name Rule_name Identity ---------------- ---------------1 NULL NULL 0 (return status = 0) sp_help tid
Page 100 of 280

Type_name Storage_type Length Prec Scale ---------- ------------ ------ ----- ----tid varchar 6 NULL NULL Nulls Default_name Rule_name Identity ---------------- ---------------0 NULL NULL 0 (return status = 0) Chapter 7

Creacin de bases de datos y tablas


En este captulo se describe el modo de configurar bases de datos y tablas, un proceso llamado definicin de datos . En l se trata lo siguiente:

Introduccin general a bases de datos y sus tablas Uso y creacin de bases de datos Creacin de tablas y definicin de sus columnas Creacin de tipos de datos definidos por el usuario Cambio de tablas existentes Obtencin de informacin sobre bases de datos y tablas

Si no planea crear sus propias bases de datos y tablas, lea los conceptos bsicos de bases de datos y tablas (descritos en la siguiente seccin) y la explicacin del comando use (descrito en una seccin posterior). Despus puede omitir el resto de este captulo. Definicin de base de datos y de tabla Uso y creacin de bases de datos Omisin de bases de datos Alteracin de los tamaos de bases de datos Creacin de tablas Definicin de restricciones de integridad para tablas Diseo y creacin de tablas Creacin de tablas nuevas a partir de resultados de consultas: select into Omisin de tablas Alteracin de tablas existentes Asignacin de permisos a los usuarios Obtencin de informacin sobre bases de datos y tablas

Definicin de base de datos y de tabla Una base de datos almacena informacin (datos) en un conjunto de objetos de base de datos, tales como tablas, relacionados entre s. Una tabla es un conjunto de filas que tienen columnas asociadas con elementos de datos individuales. La organizacin de los datos se define cuando se crean las bases de datos y las tablas. Este proceso se llama definicin de datos. Los objetos de base de datos de SQL Server incluyen:

Tablas Reglas Valores predeterminados Procedimientos almacenados Disparadores Vistas Restricciones de integridad de referencia Restricciones de integridad de verificacin

Este captulo slo cubre la creacin, modificacin y eliminacin de bases de datos y tablas, incluyendo las restricciones de integridad.
Page 101 of 280

Las reglas y valores predeterminados se explican en el Captulo 12, las vistas en el Captulo 9, los procedimientos en el Captulo 14 y los disparadores en el Captulo 15. Las columnas y tipos de datos definen el tipo de datos incluidos en las tablas, mientras que los ndices describen el modo en que dichos datos se organizan en las tablas. SQL Server no los considera objetos de la base de datos y no aparecen enumerados en sysobjects . Las columnas y tipos de datos se explican en este captulo; los ndices se describen en el Captulo 11. Imposicin de la integridad de datos en bases de datos La integridad de datos refiere a la validez e integridad de los datos dentro de una base de datos. Para imponer la integridad de datos, es posible restringir los valores de los datos que los usuarios pueden insertar, eliminar o actualizar en la base de datos. Por ejemplo, la integridad de los datos de la base de datos pubs2 requiere que un ttulo de libro de la tabla titles tenga un editor en la tabla publishers . No se debe insertar libros en titles que no tengan un editor vlido, ya que esto viola la integridad de los datos de pubs2 . Transact-SQL proporciona varios mecanismos para imponer la integridad en una base de datos, como reglas, valores predeterminados, ndices y disparadores, que permiten mantener los siguientes tipos de integridad de datos:

Requisito: esta integridad requiere que una columna de tabla contenga un valor vlido en cada fila; no permite valores nulos. La instruccin create table permite restringir los valores nulos de una columna. Verificacin o validez: esta integridad limita o restringe los valores de datos insertados en una columna de tabla. Para imponer esta integridad de datos, pueden utilizarse disparadores o reglas. Exclusividad : esta integridad establece que no debe haber dos filas de tabla con los mismos valores no nulos para una o ms columnas de tablas. Para imponer esta integridad, pueden utilizarse ndices. De referencia: esta integridad establece que los datos insertados en una columna de tabla ya tengan datos coincidentes en otra columna de tabla, o en otra columna de la misma tabla. Para imponer esta integridad, pueden utilizarse disparadores.

La consistencia de los valores de datos de la base de datos es otra integridad de datos, que se describe en el Captulo 17. Como alternativa al uso de reglas, valores predeterminados, ndices y disparadores, Transact-SQL proporciona una serie de restricciones de integridad que forman parte de la instruccin create table para imponer la integridad de datos segn las normas SQL. Estas restricciones de integridad se describen ms adelante en este captulo. Permisos dentro de bases de datos La posibilidad de crear y omitir bases de datos y objetos de base de datos depende de los permisos o privilegios que el usuario tenga asignados. Normalmente, el administrador del sistema o propietario de la base de datos define los permisos del usuario, segn el tipo de trabajo que realice y las funciones que necesite. Estos permisos pueden ser distintos para cada usuario de una instalacin o base de datos dadas. Para determinar los permisos que posee, ejecute: sp_helprotect user_name

donde user_name es su nombre de login de SQL Server. Para experimentar con objetos de base de datos de la forma ms conveniente posible, la base de datos pubs2 tiene un usuario " invitado " en su tabla del sistema sysusers . El guin que crea pubs2 concede una gran variedad de permisos al " invitado " . El mecanismo " invitado " significa que cualquiera que tenga un login en SQL Server, es decir, que aparezca en master.. syslogins , tendr acceso a pubs2 y permiso para crear y omitir objetos como tablas, ndices, valores predeterminados, reglas, procedimientos, etc.. El nombre de usuario " invitado " tambin permite utilizar algunos procedimientos almacenados, crear tipos de datos definidos por el usuario, consultar la base de datos y modificar sus datos. Para utilizar la base de datos pubs2 , emita el comando use . SQL Server verifica si su nombre de usuario aparece en pubs2.. sysusers . Si no aparece, ser admitido como invitado sin ms trmite. Si su nombre aparece en pubs2.. sysusers , ser admitido, pero sus permisos pueden ser diferentes de los de " invitado " . Todos los ejemplos de este captulo suponen que usted es un " invitado " . Uso y creacin de bases de datos
Page 102 of 280

Una base de datos es un conjunto de tablas relacionadas y otros objetos de base de datos (vistas, ndices, etc.). La primera vez que se instala, SQL Server contiene estas bases de datos del sistema :

La base de datos master controla las bases de datos del usuario y el funcionamiento de SQL Server como un todo. La base de datos sybsystemprocs contiene los procedimientos almacenados del sistema. La base de datos temporal, tempdb , almacena los objetos temporales, incluidas las tablas temporales creadas con el prefijo de nombre " tempdb ..". La base de datos model es utilizada por SQL Server como plantilla para la creacin de nuevas bases de datos de usuario.

Adems, los administradores del sistema pueden instalar la base de datos de muestra, pubs2 , y la base de datos de sintaxis, sybsyntax , mediante isql y los guiones SQL incluidos en el directorio scripts . La base de datos pubs2 sirve como base para la mayora de los ejemplos de la documentacin de SQL Server. La base de datos sybsyntax almacena toda la informacin de sintaxis de los comandos y procedimientos a los que se tiene acceso mediante sp_syntax . Las bases de datos pubs2 y sybsyntax son bases de datos del usuario. Todos sus datos - el motivo para usar un sistema de administracin de bases de datos - se almacenan en bases de datos del usuario. SQL Server administra cada base de datos mediante las tablas del sistema. Las tablas del diccionario de datos de la base de datos master y de otras bases de datos se consideran tablas del sistema. Seleccin de una base de datos: use La mayor parte del tiempo, usted utilizar una base de datos que ya existe. La sintaxis del comando que permite el acceso a una base de datos existente es: use database_name

Por ejemplo, para tener acceso a la base de datos llamada pubs2 , escriba: use pubs2 El usuario puede tener acceso a la base de datos pubs2 mediante dicho comando slo si es un usuario conocido en pubs2 . De lo contrario, SQL Server muestra un mensaje de error. El propietario de la base de datos decide quin tiene acceso a dicha base de datos ejecutando el procedimiento del sistema sp_adduser. La mayora de los usuarios podrn ver las tablas del sistema de la base de datos master como invitados, segn se explic anteriormente. Los usuarios que no son reconocidos por nombre en la base de datos master pueden tener acceso a la misma como usuarios " invitados " . El usuario " invitado " se aade a la base de datos master en el guin que crea esta base de datos cuando se instala. Un propietario de base de datos, "dbo", puede aadir un usuario "invitado" a cualquier base de datos de usuario con el procedimiento del sistema sp_adduser . Los administradores del sistema se convierten automticamente en los propietarios de las base de datos que usan. Para obtener ms informacin, consulte la Gua de Administracin del Sistema o el Manual del Referencia de SQL Server . Es probable que se conecte automticamente a la base de datos master cuando haga el login a SQL Server, de manera que deber ejecutar el comando use para tener acceso a otra base de datos. Tanto usted como el administrador del sistema pueden cambiar la base de datos a la que se conectan inicialmente mediante el procedimiento del sistema sp_modifylogin . Slo el administrador del sistema puede cambiar la base de datos predeterminada para otro usuario. Creacin de una base de datos del usuario: create database Si el administrador del sistema le concede el permiso para utilizar el comando create database , usted puede crear una base de datos nueva. Cuando cree una base de datos, deber estar usando la base de datos master . En muchas empresas, el administrador del sistema crea todas las bases de datos. El autor de la base de datos es su propietario. Si otro usuario crea la base de datos, puede transferirle los derechos de propiedad mediante el procedimiento del sistema sp_changedbowner . El propietario de la base de datos es responsable de proporcionar acceso a la base de datos a los usuarios, y de conceder y revocar otros permisos para usuarios. En algunas organizaciones, el propietario de la base de datos tambin es responsable de mantener copias de seguridad peridicas de la base de datos y de volver a cargarla en caso de un fallo del sistema. El
Page 103 of 280

propietario de la base de datos siempre puede hacerse pasar por cualquier otro usuario de la base de datos, consiguiendo temporalmente los permisos de tales usuarios, mediante el comando setuser . Dado que cada base de datos tiene asignada una cantidad importante de espacio, aunque contenga slo pequeas cantidades de datos, es posible que no se le otorgue el permiso para utilizar el comando create database . Si ste es el caso, ignore esta seccin y pase a la explicacin "Creacin de tablas". Este es el formato ms sencillo del comando create database : create database database_name

Para crear la base de datos newpubs , cercirese de estar usando la base de datos master en lugar de pubs2 y luego escriba este comando: create database newpubs El nombre de la base de datos debe ser nico en SQL Server y ajustarse a las reglas para identificadores proporcionadas en el Captulo 1. SQL Server puede administrar hasta 32.767 bases de datos. Slo se puede crear una base de datos por vez. El nmero mximo de segmentos para cualquier base de datos es 32. SQL Server crea la base de datos nueva como una copia de la base de datos model , que contiene las tablas del sistema pertenecientes a todas las bases de datos de usuario. La creacin de una base de datos nueva se registra en las tablas sysdatabases y sysusages de la base de datos master . Esta es la sintaxis completa del comando create database : create database database_name [on {default | database_device } [= size [, database_device [= size ]]...] [log on database_device [= size ] [, database_device [= size ]]...] [with override] [for load]

En este captulo se describen todas las opciones de create database , excepto with override . Para obtener ms informacin sobre dicha opcin, consulte la Gua de Administracin del Sistema . Note: En los ejemplos anteriores y en los de la siguiente seccin, no se muestra la clusula log on por razones de simplicidad. Sin embargo, cuando cree bases de datos de produccin, siempre debe hacerlo con la clusula log on . Consulte la siguiente seccin. La clusula on La clusula opcional on permite especificar la posicin donde debe almacenarse la base de datos y la cantidad de espacio en megabytes que se le debe asignar. Si utiliza la palabra clave default , la base de datos se asignar a un dispositivo de bases de datos del banco de dispositivos de bases de datos indicado en la tabla sysdevices de la base de datos master . Emplee el procedimiento del sistema sp_helpdevice para ver los dispositivos de la lista predeterminada. Note: Un administrador del sistema puede tener ciertas asignaciones de almacenamiento basadas en estadsticas de rendimiento y otras consideraciones. Antes de crear bases de datos, consulte con un administrador del sistema. Para especificar un tamao de 5 MB para una base de datos que va a almacenarse en esta posicin predeterminada, utilice on default = size de la siguiente manera: create database newpubs on default = 5 Si quiere especificar una posicin diferente para la base de datos, proporcione el nombre lgico del dispositivo de base de datos donde desea almacenarla. Una base de datos puede almacenarse en varios dispositivos de base de datos, con diferentes cantidades de espacio en cada uno. Esta instruccin crea la base de datos newpubs y le asigna 3 MB en pubsdata y 2 MB en newdata :
Page 104 of 280

create database newpubs on pubsdata = 3, newdata = 2 Si omite la clusula on y el tamao, la base de datos se crea con 2 MB de espacio del banco de dispositivos de base de datos predeterminados indicados en sysdevices . El tamao de una asignacin de base de datos puede estar comprendido entre 2 MB y 2 23 MB. La clusula log on A menos que est creando bases de datos pequeas y no esenciales, siempre deber utilizar la extensin log on database_device de create database . Esta extensin sita los diarios de transacciones en un dispositivo de bases de datos independiente. Hay varias razones para situar los diarios en otro dispositivo:

Permite utilizar el comando dump transaction en lugar de dump database , ahorrando as tiempo y cintas. Permite establecer un tamao fijo para el diario, dejando as espacio libre para otras actividades de la base de datos.

Hay otras razones para situar el diario en un dispositivo fsico distinto del de las tablas de datos:

Aumento de rendimiento. Garanta de una capacidad de recuperacin total en caso de fallos del disco duro.

El siguiente comando coloca el diario de newpubs en el dispositivo lgico "pubslog" , con un tamao de 1 megabyte: create database newpubs on pubsdata = 3, newdata = 2 log on pubslog = 1 Note: Cuando utilice la extensin log on , colocar el diario de transacciones de la base de datos en un segmento llamado "logsegment". Si alguna vez necesita aadir ms espacio para el diario, deber usar alter database y, en algunos casos, el procedimiento del sistema sp_extendsegment . Consulte el Manual de Referencia de SQL Server o la Gua de Administracin de Sistema SQL Server para obtener informacin adicional. El tamao del dispositivo requerido para el diario de transacciones vara segn la cantidad de actividad de actualizacin y la frecuencia de los volcados del diario de transacciones. Como regla prctica, asigne entre un 10 y 25 por ciento del espacio asignado a la base de datos en s al diario. La opcin for load La clusula opcional for load ejecuta una versin racionalizada de create database que slo puede utilizarse para cargar un volcado de base de datos. Use esta opcin para efectuar la recuperacin tras un fallo de medios, o para el traslado de una base de datos de una mquina a otra. Consulte la Gua de Administracin del Sistema para obtener informacin detallada. Omisin de bases de datos La supresin de una base de datos se lleva a cabo con el comando drop database . drop database elimina la base de datos y su contenido de SQL Server, libera el espacio de almacenamiento que se le haba asignado, y elimina las referencias a la misma por parte de la base de datos master . Esta es la sintaxis del comando: drop database database_name [, database_name ]...

No es posible omitir una base de datos en uso, es decir, que est abierta para su lectura o escritura por parte de cualquier usuario. Como se indica, se puede omitir ms de una base de datos en un solo comando. Por ejemplo: drop database newpubs, newdb Una base de datos daada no puede suprimirse con drop database . Utilice el comando dbcc dbrepair .
Page 105 of 280

Alteracin de los tamaos de bases de datos Si una base de datos ha utilizado todo el espacio de almacenamiento asignado, no es posible aadirle datos nuevos ni actualizaciones. Lgicamente, los datos existentes siempre se conservan. Si el espacio asignado a una base de datos es demasiado reducido, el propietario de la base de datos puede aumentarlo con el comando alter database . El permiso alter database corresponde predeterminadamente al propietario de la base de datos y no puede transferirse. Para usar el comando alter database , hay que estar utilizando la base de datos master . El incremento predeterminado es de 2 MB y proviene del banco predeterminado de espacio. Esta instruccin aade 2 MB a newpubs en el dispositivo de bases de datos predeterminado: alter database newpubs La sintaxis completa de alter database permite ampliar una base de datos en un nmero especificado de megabytes (un mnimo de 1 MB) e indicar dnde debe aadirse el espacio de almacenamiento: alter database database_name [on {default | database_device } [= size [, database_device [= size ]]...] [log on { default | database_device } [ = [ , database_device [= size ]]...] [with override] [for load]

] size ]

La clusula on del comando alter database es como la clusula on del comando create database . La clusula for load es como la clusula for load del comando create database y slo puede utilizarse en una base de datos creada con for load . Para aumentar el espacio asignado a newpubs en 2 MB en el dispositivo de bases de datos pubsdata , y en 3 MB en el dispositivo de bases de datos newdata , escriba: alter database newpubs on pubsdata = 2, newdata = 3 Cuando se usa alter database para asignar ms espacio en un dispositivo ya en uso por la base de datos, todos los segmentos existentes del dispositivo utilizan el fragmento de espacio aadido. Todos los objetos ya correlacionados con los segmentos existentes pueden ampliarse en el espacio aadido. El nmero mximo de segmentos para cualquier base de datos es 32. Cuando se usa alter database para asignar espacio en un dispositivo que todava no est en uso por una base de datos, los segmentos system y default se correlacionan con el dispositivo nuevo. Si quiere cambiar esta correlacin de segmentos, debe utilizar sp_dropsegment para omitir los segmentos no deseados del dispositivo. Note: El uso de sp_extendsegment , logsegment o device_name cancela automticamente la correlacin de los segmentos system y default . Para obtener informacin sobre with override , consulte la Gua de Administracin del Sistema. Creacin de tablas Cuando se crea una tabla, se asignan nombres a sus columnas y un tipo de datos a cada columna. Tambin puede especificarse si una columna concreta puede contener valores nulos, o indicarse cualquier restriccin de integridad para las columnas de la tabla. Puede haber 2.000 millones de tablas por base de datos. Ejemplo de creacin de una tabla Cercirese de utilizar la base de datos newpubs creada en la seccin anterior para intentar estos ejemplos. De lo contrario, todos estos cambios afectarn a otra base de datos, como pubs2 . Para crear una tabla, use el comando create table , cuyo formato ms sencillo es el siguiente: create table table_name ( column_name datatype

)
Page 106 of 280

Por ejemplo, para crear una tabla llamada names con una columna some_name y una longitud fija de 11 bytes, introduzca: create table names (some_name char(11)) Puede definir hasta 250 columnas. Si ha definido quoted_identifier como on , el nombre de la tabla y los nombres de las columnas pueden ser identificadores delimitados. En caso contrario, deben ajustarse a las reglas para identificadores del Captulo 1, "Introduccin". Los nombres de columna deben ser nicos dentro de una tabla determinada, pero es posible utilizar el mismo nombre de columna en diferentes tablas de la misma base de datos. Debe haber un tipo de datos para cada columna. La palabra "char" despus del nombre de columna del ejemplo anterior hace referencia al tipo de datos de la columna, es decir, el tipo de valor que contendr la columna. Los tipos de datos se explican en el Captulo 6, "Uso y creacin de tipos de datos". El nmero entre parntesis despus del tipo de datos proporciona el nmero mximo de bytes que puede almacenarse en la columna. Se proporciona una longitud mxima para algunos tipos de datos. Otros tienen una longitud definida por el sistema. Cercirese de incluir la lista de nombres de columnas entre parntesis y de colocar comas despus de cada definicin de columna. Seleccin de nombres de tablas El comando create table crea la tabla nueva en la base de datos abierta. Los nombres de tablas deben ser nicos para cada usuario. Se pueden crear tablas temporales precediendo el nombre de la tabla en una instruccin create table con un smbolo de nmero (#) o especificando el prefijo de nombre " tempdb ..". Las tablas temporales creadas con el smbolo de libra slo pueden accederse durante la sesin actual de SQL Server y se eliminan al final de la sesin. Los 13 primeros bytes del nombre de la tabla, incluido el smbolo de nmero (#), deben ser nicos. SQL Server asigna un sufijo numrico de 17 bytes a los nombres de dichas tablas. Las tablas temporales creadas con el prefijo " tempdb .." se almacenan en tempdb y pueden compartirse entre sesiones de SQL Server. SQL Server no cambia los nombres de las tablas temporales creadas de este modo. La tabla existe hasta que se reinicia SQL Server o hasta que la omite su propietario mediante drop table . Las tablas temporales no son recuperables. create table #authors (au_id char(11)) crea una tabla temporal no compartible. create table tempdb..authors (au_id char(11)) crea una tabla temporal que puede compartirse entre sesiones de SQL Server. Usted puede utilizar cualquier tabla u otros objetos que haya creado sin calificar sus nombres. Tambin puede usar los objetos creados por el propietario de la base de datos sin calificar sus nombres, siempre que tenga los permisos adecuados. Estas reglas se aplican a todos los usuarios, incluidos el administrador del sistema y el propietario de la base de datos. Si bien los nombres de tablas deben ser nicos para cada usuario, diferentes usuarios pueden crear tablas con el mismo nombre. Por ejemplo, un usuario llamado "jonah" y otro llamado "sally" pueden crear tablas llamadas info . Los usuarios que tengan permiso en ambas tablas tendrn que calificarlas como jonah . info y sally.info. Sally tendr que calificar todas las referencias a la tabla info de Jonah, aunque puede referirse a la suya simplemente como info . Sintaxis de create table Esta es la sintaxis del comando create table : create table [ database .[ owner [default { constant_expression {[{identity | null | not null}] ].] table_name | user | null}] ( column_name datatype

Page 107 of 280

| [[constraint constraint_name ] {{unique | primary key} [clustered | nonclustered] [with {fillfactor | max_rows_per_page} = x] [on segment_name ] | references [[ database .] owner .] ref_table [( ref_column )] | check ( search_condition )}]}... | [constraint constraint_name ] {{unique | primary key} [clustered | nonclustered] ( column_name [{, column_name }...]) [with {fillfactor | max_rows_per_page} = x] [on segment_name ] | foreign key ( column_name [{, column_name }...]) references [[ database .] owner .] ref_table [( ref_column [{, ref_column }...])] | check ( search_condition )} [{, { next_column | next_constraint }}...]) + [with max_rows_per_page = x][on segment_name ] La instruccin create table define cada columna de la tabla. create table proporciona el nombre y el tipo de datos de la columna, especifica el modo en que cada columna manipula los valores nulos, e indica qu columna, si hubiera alguna, tiene la propiedad IDENTITY. create table tambin puede definir restricciones de integridad a nivel de columna y a nivel de tabla. Cada definicin de tabla puede tener mltiples restricciones por columna y por tabla. Por ejemplo, la instruccin create table para la tabla titles de la base de datos pubs2 es: create table titles (title_id tid, title varchar(80) not null, type char(12), pub_id char(4) null, price money null, advance money null, royalty int null, total_sales int null, notes varchar(200) null, pubdate datetime contract bit not null) En las secciones siguientes se describen varios componentes distintos de definicin de tabla: tipos de datos suministrados por el sistema, tipos de datos definidos por el usuario, tipos nulos y columnas IDENTITY. La definicin de restricciones de integridad para una tabla se describe despus de estas secciones. Note: La extensin on segment_name de create table permite colocar la tabla en un segmento, un nombre que apunte a un dispositivo de bases de datos especfico, o un conjunto de dispositivos de bases de datos. Antes de crear una tabla en un segmento, solicite una lista de los segmentos que pueden utilizarse al administrador del sistema o propietario de la base de datos. Algunos segmentos pueden estar asignados a tablas o ndices especficos por razones de rendimiento, o por otras consideraciones. Uso de valores nulos Para cada columna, puede especificar si se admiten o no valores nulos. Un valor nulo no es lo mismo que "cero" o "espacio en blanco". NULL (nulo) significa que no se ha realizado ninguna entrada y generalmente implica "valor desconocido" o "valor inaplicable". Esto indica que el usuario no ha realizado ninguna entrada, cualquiera que sea la razn. Por ejemplo, una entrada nula en la columna price de la tabla titles no quiere decir que el libro sea gratuito, sino que el precio se desconoce, o que todava no se ha fijado. Si el usuario no realiza ninguna entrada en una columna definida con la palabra clave null , SQL Server proporcionar el valor NULL. Una columna definida con la palabra clave null tambin aceptar una entrada explcita de NULL por parte del usuario, cualquiera sea su tipo de datos. Sin embargo, hay que tener cuidado al introducir valores nulos en columnas de caracteres. Si incluye la palabra "null" entre comillas dobles o simples, SQL Server interpreta la entrada como una cadena de caracteres y no como el valor NULL.
Page 108 of 280

Si omite null o not null en la instruccin create table , SQL Server utiliza el modo nulo definido para la base de datos (de forma predeterminada, NOT NULL). Para compatibilidad con las normas SQL, utilice el procedimiento del sistema sp_dboption para definir la opcin allow nulls by default como true (verdadera). Para una columna definida como NOT NULL, SQL Server insistir en que se realice una entrada. Si no existe ninguna entrada para una columna NOT NULL, aparecer un mensaje de error. Los valores predeterminados, es decir, los valores suministrados de forma automtica cuando no se realiza ninguna entrada, pueden usarse con columnas NULL y NOT NULL. Un valor predeterminado se considera una entrada. Sin embargo, no es posible designar un valor predeterminado NULL para una columna NOT NULL. Los valores nulos pueden especificarse como valores predeterminados mediante la restriccin default de la instruccin create table , o mediante la instruccin create default . La restriccin default se describe ms adelante en este captulo; create default se describe en el Captulo 12. Definir las columnas como NULL proporciona un marcador de lugar para los datos que todava se desconocen. Por ejemplo, en la tabla titles , las columnas price , advance , royalty y total_sales estn definidas para permitir valores NULL. Sin embargo, title_id y title no estn definidas para permitir valores NULL, ya que la falta de una entrada en estas columnas no tendra sentido y resultara confuso. Un precio sin ttulo no tendra sentido, mientras que un ttulo sin precio simplemente significara que el precio todava estaba sin decidir o no estaba disponible. En la instruccin create table , use las palabras clave not null cuando la informacin de la columna sea fundamental para el significado de las dems columnas. Uso de columnas IDENTITY Cada tabla puede incluir una sola columna IDENTITY. Las columnas IDENTITY almacenan nmeros secuenciales (como los nmeros de factura, de empleado o de registro) generados de forma automtica por SQL Server. El valor de la columna IDENTITY identifica de forma nica cada fila de una tabla. La columna IDENTITY se define especificando la palabra clave identity, en lugar de null o not null, en la instruccin create table (por definicin, las columnas IDENTITY no permiten valores nulos). Las columnas IDENTITY deben tener un tipo de datos numeric y una escala de 0. La precisin determina el valor mximo que puede insertarse en la columna. El valor mximo posible de columna es 10 precision 1. A continuacin se muestra un ejemplo de una tabla cuya columna IDENTITY permite un valor mximo de 10 5 - 1, o 9,999: create table sales_daily (row_id numeric(5,0) identity, stor_id char(4) not null) Con la opcin de base de datos auto identity y el parmetro de configuracin size of auto identity se pueden crear columnas IDENTITY automticas. Para incluir columnas IDENTITY como ndices no nicos, use la opcin de base de datos identity in nonunique index . Creacin de columnas IDENTITY con tipos de datos definidos por el usuario Tambin pueden utilizarse tipos de datos definidos por el usuario para crear columnas IDENTITY. El tipo de datos definido por el usuario debe tener un tipo numeric subyacente y una escala de 0. Si el tipo de datos definido por el usuario fue creado con la propiedad IDENTITY, no es necesario repetir la palabra clave identity al crear la columna. A continuacin se muestra un ejemplo de un tipo de datos definido por el usuario con la propiedad IDENTITY: sp_addtype ident, "numeric(5)", "identity" Esta es una columna IDENTITY basada en ese tipo: create table sales_monthly (row_id ident, stor_id char(4) not null) Si el tipo definido por el usuario fue creado como not null , deber especificar la palabra clave identity en la instruccin create table . No es posible crear una columna IDENTITY a partir de un tipo de datos definido por el usuario que permite valores nulos.
Page 109 of 280

Referencia a columnas IDENTITY con syb_identity Una vez definida la columna IDENTITY, no es necesario recordar el nombre de columna real. Se puede utilizar la palabra clave syb_identity, calificada por el nombre de la tabla donde sea necesario, en operaciones de seleccin, actualizacin y eliminacin realizadas en la tabla. Por ejemplo, para seleccionar la fila donde row_id es igual a 30, utilice esta consulta: select * from sales_daily where syb_identity = 30 Generacin de valores de columna La primera vez que inserta una fila en una tabla, SQL Server asigna el valor 1 a la columna IDENTITY. Cada nueva fila obtiene un valor de columna mayor en uno que el anterior. Las reversiones de transacciones, eliminacin de filas, parmetro de configuracin identity grab size e insercin manual de datos en la columna IDENTITY pueden provocar la aparicin de espacios en blanco en los valores de columna. Los fallos del servidor tambin pueden crear espacios en blanco en los valores de columnas IDENTITY. El tamao de estos espacios en blanco, como un porcentaje del tamao mximo de la tabla, depende del valor del parmetro de configuracin identity burning set factor . Este parmetro se define durante la instalacin y el administrador del sistema puede volver a definirlo. Uso de tablas temporales Si utiliza el smbolo de nmero (#) o " tempdb .." antes del nombre de la tabla en el comando create table , la tabla nueva es temporal. Hay dos tipos de tablas temporales:

Tablas que pueden compartirse entre sesiones de SQL Server.Estas tablas temporales compartibles se crean especificando tempdb como parte del nombre de la tabla en la instruccin create table . Por ejemplo: create table tempdb..my_temptbl SQL Server no cambia los nombres de las tablas temporales creadas de este modo. La tabla existe hasta que se reinicia SQL Server o hasta que su propietario la omita con drop table .

Tablas a las que slo puede accederse durante la sesin actual de SQL Server. Las tablas temporales no compartibles deben comenzar con un smbolo de nmero (#). Para crear una tabla temporal no compartible, especifique slo el nombre de la tabla en la instruccin create table . Por ejemplo: create table #my_temptbl SQL Server garantiza que el nombre de la tabla temporal sea nico en la sesin actual. El programa trunca los nombres de tabla temporal largos a 13 caracteres (incluido el smbolo de nmero) y rellena los nombres cortos a 13 caracteres mediante caracteres de subrayado (_). Luego SQL Server aade un sufijo numrico de 17 dgitos nico para una sesin de SQL Server. La tabla existe hasta que la sesin actual termina o hasta que su propietario la omite con drop table .

Si no indica el smbolo de nmero o " tempdb .." antes del nombre de la tabla y no utiliza tempdb , la tabla se crea como una tabla permanente. Una tabla permanente se conserva en la base de datos hasta que su propietario la omite de forma explcita. A continuacin se muestra una instruccin que crea una tabla temporal no compartible: create table #myjobs (task char(30), start datetime, stop datetime, notes varchar(200)) Esta tabla se puede utilizar para mantener una lista de las tareas diarias junto con un registro del inicio y trmino de las mismas, y cualquier otra observacin. La tabla y sus datos desaparecern al final de la sesin de trabajo actual.
Page 110 of 280

Las tablas temporales no son recuperables. Es posible asociar reglas, valores predeterminados e ndices a las tablas temporales, pero no crear vistas en tablas temporales ni asociar disparadores con ellas. Al crearse una tabla temporal, se puede utilizar un tipo de datos definido por el usuario, slo si dicho tipo se encuentra en tempdb .. systypes . Existen dos formas de aadir un tipo de datos definido por el usuario, o cualquier otro objeto, a tempdb . Para aadir un objeto slo para la sesin actual, ejecute sp_addtype mientras utiliza tempdb . Para aadir un tipo de datos definido por el usuario permanentemente, ejecute sp_addtype en model y despus reinicie SQL Server para que model se copie en tempdb . Creacin de tablas en bases de datos diferentes Como muestra la sintaxis de create table , se puede crear una tabla en una base de datos distinta de la actual calificando el nombre de la tabla con el nombre de la otra base de datos. Sin embargo, es necesario ser un usuario autorizado de la base de datos donde va a crearse la tabla y tener el permiso create table sobre ella. Si se usa pubs2 y hay otra base de datos llamada newpubs , se puede crear una tabla llamada newtab en newpubs as: create table newpubs..newtab (col1 int) Para que create table se ejecute de forma correcta, la etiqueta de sesin curread debe dominar el obstculo de la base de datos donde se va a crear la tabla. No es posible crear otros objetos de base de datos (vistas, reglas, valores predeterminados, procedimientos almacenados o disparadores) en una base de datos distinta de la actual. Definicin de restricciones de integridad para tablas Transact-SQL proporciona dos mtodos para mantener la integridad de los datos de una base de datos:

Definicin de reglas, valores predeterminados, ndices y disparadores Definicin de restricciones de integridad de create table

La seleccin de un mtodo en lugar de otro depende de los requisitos del usuario. Las restricciones de integridad ofrecen la ventaja de definir los controles de integridad en un paso durante el proceso de creacin de la tabla (segn definen las normas SQL) y de simplificar el proceso para crear dichos controles. Sin embargo, las restricciones de integridad estn ms limitadas en alcance y son menos extensas que los valores predeterminados, reglas, ndices y disparadores. Por ejemplo, los disparadores proporcionan una manipulacin ms compleja de la integridad de referencia que los declarados en create table . Asimismo, las restricciones de referencia definidas por create table son especficas de dicha tabla. A diferencia de las reglas o valores predeterminados, las restricciones no pueden vincularse a otras tablas y slo pueden omitirse o cambiarse mediante alter table . Las restricciones no pueden contener subconsultas ni funciones agregadas, ni siquiera en la misma tabla. Los dos mtodos no son excluyentes entre s. Es posible utilizar restricciones de referencia junto con valores predeterminados, reglas, ndices y disparadores. Esto proporciona la flexibilidad de elegir el mtodo que mejor se ajuste a cada aplicacin de usuario. En esta seccin se describen las restricciones de integridad de create table . Los valores predeterminados, reglas, ndices y disparadores se explican en captulos posteriores. Pueden crearse los siguientes tipos de restricciones:

Las restricciones unique y primary key exigen que no haya dos filas en una tabla con los mismos valores en las columnas especificadas. Adems, la restriccin primary key requiere que no haya valores nulos en ninguna fila de la columna. La integridad de referencia ( references ) exige que los datos insertados en columnas especficas ya tengan datos coincidentes en la tabla y columnas especificadas. Las restricciones check limitan los valores de datos insertados en las columnas.

Tambin se puede imponer la integridad de datos restringiendo el uso de valores nulos en una columna (las palabras clave null o not null ) y proporcionando valores predeterminados para columnas (la clusula default ). Consulte la seccin ''Uso de valores nulos'', para obtener ms informacin sobre las palabras clave null y not null .
Page 111 of 280

Se pueden crear mensajes de error vinculados a restricciones. Genere mensajes con sp_addmessage y vinclelos a las restricciones con sp_bindmsg. Para obtener ms informacin, consulte sp_addmessage y sp_bindmsg en el Manual de Referencia de SQL Server . Para obtener ms informacin sobre restricciones definidas para una tabla, utilice el procedimiento del sistema sp_helpconstraint , que se describe al final de este captulo. Especificacin de restricciones a nivel de tabla o de columna Es posible declarar restricciones de integridad a nivel de tabla o de columna. La diferencia es sintctica. Las restricciones a nivel de columna se incluyen despus del nombre de columna y del tipo de datos, antes de la coma de delimitacin. Las restricciones a nivel de tabla se introducen como clusulas delimitadas por comas distintas. SQL Server trata las restricciones a nivel de tabla y de columna del mismo modo; ningn mtodo es ms eficaz que el otro. Sin embargo, las restricciones que operen en ms de una columna deben declararse como restricciones a nivel de tabla. Por ejemplo, la siguiente instruccin create table tiene una restriccin check que opera en dos columnas , pub_id y pub_name : create table my_publishers (pub_id char(4), pub_name varchar(40), constraint my_chk_constraint check(pub_id in ("1389", "0736", "0877") or pub_name not like "Bad News Books")) Es posible, pero no es necesario, declarar las restricciones que operan slo en una columna como restricciones a nivel de columna. Por ejemplo, si la restriccin check anterior slo utiliza una columna ( pub_id) , se puede poner la restriccin en esa columna: create table my_publishers (pub_id char(4) constraint my_chk_constraint check(pub_id in ("1389", "0736", "0877")), pub_name varchar(40)) En ambos casos, la palabra clave constraint y el nombre de restriccin que la acompaa son opcionales. La restriccin check se describe en una seccin posterior. Especificacin de valores de columna predeterminados Antes de definir ninguna restriccin de integridad a nivel de columna, se puede especificar un valor predeterminado de columna con la clusula default . Esta clusula asigna un valor predeterminado a una columna en un paso, como parte de la instruccin create table . Cuando un usuario no introduce ningn valor de columna, SQL Server inserta el valor predeterminado automticamente. Con la clusula default se pueden utilizar los siguientes valores:

constant_expression : especifica una expresin constante para usarse como valor predeterminado de la columna. No

se puede incluir el nombre de ninguna columna ni otro objeto de base de datos, pero s funciones incorporadas que no hagan referencia a objetos de base de datos. Este valor predeterminado debe ser compatible con el tipo de datos de la columna. user : indica que SQL Server debe insertar el nombre del usuario como valor predeterminado. Para utilizar este valor predeterminado, el tipo de datos de la columna debe ser char(30) o varchar(30) . null : indica que SQL Server debe insertar el valor nulo como valor predeterminado. No se puede definir este valor predeterminado en columnas que no permitan valores nulos (utilizando la palabra clave not null ).

Por ejemplo, esta instruccin create table define dos valores predeterminados de columna: create table my_titles (title_id char(6), title varchar(80), price money default null, total_sales int default 0) Slo puede incluirse una clusula default por columna de tabla.
Page 112 of 280

El uso de la clusula default para asignar valores predeterminados es ms sencillo que el mtodo de dos pasos de TransactSQL. En Transact-SQL, es posible utilizar create default para declarar el valor predeterminado y luego vincularlo a la columna con sp_bindefault . Especificacin de restricciones unique y primary key Para garantizar que no haya dos filas de una tabla con los mismos valores en las columnas especificadas, se pueden declarar restricciones unique o primary key . Ambas restricciones crean ndices nicos que imponen esta integridad de datos. Sin embargo, las restricciones primary key son ms restrictivas que las unique . Las columnas con restricciones primary key no pueden contener valores nulos. La restriccin primary key de una tabla suele usarse en conjuncin con las restricciones de integridad de referencia definidas en otras tablas. La definicin de restricciones unique de las normas SQL especifica que la definicin de columna no debe admitir valores nulos. De forma predeterminada, SQL Server define la columna para no permitir valores nulos (si no se modific con sp_dboption ) si el usuario omite las palabras clave null o not null en la definicin de columna. En Transact-SQL, es posible definir la columna para que admita valores nulos con la restriccin unique , ya que el ndice nico usado para imponer la restriccin permite insertar valores nulos. Note: No confunda las restricciones de integridad unique y primary key con la informacin definida por los procedimientos del sistema sp_primarykey , sp_foreignkey y sp_commonkey . Las restricciones unique y primary key crean ndices para definir los atributos nicos o de clave primaria de las columnas de tablas. sp_primarykey , sp_foreignkey y sp_commonkey definen la relacin lgica de claves (en la tabla syskeys ) para las columnas de tabla, que se impone mediante la creacin de ndices y disparadores. De forma predeterminada, las restricciones unique crean ndices nicos no agrupados y las restricciones primary key crean ndices nicos agrupados. Los ndices agrupados o no agrupados pueden declararse con cualquiera de los dos tipos de restriccin. Por ejemplo, esta instruccin create table utiliza una restriccin unique a nivel de tabla para garantizar que no haya dos filas con los mismos valores en las columnas stor_id y ord_num : create table my_sales (stor_id char(4), ord_num varchar(20), date datetime, unique clustered (stor_id, ord_num)) Slo puede existir un ndice agrupado en una tabla, de modo que slo puede especificarse una restriccin unique clustered o primary key clustered . Las restricciones unique y primary key pueden emplearse para crear ndices nicos (incluidas las opciones with fillfactor , with max_rows_per_page y on segment_name ) al reforzar la integridad de datos. Sin embargo, los ndices proporcionan funciones adicionales. Para obtener ms informacin sobre los ndices y sus opciones, incluidas las diferencias entre los ndices agrupados y no agrupados, consulte el Captulo 11, "Creacin de ndices en tablas". Especificacin de restricciones de integridad de referencia Se pueden declarar restricciones de integridad de referencia para que los datos insertados en una tabla "de referencia" que defina la restriccin tengan valores coincidentes en una tabla "referenciada". Una restriccin de integridad de referencia se satisface con cualquiera de las siguientes condiciones:

Si una columna de la tabla de referencia incluida con la restriccin contiene un valor nulo Si las columnas de la tabla de referencia incluidas con la restriccin coinciden con las columnas correspondientes de la tabla referenciada

Por ejemplo, esta instruccin create table emplea dos restricciones de integridad de referencia: create table my_salesdetail (stor_id char(4), ord_num varchar(20), title_id char(6) references my_titles(title_id), qty smallint, constraint salesdet_constr
Page 113 of 280

foreign key (stor_id, ord_num) references my_sales (stor_id, ord_num)) La primera restriccin garantiza que cualquier fila insertada en my_salesdetail tenga un valor para title_id que coincida con un valor para la columna title_id de la tabla my_titles . my_salesdetail es la tabla de referencia y my_titles es la tabla referenciada. La segunda restriccin (llamada salesdet_constr ) garantiza que los valores insertados para las columnas stor_id y ord_num de una fila coincidan con columnas con nombres similares en una fila de la tabla my_sales . Una tabla puede incluir una restriccin de integridad de referencia en s misma. No es posible eliminar filas ni actualizar valores de columna de una tabla referenciada que tenga valores coincidentes en una tabla de referencia. Asimismo, slo se puede omitir la tabla referenciada si se omite la tabla de referencia o se quita la restriccin de integridad de referencia. Las restricciones de integridad de referencia a nivel de tabla deben incluir la clusula foreign key y una lista de uno o ms nombres de columna. Los nombres de columna de la clusula references son opcionales slo si las columnas de la tabla referenciada se designan como clave primaria a travs de una restriccin primary key . Cualquier columna referenciada que se especifique debe estar restringida por un ndice nico de dicha tabla. Dicho ndice nico puede crearse mediante la restriccin unique o primary key , o la instruccin create index . Adems, los tipos de datos de las columnas de la tabla de referencia deben coincidir exactamente con el tipo de datos de las columnas de la tabla referenciada. Por ejemplo: create table test_type (col1 char(4) not null references publishers(pub_id), col2 varchar(20) not null) El tipo de datos de col1 de la tabla de referencia ( test_type ) coincide con el tipo de datos de pub_id de la tabla referenciada ( publishers ). Es necesario tener el permiso references en la tabla referenciada para utilizar las restricciones de integridad de referencia. Para obtener ms informacin sobre permisos, consulte la Gua del Usuario de las Caractersticas de Seguridad . Las restricciones de integridad de referencia proporcionan un modo ms sencillo de imponer la integridad de los datos cuando se comparan con la creacin de disparadores. Sin embargo, los disparadores proporcionan funciones adicionales para imponer la integridad de referencia entre tablas. Para obtener ms informacin sobre disparadores, consulte el Captulo 15. Especificacin de restricciones check Es posible declarar una restriccin check para limitar los valores que los usuarios pueden insertar en una columna de una tabla. Una restriccin check especifica una condicin de bsqueda ( search_condition) que los valores deben cumplir antes de su insercin en la tabla. Una condicin de bsqueda puede incluir:

Una lista de expresiones constantes introducidas por in Un rango de expresiones constantes introducidas por between Un conjunto de condiciones introducidas por like , que puede contener caracteres comodn

Una expresin puede incluir operaciones aritmticas y funciones Transact-SQL incorporadas. La condicin de bsqueda no puede contener subconsultas, una especificacin de funcin de conjunto ni una especificacin de destino. Por ejemplo, esta instruccin create table garantiza que slo se introducirn determinados valores en la columna pub_id : create table my_new_publishers (pub_id char(4) check (pub_id in ("1389", "0736", "0877", "1622", "1756") or pub_id like "99[0-9][0-9]"), pub_name varchar(40), city varchar(20), state char(2)) Si la restriccin de verificacin es una restriccin de verificacin a nivel de columna, slo puede hacer referencia a la columna en la que est definida y no puede hacer referencia a ninguna otra columna de la tabla. Las restricciones de verificacin a nivel de tabla pueden hacer referencia a cualquier columna de la tabla. create table permite mltiples restricciones check en una definicin de columna.
Page 114 of 280

Diseo y creacin de tablas Esta seccin proporciona un ejemplo de una instruccin create table que se puede utilizar para crear una tabla prctica propia. Si no dispone del permiso create table , consulte al administrador del sistema o propietario de la base de datos en la que se est trabajando. La creacin de una tabla implica normalmente la creacin de ndices, valores predeterminados y reglas que la acompaan. Con frecuencia tambin se incluyen tipos de datos, disparadores y vistas personalizados. Lgicamente, se puede crear una tabla, introducir algunos datos y trabajar con ellos durante algn tiempo antes de crear ndices, valores predeterminados, reglas, disparadores o vistas. Esto ofrece la oportunidad de ver el tipo de transacciones que son ms comunes y el tipo de datos que se introducen con ms frecuencia. Por otro lado, generalmente es ms eficaz disear una tabla y todos los componentes que la acompaan al mismo tiempo. A continuacin se muestra un esquema de los pasos a seguir. Quizs le resulte ms sencillo realizar un esquema sobre papel antes de crear la tabla y los objetos que la acompaan. 1. 2. 3. 4. 5. Decida qu columnas necesita en la tabla, as como el tipo de datos, longitud, precisin y escala de cada una. Cree los nuevos tipos de datos definidos por el usuario antes de establecer la tabla en la que se van a utilizar. Decida qu columna, si fuera necesario, debe ser la columna IDENTITY. Decida qu columnas deben aceptar valores nulos y cules no. Decida qu restricciones de integridad o valores predeterminados de columna, si los hubiera, es necesario aadir a las columnas de la tabla. Esto tambin implica decidir cundo deben utilizarse las restricciones y valores predeterminados de columna en lugar de los valores predeterminados, reglas, ndices y disparadores para imponer la integridad de los datos. 6. Decida si necesita valores predeterminados y reglas y, en caso afirmativo, determine su ubicacin y tipo. Tenga en cuenta la relacin entre el estado NULL y NOT NULL de una columna, as como los valores predeterminados y las reglas. 7. Decida qu tipo de ndices necesita y su ubicacin. Los ndices se explican en el Captulo 11. 8. Cree la tabla y sus ndices con los comandos create table y create index . 9. Cree los nuevos valores predeterminados y reglas necesarios con los comandos create default y create rule . Estos comandos se explican en el Captulo 12. 10. Vincule los valores predeterminados y reglas necesarios con los procedimientos del sistema sp_bindefault y sp_bindrule . Si hubiera algn valor predeterminado o regla en un tipo de datos definido por el usuario utilizado en una instruccin create table , se activar de forma automtica. Estos procedimientos del sistema se explican en el Captulo 14. 11. Cree disparadores con el comando create trigger . Los disparadores se explican en el Captulo 15. 12. Cree vistas con el comando create view . Las vistas se explican en el Captulo 9. Realizacin de un esquema de diseo La tabla friends_etc se utiliza en captulos subsiguientes para mostrar cmo crear ndices, valores predeterminados, reglas, disparadores, etc.. Dicha tabla puede contener nombres, direcciones, nmeros de telfono e informacin personal sobre amigos, y no define ningn valor predeterminado de columna o restriccin de integridad a fin de evitar entrar en conflicto con dichos objetos. Si piensa seguir los ejemplos y crear todos los objetos de friends_etc , consulte al administrador del sistema o propietario de la base de datos. La persona responsable deber cerciorarse de que, si otro usuario cre la tabla, sus ndices, valores predeterminados, reglas y disparadores, la tabla haya sido omitida a fin de evitar cualquier conflicto al crear los objetos. La siguiente tabla muestra la estructura propuesta de la tabla y los ndices, valores predeterminados y reglas que acompaarn a cada columna. Tabla 7-1: Muestra de un diseo de tabla Columna Tipo de datos NULL? Indice Valor predeterminado Regla

pname sname address city state zip

nm nm varchar(30) varchar(30) char(2) char(5)

NOT NULL nmind (compuesto) NOT NULL nmind (compuesto) NULL NOT NULL NOT NULL NULL

citydflt statedflt zipind zipdflt ziprule


Page 115 of 280

phone age bday sex debt notes

p# tinyint datetime bit money varchar(255)

NULL NULL NOT NULL NOT NULL NOT NULL NULL

phonerule agerule bdflt sexdflt sexdflt

Creacin de tipos de datos definidos por el usuario Las dos primeras columnas son para el nombre y apellido, y su tipo de datos est definido como nm . Antes de crear la tabla, es necesario generar el tipo de datos. Lo mismo ocurre con el tipo de datos p# de la columna phone . El tipo de datos nm permite una entrada de caracteres de longitud variable con un mximo de 30 bytes. El tipo de datos p # permite un tipo de datos char con un tamao de longitud fija de 10 bytes. Introduzca las definiciones de tipo de datos de nm y p # de esta forma: execute sp_addtype nm, "varchar(30)" execute sp_addtype p#, "char(10)" Seleccin de columnas que aceptan valores nulos Salvo las columnas a las que se asignan tipos de datos definidos por el usuario, cada columna tiene una entrada explcita NULL o NOT NULL. Recuerde que no es necesario especificar NOT NULL en la definicin de tabla, porque se trata del valor predeterminado. Este diseo de tabla especifica NOT NULL de forma explcita para facilitar la lectura. El valor predeterminado NOT NULL quiere decir que se precisa una entrada, por ejemplo, para las dos columnas de nombre de esta tabla. Los dems datos no tienen sentido sin los nombres. Adems, la columna sex debe ser NOT NULL porque no se puede utilizar NULL con columnas bit . Si se designa una columna como NULL y se vincula con un valor predeterminado, cuando no se proporciona ningn otro valor en la entrada, se introduce el valor predeterminado, en lugar de NULL. Si se designa una columna NULL y se vincula con una regla que no especifica NULL, cuando no se introduce ningn valor para la columna, la definicin de columna ignora la regla. Las columnas pueden tener valores predeterminados y reglas. La relacin entre ambos se explica en un captulo posterior. Definicin de una tabla Ahora puede escribir la instruccin create table : create table (pname sname address city state postalcode phone age bday sex debt notes friends_etc nm no varchar(30) varchar(30) char(2) char(5) p# tinyint datetime bit money varchar(255)

not null, not null, null, not null, not null, null, null, null, not null, not null, not null, null

Ahora hay columnas definidas para nombre y apellido, direccin, ciudad, estado, cdigo postal, nmero de telfono, edad, fecha de nacimiento, sexo, informacin sobre deudas y notas. En otros captulos se describe el modo de crear reglas, valores predeterminados, ndices, disparadores y vistas usados con la tabla. Creacin de tablas nuevas a partir de resultados de consultas: select into La clusula select into se puede utilizar para hacer una seleccin dentro de una tabla permanente, slo si la opcin de base de datos select into/bulkcopy est definida como on . El administrador del sistema puede activar esta opcin con el
Page 116 of 280

procedimiento del sistema sp_dboption . Para comprobar si esta opcin est activada, ejecute el procedimiento del sistema sp_helpdb . A continuacin se muestra el comando y sus resultados si la opcin est activada: sp_helpdb pubs2 name db_size owner --------- ------- -----pubs 2 MB sa (1 row affected) device ----------------master (1 row affected) Si la opcin est desactivada, el informe generado por sp_helpdb as lo indica. Slo el administrador del sistema o el propietario de la base de datos pueden definir las opciones de base de datos. Si la opcin de base de datos select into/bulkcopy est activada, puede utilizar la clusula select into para crear una tabla nueva permanente sin emplear una instruccin create table . Es posible usar select into en una tabla temporal, incluso si la opcin no est activada. Note: Dado que select into es una operacin no registrada, use dump database para realizar una copia de seguridad de la base de datos despus de un select into . No utilice dump transaction , puesto que un volcado del diario despus de una operacin no registrada no es utilizable con load transaction . A diferencia de una vista que muestra parte de una tabla, una tabla creada con select into es una entidad diferente e independiente. Consulte el Captulo 9 para obtener informacin detallada sobre las vistas. La tabla nueva se basa en las columnas especificadas en la lista de seleccin, las tablas indicadas en la clusula from y las filas elegidas en la clusula where . El nombre de la tabla nueva debe ser nico en la base de datos y cumplir con las reglas para identificadores. Una instruccin select con una clusula into permite definir una tabla y poner datos en ella, basndose en definiciones y datos existentes, sin realizar el proceso de definicin de datos habitual. El siguiente ejemplo muestra una instruccin select into y sus resultados. Se crea una tabla llamada newtable a partir de dos de las cuatro columnas de la tabla publishers . Dado que esta instruccin concreta no incluye ninguna clusula where , los datos de todas las filas (pero slo dos de las columnas) se copian en newtable . select pub_id, pub_name into newtable from publishers (3 rows affected) El mensaje de SQL Server "3 rows affected" se refiere a las tres filas insertadas en newtable . Este es el aspecto de newtable : select * from newtable pub_id pub_name ------ -----------------------------------0736 New Age Books 0877 Binnet & Hardley 1389 Algodata Infosystems (3 rows affected) La tabla nueva contiene los resultados de la instruccin select y pasa a formar parte de la base de datos, al igual que su tabla madre. La clusula into resulta til para crear tablas de prueba, tablas nuevas como copias de tablas existentes, y para generar varias tablas pequeas a partir de una grande. Tambin se puede utilizar select into para crear una tabla base sin datos mediante la colocacin de una condicin falsa en la clusula where . Por ejemplo:
Page 117 of 280

dbid ----5

created ----------Jun 3 1988

status -----------select into /bulkcopy

size --------2 MB

usage -------------data and log

select * into newtable2 from publishers where 1=2 (0 rows affected) select * from newtable2 pub_id pub_name ---------------------(0 rows affected)

city -----------

state

No se inserta ninguna fila en la tabla nueva, porque 1 nunca es igual a 2. Tambin puede utilizar select into con funciones agregadas para crear tablas con datos de totalizacin: select type, "Total_amount" = sum(advance) into #whatspent from titles group by type (6 rows affected) select * from #whatspent type Total_amount ------------ -----------------------UNDECIDED NULL business 25,125.00 mod_cook 15,000.00 popular_comp 15,000.00 psychology 21,275.00 trad_cook 19,000.00 (6 rows affected) Siempre debe proporcionarse un nombre de columna para cualquier columna de la tabla de resultados de select into que resulte de una funcin agregada o de cualquier otra expresin, como la realizacin de operaciones aritmticas ( amount*2 ), la concatenacin ( lname + fname ) o el uso de funciones incorporadas de SQL Server ( lower(lname) ). A continuacin se muestra un ejemplo del uso de la concatenacin: select au_id, "Full_Name" = au_fname + ' ' + au_lname into #g_authortemp from authors where au_lname like "G%" (3 rows affected) select * from #g_authortemp au_id Full_Name ----------- ------------------------213-46-8915 Marjorie Green 472-27-2349 Burt Gringlesby 527-72-3246 Morningstar Greene (3 rows affected) Seleccin de una columna IDENTITY Para seleccionar una columna IDENTITY en una tabla nueva, hay que incluir el nombre de la columna (o la palabra clave syb_identity ) en la lista de columnas de la instruccin de seleccin. La columna nueva hereda la propiedad IDENTITY, a menos que se cumpla alguna de las siguientes condiciones:

La columna IDENTITY est seleccionada ms de una vez. La columna IDENTITY est seleccionada como parte de una expresin. La instruccin select contiene una clusula group by , funcin agregada, operador union o combinacin.

Adicin de una nueva columna IDENTITY con select into Para definir una nueva columna IDENTITY en una instruccin select into , hay que aadir la definicin de columna antes de la clusula into . Observe que la definicin incluye la precisin de la columna, pero no su escala:

Page 118 of 280

select column_list identity_column_name into table_name from table_name

= identity(

precision

No es posible utilizar select into para crear una tabla nueva con mltiples columnas IDENTITY. Si la instruccin select incluye una columna IDENTITY existente y una especificacin IDENTITY nueva, la instruccin no se ejecuta correctamente. Para obtener ms informacin sobre columnas IDENTITY, consulte select y la seccin sobre columnas IDENTITY en el Manual de Referencia de SQL Server . Omisin de tablas El comando para quitar una tabla de una base de datos es drop table . Su sintaxis es: drop table [[ database .] owner .] table_name [, [[ database .] owner .] table_name ]... Cuando se ejecuta este comando, SQL Server quita las tablas especificadas de la base de datos, junto con su contenido y todos los ndices y privilegios asociados a ellas. Las reglas o valores predeterminados vinculados a la tabla dejan de estar vinculados, pero no son afectados. Es necesario ser el propietario de una tabla para poder omitirla. Sin embargo, nadie puede omitir una tabla mientras est en uso, es decir, mientras un usuario o un programa frontal la est leyendo o escribiendo. El comando drop table no puede utilizarse en ninguna de las tablas del sistema, en la base de datos master ni en una base de datos de usuario. Como indica la sintaxis, el usuario puede omitir una tabla de otra base de datos siempre que sea propietario de la tabla. Si elimina todas las filas de una tabla (con delete ) o utiliza el comando truncate table , la tabla continuar existiendo hasta que se omita (con drop ). El permiso drop table y truncate table no puede transferirse a otros usuarios. Alteracin de tablas existentes Si cambia de opinin sobre la estructura de una tabla despus de haberla utilizado durante algn tiempo y decide que es necesario modificar la manera en que est definida, tiene estas alternativas:

Aadir columnas y restricciones, omitir restricciones o cambiar valores predeterminados de columna mediante el comando alter table . Cambiar el nombre de una tabla, columna o cualquier otro objeto de base de datos con el procedimiento del sistema sp_rename .

Cambio de las estructuras de tabla: alter table El comando alter table permite realizar los siguientes cambios en tablas existentes:

Aadir columnas (salvo columnas de tipo de datos bit ) Aadir restricciones Omitir restricciones Sustituir los valores predeterminados definidos para sus columnas

A continuacin se muestra la sintaxis de alter table : alter table [ database .[ owner ].] table_name {add column_name datatype [default { constant_expression | user | null}] {[{identity | null}] | [[constraint constraint_name ] {{unique | primary key} [clustered | nonclustered] [with {fillfactor | max_rows_per_page} = x]
Page 119 of 280

[on segment_name ] | references [[ database .] owner [( ref_column )] | check ( search_condition )}]}... {[, next_column ]}...

.]

ref_table

| add {[constraint constraint_name ] {unique | primary key} [clustered | nonclustered] ( column_name [{, column_name }...]) [with {fillfactor | max_rows_per_page} = x] [on segment_name ] | foreign key ( column_name [{, column_name }...]) references [[ database .] owner .] ref_table [( ref_column [{, ref_column }...])] | check ( search_condition )} | drop constraint constraint_name | user | null}}

| replace column_name default { constant_expression

El nmero de columnas de una tabla no puede ser superior a 250, tanto si se aaden con una instruccin alter table como si se definen con la instruccin create table original. Una tabla slo puede tener una columna IDENTITY con un tipo de datos numeric y una escala de cero. Cuando se aade una columna IDENTITY con la instruccin alter table, SQL Server asigna un valor secuencial nico a cada fila existente. Todas las dems columnas que se aadan deben permitir valores nulos. Esto se debe a que, cuando se aade la columna nueva a las filas existentes, debe tener algn valor. Hay que especificar null cuando se aade una columna diferente a la columna IDENTITY. Note: Si los procedimientos almacenados que utilizan select * hacen referencia a una tabla alterada, el procedimiento, aunque se utilice la opcin with recompile , no tomar ninguna columna nueva que pueda haberse aadido a la tabla. Es preciso omitir el procedimiento y volver a crearlo. Por ejemplo, se puede aadir una columna a la tabla friends_etc de la siguiente manera: alter table friends_etc add country varchar(20) null Luego se puede aadir una o ms restricciones de integridad a la columna nueva (o a cualquier otra columna) de friends_etc : alter table friends_etc add constraint no_old_country check (country not in ("GDR", "E. Germany", "East Germany")) Cuando no se necesita una restriccin, puede omitirse: alter table friends_etc drop constraint no_old_country Para omitir restricciones, especifique el nombre de restriccin. Si desea determinar los nombres de las restricciones definidas para una tabla, utilice el procedimiento almacenado del sistema sp_helpconstraint , descrito en "Uso de sp_helpconstraint en tablas". alter table tambin permite cambiar el valor predeterminado definido para una columna (o aadir un valor predeterminado de columna si no existe ninguno). Por ejemplo: alter table friends_etc replace country default "USA" Para obtener ms informacin sobre valores predeterminados de columna y restricciones de integridad, consulte la seccin "Definicin de restricciones de integridad para tablas".
Page 120 of 280

Cambio de nombre de tablas y otros objetos Para cambiar el nombre de las tablas y otros objetos de base de datos (vistas, ndices, reglas, valores predeterminados, procedimientos y disparadores), utilice el procedimiento del sistema sp_rename . Para cambiar el nombre de un objeto, es necesario ser el propietario. Para cambiar el nombre de la base de datos, utilice el procedimiento del sistema sp_renamedb . Consulte el Manual de Referencia de SQL Server para obtener informacin sobre sp_renamedb . Esta es la sintaxis de sp_rename : sp_rename objname , newname

Por ejemplo, para cambiar el nombre de friends_etc a infotable , escriba lo siguiente: sp_rename friends_etc, infotable Tambin puede utilizarse sp_rename para cambiar el nombre de otros objetos: columnas, valores predeterminados, reglas, procedimientos, vistas, disparadores, restricciones de verificacin, restricciones de integridad de referencia y tipos de datos del usuario. Si cambia el nombre de una columna, use esta sintaxis: sp_rename "table.column", newcolumnname Omita el prefijo del nombre de la tabla del nuevo nombre de columna, ya que, de lo contrario, no se aceptar el nombre nuevo. Para cambiar el nombre de un ndice, use esta sintaxis: sp_rename "table.index", newindexname Una vez ms, no incluya el nombre de tabla en el nombre nuevo. A continuacin se indica cmo cambiar el nombre del tipo de datos de usuario tid a t_id : exec sp_rename tid, "t_id" No se puede cambiar el nombre de los objetos del sistema ni de los tipos de datos del sistema. El objeto cuyo nombre se est cambiando debe estar en la base de datos actual. Slo el propietarios de los objetos puede cambiar los nombres de los mismos. Sin embargo, el propietario de la base de datos puede cambiar el nombre de cualquier objeto de usuario. El usuario slo puede cambiar los nombres de los objetos que son de su propiedad. El propietario de la base de datos puede cambiar el nombre de cualquier objeto de usuario. Efecto del cambio de nombre en objetos dependientes Los procedimientos, disparadores y vistas que dependen de un objeto cuyo nombre se ha cambiado funcionan bien hasta que se vuelven a compilar. Sin embargo, la recompilacin tiene lugar por diversas razones y sin notificacin al usuario, por ejemplo, si se carga una base de datos, o si un usuario omite y vuelve a crear una tabla u omite un ndice. Cuando SQL Server vuelve a compilar el procedimiento, disparador o vista, stos dejan de funcionar. El usuario debe cambiar su texto para reflejar el nombre de objeto nuevo. Adems, el nombre de objeto antiguo aparecer en los resultados de la consulta hasta que el procedimiento, disparador o vista se haya cambiado y vuelto a compilar. La forma ms segura es cambiar las definiciones de cualquier objeto dependiente al ejecutar sp_rename . El procedimiento del sistema sp_depends proporciona una lista de objetos dependientes. Asignacin de permisos a los usuarios Los comandos grant y revoke de SQL controlan el sistema de proteccin de objetos y comandos de SQL Server. Pueden concederse diversos tipos de permisos a los usuarios, grupos y roles mediante el comando grant y revocarse con el comando revoke . grant y revoke se usan a fin de conceder permisos a los usuarios para:

Crear bases de datos Crear objetos en una base de datos


Page 121 of 280

Tener acceso a tablas, vistas y columnas Ejecutar procedimientos almacenados

Algunos comandos pueden ser utilizados por cualquier usuario a cualquier hora, sin necesidad de permiso alguno. Otros slo los pueden emplear los usuarios con un estado determinado (por ejemplo, el administrador del sistema), y no es posible transferirlos. La capacidad de asignar permisos para los comandos que pueden concederse y revocarse depende del estado de cada usuario (administrador del sistema, propietario de la base de datos o propietario del objeto de base de datos) o de si un usuario concreto recibi un permiso con la opcin para conceder este permiso a otro usuario. El propietario de una base de datos no recibe permisos sobre objetos que son propiedad de otros usuarios de forma automtica. Sin embargo, el propietario de la base de datos o el administrador del sistema pueden adoptar cualquier permiso asumiendo la identidad del propietario del objeto mediante el comando setuser y escribiendo la instruccin grant o revoke apropiada. Es posible asignar dos clases de permisos con grant y revoke : permisos de acceso a objetos y permisos de creacin de objetos . Los permisos de acceso a objetos controlan el uso de determinados comandos que proporcionan acceso a objetos de base de datos concretos. Por ejemplo, el usuario debe recibir explcitamente el permiso para usar el comando select con la tabla authors . Los permisos de acceso a objetos los concede y revoca el propietario del objeto en cuestin. La siguiente instruccin concede a Mary y Joe permiso de acceso a objetos para realizar operaciones con insert y delete en la tabla titles : grant insert, delete on titles to mary, joe Los permisos de creacin de objetos controlan el uso de los comandos que crean objetos y slo pueden ser concedidos por el administrador del sistema o el propietario de la base de datos. La siguiente instruccin revoca el permiso de creacin de objetos para crear tablas y reglas en la base de datos actual de Mary: revoke create table, create rule from mary Para obtener informacin completa sobre el uso de grant y revoke para los permisos de acceso a objetos y de creacin de objetos, consulte la Gua del Usuario de las Caractersticas de Seguridad . Obtencin de informacin sobre bases de datos y tablas SQL Server proporciona varios procedimientos almacenados del sistema para obtener informacin sobre bases de datos, tablas y otros objetos de base de datos. En esta seccin se describen cuatro de ellos: sp_help , sp_helpdb , sp_helpconstraint y sp_spaceused . Para obtener informacin completa sobre los procedimientos del sistema, consulte el Manual de Referencia de SQL Server . Uso de sp_help en objetos de base de datos El procedimiento del sistema sp_help proporciona informacin sobre un objeto de base de datos especificado (es decir, cualquier objeto enumerado en sysobjects ), un tipo de datos especificado (enumerado en systypes ) o todos los objetos y tipos de datos de la base de datos actual. Esta es la sintaxis de sp_help : sp_help [ objname ]

A continuacin se muestra la salida de la tabla publishers :

Page 122 of 280

Name -------------------------publisher

Owner Type ----------- -------dbo user table

Data_located_on_segment When_created ------------------------------------------------default Jan 1 1900 12:00AM Column_name Type Length Prec Scale ----------- ------- ---------- ----pub_id char 4 NULL NULL pub_name varchar 40 NULL NULL city varchar 20 NULL NULL state char 2 NULL NULL Nulls Default_name Rule_name Identity ----------------- ---------------0 NULL NULL 0 1 NULL NULL 0 1 NULL NULL 0 1 NULL NULL 0 index_name index_description index_keys -------------- ------------------------------------ ---------pubind clustered, unique located on default pub_id (1 row affected) keytype object related_object related_keys ------- ---------- --------------------------------------primary publishers -- none -*, *, *, *, *, *, *, * foreign titles publishers pub_id, *, *, *, *, *, *, * (return status = 0) Si ejecuta sp_help sin suministrar un nombre de objeto, el informe resultante muestra una lista breve de cada objeto de sysobjects , con su nombre, propietario y tipo de objeto. Tambin muestra cada tipo de datos definido por el usuario de systypes y su nombre, tipo de almacenamiento y longitud, si se admiten valores nulos, y los nombres de los valores predeterminados o reglas vinculados a l. El informe indica, adems, si se han definido columnas de claves primarias o externas para una tabla o vista con los procedimientos del sistema sp_primarykey o sp_foreignkey . sp_help muestra los ndices de una tabla, incluidos los ndices creados mediante la definicin de restricciones unique o primary key de instrucciones create table o alter table . Sin embargo, no ofrece informacin sobre las restricciones de integridad definidas para una tabla. Para obtener informacin sobre las restricciones de integridad, utilice sp_helpconstraint . Uso de sp_helpdb en bases de datos El procedimiento del sistema sp_helpdb proporciona informacin sobre una base de datos especificada, o sobre todas las bases de datos de SQL Server. sp_helpdb muestra informacin sobre el nombre, tamao y uso de cada fragmento asignado a la base de datos con create o alter database . Su sintaxis es: sp_helpdb [ dbname ] object_keys ----------------------------pub_id, *, *, *, *, *, *, * pub_id, *, *, *, *, *, *, *

A continuacin se muestra cmo obtener un informe sobre pubs2 : sp_helpdb pubs2 name db_size ----------pubs2 2 MB (1 row affected) device ----------------pubsdev (1 row affected) Uso de sp_helpconstraint en tablas
Page 123 of 280

owner dbid created ------ ---- --------------sa 4 Jan 10 1988 size ----------2 MB usage -------------data + log

status ------------no se ha establecido ninguna opcin

El procedimiento del sistema sp_helpconstraint proporciona informacin sobre cualquier restriccin de integridad especificada para una tabla. Esta informacin incluye el nombre de la restriccin y la definicin del valor predeterminado, restriccin de clave nica o primaria , restriccin de referencia o restriccin de verificacin. Su sintaxis es: sp_helpconstraint objname [, detail] De forma predeterminada, sp_helpconstraint imprime slo el nombre y la definicin de la restriccin de integridad. Si especifica la opcin detail con este procedimiento del sistema, tambin se obtiene informacin sobre el usuario de la restriccin o mensajes de error. Por ejemplo, suponga que la tabla states se define as: create table states (rank smallint, abbrev char(2), name varchar(20) null, population int check (population > 1000000), constraint stateconstr primary key (rank, abbrev)) Para conseguir informacin sobre sus restricciones, ejecute sp_helpconstraint : sp_helpconstraint states name ----------------------states_popula_1088006907 stateconstr

defn --------------------------------------CHECK (population > 1000000) PRIMARY KEY INDEX (rank, abbrev): CLUSTERED,FOREIGN REFERENCE (3 rows affected, return status = 0) Uso de sp_spaceused en tablas Para saber la cantidad de espacio que utiliza una tabla, utilice el procedimiento del sistema sp_spaceused . Su sintaxis es: sp_spaceused [ objname ]

Este procedimiento del sistema tambin funciona con ndices, que se describen en el Captulo 11, "Creacin de ndices en tablas". sp_spaceused calcula y muestra el nmero de filas y pginas de datos utilizadas por una tabla o un ndice agrupado o no agrupado. A continuacin se muestra cmo obtener un informe sobre el espacio empleado por la tabla titles : sp_spaceused titles name rows reserved data index_size unused ------- ----- ---------- ----- --------- -----titles 18 48 KB 6 KB 4 KB 38 KB (0 rows affected) Si no se introduce ningn nombre de objeto como parmetro, sp_spaceused muestra un resumen del espacio utilizado por todos los objetos de base de datos. Chapter 8

Adicin, modificacin y eliminacin de datos


Una vez que haya creado una base de datos, tablas e ndices, querr introducir datos en las tablas y trabajar con ellos (aadiendo, modificando y eliminando datos, segn lo necesario). En este captulo se trata lo siguiente:

Introduccin general a las formas en que se modifican datos Reglas asociadas con la introduccin de datos para determinados tipos de datos Adicin de nuevos datos en las tablas Modificacin de datos existentes en tablas Modificacin de datos text
Page 124 of 280

Eliminacin de datos de tablas Eliminacin (o truncado) de todas las filas de una tabla Opciones disponibles para la modificacin de datos Reglas para la introduccin de tipos de datos Adicin de datos nuevos Modificacin de datos existentes Modificacin de datos text e image Eliminacin de datos Eliminacin de todas las filas de una tabla

Opciones disponibles para la modificacin de datos El comando insert permite aadir nuevas filas a la base de datos. El comando update permite cambiar las filas existentes en la base de datos. El comando delete permite eliminar filas de la base de datos. El comando writetext permite aadir y modificar datos de tipo text e image sin escribir cambios largos en el diario de transacciones del sistema. Estas operaciones se denominan colectivamente instrucciones de modificacin de datos . El comando truncate table , que elimina todas las filas de una tabla, tambin se explica en este captulo. Otro mtodo para aadir datos a una tabla es transferirlos desde un archivo mediante el programa de utilidad de copia masiva, bcp . Para obtener informacin sobre estas facilidades, consulte el Manual de Referencia de SQL Server y el manual sobre utilidades de su sistema operativo. Mediante las instrucciones insert , update o delete , es posible modificar datos en una sola tabla por instruccin. Sin embargo, las modificaciones que realice pueden basarse en los datos de otras tablas, e incluso de otras bases de datos. Esta es una mejora de Transact-SQL con respecto a las versiones estndar de SQL. Los comandos de modificacin de datos pueden aplicarse a las vistas adems de a las tablas, aunque con algunas restricciones. Consulte el Captulo 9, "Vistas: limitacin del acceso a datos", para obtener ms detalles al respecto. Permisos Los comandos de modificacin de datos no estn necesariamente a disposicin de todos los usuarios. El propietario de la base de datos y los propietarios de los objetos de base de datos usan los comandos grant y revoke para decidir quines tendrn acceso a las distintas funciones de modificacin de datos. Es posible conceder permisos o privilegios a usuarios individuales, a grupos o a los usuarios en general, para cualquier combinacin de comandos de modificacin de datos. Los permisos se tratan en la Gua del Usuario de las Caractersticas de Seguridad . Integridad de referencia insert , update , delete , writetext y truncate table permiten modificar los datos de la base de datos. Sin embargo, si modifica los datos de una tabla sin alterar los datos relacionados de otras tablas, pueden producirse disparidades. Por ejemplo, si descubre que la entrada au_id correspondiente a Sylvia Panteley es incorrecta y la cambia en la tabla authors , tambin deber cambiarla en la tabla titleauthor y en cualquier otra tabla de la base de datos que contenga una columna con ese valor. Si no lo hace, no podr encontrar datos como los nombres de los libros de Sylvia Panteley, porque ser imposible realizar combinaciones con su columna au_id . El problema general de mantener la consistencia de las modificaciones de datos en todas las tablas de una base de datos se denomina integridad de referencia. Una forma de solucionar este problema es crear procedimientos especiales, llamados disparadores, que se activan automticamente al ejecutar los comandos insert , update y delete en tablas o columnas concretas (el comando truncate table no es atrapado por los disparadores). Otra posibilidad es definir restricciones de integridad de referencia para la tabla. Los disparadores se tratan en el Captulo 15, "Disparadores: imposicin de la integridad de referencia" y las restricciones de integridad en el Captulo 7, "Creacin de bases de datos y tablas". Transacciones En el diario de transacciones se escribe una copia del estado antiguo y nuevo de cada fila afectada por las distintas instrucciones de modificacin, con excepcin de writetext . Esto significa que si comienza una transaccin ejecutando el
Page 125 of 280

comando begin transaction , advierte que ha cometido un error y revierte la transaccin, puede restaurar la base de datos a su estado anterior. Note: Los cambios realizados en un SQL Server remoto mediante una llamada de procedimientos remotos (RPC) no se pueden revertir. El modo de funcionamiento predeterminado de writetext no registra las transacciones. Esto evita que el diario de transacciones se llene con los largusimos bloques de datos que pueden contener los campos text e image . Para registrar los cambios realizados con este comando, utilice la opcin with log del comando writetext . En el Captulo 17, "Transacciones: mantenimiento de la consistencia y recuperacin de datos". encontrar una explicacin ms completa sobre las transacciones. Uso de la base de datos de muestra Si sigue los ejemplos de este captulo en su pantalla, es conveniente comenzar con una copia limpia de la base de datos pubs2 y limpiarla al terminar. Consulte al administrador del sistema para obtener una copia limpia de la base de datos pubs2 . Si comienza con una copia limpia de la base de datos pubs2 , puede evitar que los cambios realizados sean permanentes incluyendo todas las instrucciones en una transaccin y abortando la transaccin una vez que termine con este captulo. Inicie la transaccin escribiendo lo siguiente: begin tran modify_pubs2 Esta transaccin se llama modify_pubs2 . Se puede cancelar la transaccin en cualquier momento y restaurar la base de datos a la situacin original, escribiendo: rollback tran modify_pubs2 Reglas para la introduccin de tipos de datos Varios tipos de datos suministrados por SQL Server tienen reglas especiales para introducir y buscar datos. Estas reglas se detallan en los siguientes apartados. Para obtener ms informacin sobre los tipos de datos, consulte el Captulo 7, "Creacin de bases de datos y tablas".

char , nchar , varchar , nvarchar y text


No olvide que todos los datos character , text y datetime se deben escribir entre comillas simples o dobles al ser introducidos y cuando se buscan. Utilice comillas simples si la opcin quoted_identifier est definida como on (activada). Si emplea comillas dobles, SQL Server tratar el texto como un identificador. Consulte el Manual de Referencia de SQL Server para obtener ms detalles sobre la insercin de datos text . Si introduce cadenas ms largas que la longitud especificada de una columna char , nchar, varchar o nvarchar , la entrada queda truncada. Active la opcin string_rtruncation para recibir un mensaje de aviso cuando esto ocurra. Hay dos formas de especificar comillas literales dentro de una entrada de caracteres. El primer mtodo consiste en utilizar dos comillas. Por ejemplo, si comienza una entrada de caracteres con una comilla simple y desea incluir otra como parte de la entrada, emplee dos comillas simples seguidas: 'I don' 't understand'. Con comillas dobles: "He said, ""It's not really confusing""" . El segundo mtodo consiste en incluir una comilla entre comillas del otro tipo. En otras palabras, site una entrada con comillas dobles entre comillas simples, o viceversa. Por ejemplo: 'George said, "There must be a better way" '. Para introducir una cadena de caracteres ms larga que la anchura de la pantalla, introduzca una barra invertida (\) antes de pasar a la siguiente lnea. La palabra clave like y los caracteres comodn descritos en el Captulo 2, "Consultas: seleccin de datos de una tabla", pueden utilizarse para buscar datos de tipo character , text y datetime . Consulte la seccin sobre tipos de datos en el Manual de Referencia SQL Server para obtener informacin sobre los espacios en blanco finales en los datos character .
Page 126 of 280

datetime y smalldatetime
Los formatos de visualizacin y de entrada de los datos datetime proporcionan una amplia gama de formatos de salida para las fechas, adems de reconocer numerosos formatos de entrada. Los formatos de visualizacin y de entrada se controlan por separado. El formato de visualizacin predeterminado proporciona una salida que tiene el siguiente aspecto: "Apr 15 1987 10:23PM". El comando convert proporciona varias opciones para mostrar los segundos y milisegundos y presentar la fecha con ordenaciones distintas de sus componentes. Consulte el Captulo 10, "Uso de funciones incorporadas en consultas", para obtener ms informacin sobre la presentacin de los valores de fecha. SQL Server reconoce una amplia gama de formatos de entrada de datos para las fechas. Las maysculas y minsculas siempre se ignoran y los espacios pueden tener cualquier ubicacin entre los componentes de la fecha. Cuando introduzca valores de tipo datetime y smalldatetime , inclyalos siempre entre comillas simples o dobles (use comillas simples si la opcin quoted_identifier est activada; si emplea comillas dobles, SQL Server tratar la entrada como si fuera un identificador). SQL Server reconoce por separado las dos partes (fecha y hora) de los datos, de modo que puede situar la hora antes o despus de la fecha y omitir cualquiera de las dos partes. SQL Server proporciona valores predeterminados, descritos tambin a continuacin. Si se omiten las dos partes, la fecha predeterminada es el 1 de enero de 1900, 12:00:00:000AM (January 1, 1900, 12:00:00:000AM). Para datetime, la fecha ms antigua que puede usarse es el 1 de enero de 1753 (January 1, 1753) y la ltima el 31 de diciembre de 9999 (December 31, 9999). Para smalldatetime , la fecha ms antigua que puede usarse es el 1 de enero de 1900 y la ltima el 6 de junio de 2079 (June 6, 2079). Las fechas anteriores o posteriores se deben introducir, almacenar y manipular como valores char o varchar . SQL Server rechaza todos los valores que no puede reconocer como fechas comprendidas en los mrgenes indicados. Introduccin de horas El orden de los componentes de la hora es relevante para la parte horaria de los datos. Introduzca las horas, minutos y segundos, en este orden, y despus AM, am, PM o pm. 12AM es medianoche y 12PM es medioda. Para que un valor se reconozca como una hora, debe contener un signo de dos puntos (:) o el calificador AM/PM. Observe que smalldatetime slo precisa hasta los minutos. Los milisegundos pueden ir precedidos de un signo de dos puntos o de un punto. Si van precedidos de dos puntos, el nmero expresar milsimas de segundo y, si van precedidos de un punto, un solo dgito indicar dcimas de segundo, dos dgitos centsimas de segundo y tres dgitos, milsimas de segundo. Por ejemplo, '12:30:20:1' expresa las 12:30 y 20 segundos y una milsima de segundo, mientras que '12:30:20.1' expresa las 12:30 y 20 segundos y una dcima de segundo A continuacin se indican algunos de los formatos aceptables para la hora: 14:30 14:30[:20:999] 14:30[:20.9] 4am 4 PM [0]4[:30:20:500]AM Introduccin de fechas El comando set dateformat permite especificar el orden de los componentes de las fechas (mes, da y ao) cuando se introducen como cadenas de nmeros con separadores. Cambiar de idioma con set language tambin puede afectar al formato de fechas, segn el formato de fecha predeterminado del idioma. El idioma predeterminado es us_english y el formato de fecha predeterminado es mdy . Consulte el comando set en el Manual de Referencia de SQL Server para obtener ms informacin al respecto. Note: dateformat slo afecta a las fechas introducidas como nmeros con separadores, como "4/15/90" o "20.05.88". No afecta a las fechas en las que el mes se indica en formato alfanumrico, como "April 15, 1990", o en las que no hay separadores, como "19890415". SQL Server reconoce tres estilos bsicos para la introduccin de fechas. Cada uno de los formatos de fecha indicados a continuacin debe ir entre comillas cuando se utilice y puede estar precedido o seguido de una especificacin horaria, segn lo descrito anteriormente.

El mes se introduce en formato alfanumrico.


Page 127 of 280

o o o o o o o o

El mes puede ser una abreviatura de 3 caracteres o el nombre completo del mes, de acuerdo con la especificacin del idioma utilizado. Las comas son opcionales. No se realiza distincin entre maysculas y minsculas. Si slo especifica los dos ltimos dgitos del ao, los valores menores que 50 se interpretan como "20yy" ("20aa"), mientras que el 50 y los valores mayores que 50 se interpretan como "19yy" ("19aa"). Escriba el siglo slo si omite el da o necesita especificar un siglo que no sea el predeterminado, segn lo descrito anteriormente. Si falta el da en la fecha, se le asigna el primer da del mes predeterminadamente. Cuando se especifica el mes en formato alfabtico, el parmetro de dateformat (consulte el comando set ) siempre se ignora. Estos son formatos vlidos para especificar la fecha alfabticamente: Apr[il] [15][,] 1988 Apr[il] 15[,] [19]88 Apr[il] 1988 [15] [15] Apr[il][,] 1988 15 Apr[il][,] [19]88 15 [19]88 apr[il] [15] 1988 apr[il] 1988 APR[IL] [15] [19]88 APR[IL] 15 1988 [15] APR[IL]

El mes se introduce con formato numrico en una cadena con separadores de barra (/), guin (-) o punto (.). o Se debe especificar el mes, da y ao. o Las cadenas deben tener el siguiente formato: <num> <sep> <num> <sep> <num> [ <time spec> ] o bien: [ <time spec> ] <num> <sep> <num> <sep> <num> o La interpretacin de los valores que componen las fechas depende del parmetro de dateformat . Si el orden no coincide con el parmetro, los valores no se interpretan como fechas, por estar fuera de margen, o se interpretan incorrectamente. Por ejemplo, "12/10/08" podra interpretarse como seis fechas distintas, dependiendo del parmetro de dateformat . Consulte el comando set para obtener ms informacin al respecto. o Para introducir "15 de abril de 1988" (April 15, 1988) en el orden mdy de dateformat , se pueden usar estos formatos: [0]4/15/[19]88 [0]4-15-[19]88 [0]4.15.[19]88

Los dems rdenes de introduccin se muestran a continuacin con barras (''/") como separadores, aunque tambin pueden emplearse guiones o puntos: 15/[0]4/[19]88 [19]88/[0]4/15 [19]88/15/[0]4 [0]4/[19]88/15 15/[19]88/[0]4 (dmy) (ymd) (ydm) (myd) (dym)

La fecha se proporciona como una cadena de 4, 6 u 8 dgitos no separados, como una cadena vaca o con la hora, pero sin valores de fecha. o El parmetro de dateformat siempre se ignora con este formato de entrada. o Si se introducen 4 dgitos, la cadena se interpreta como el ao, mientras que el mes y el da se definen como el 1 de enero. No es posible omitir el siglo. o Las cadenas de 6 y 8 dgitos siempre se interpretan como ymd; el mes y el da siempre deben tener 2 dgitos. El siguiente formato se reconoce: [19]880415 o Si se introduce una cadena vaca (" ") o no se indica fecha, se interpreta como la fecha base, el 1 de enero de 1900. Por ejemplo, un valor horario de "4:33" sin ninguna fecha se interpreta como "January, 1, 1900, 4:33AM''.

Bsqueda de fechas y horas Es posible utilizar la palabra clave like y los caracteres comodn con datos de tipo datetime y smalldatetime , as como con char , nchar, varchar , nvarchar y text . Cuando se usa like con valores datetime o smalldatetime , SQL Server convierte las fechas al formato estndar de datetime y luego a varchar . Puesto que el formato de visualizacin estndar no incluye segundos ni milisegundos, stos no pueden buscarse con like y un patrn de coincidencia. Utilice la funcin de conversin de tipo , convert , para buscar los segundos y milisegundos.
Page 128 of 280

Es conveniente usar like para buscar valores datetime o smalldatetime , dado que las entradas de estos tipos de datos pueden contener diversos componentes de fecha. Por ejemplo, si inserta el valor "9:20" en una columna llamada arrival_time , la clusula: where arrival_time = '9:20' no lo encontrara, ya que SQL Server convierte la entrada en "Jan 1, 1900 9:20AM". Sin embargo, la siguiente clusula s lo encontrara: where arrival_time like '%9:20%' Si utiliza like y el da del mes es inferior a 10, deber insertar dos espacios entre el mes y el da para hacer coincidir el valor datetime con su conversin a varchar . Igualmente, si la hora es menor que 10, la conversin colocar dos espacios entre el ao y la hora. La clusula like May 2% con un espacio entre "May" y "2" encontrar todas las fechas entre el 20 y el 29 de mayo, pero no el 2 de mayo. No es necesario insertar el espacio adicional con otras comparaciones de fecha, sino slo con like , ya que los valores de fecha y hora se convierten a varchar slo para la comparacin con like .

binary , varbinary e image


Cuando se introducen o buscan datos binary , varbinary o image , stos deben ir precedidos de "0x". Por ejemplo, para introducir "FF", teclee "0xFF". Si introduce cadenas ms largas que la longitud especificada de una columna binary o varbinary , la entrada se trunca sin previo aviso. Una longitud de 10 para una columna binary o varbinary significa 10 bytes, cada uno de los cuales almacena 2 dgitos hexadecimales. Al crear un valor predeterminado en una columna binary o varbinary , escrbalo precedido de "0x" . Consulte la seccin sobre tipos de datos en el Manual de Referencia de SQL Server para obtener informacin sobre los ceros finales en los valores hexadecimales.

money y smallmoney
Los valores monetarios introducidos con la notacin E se interpretan como float . Esto puede hacer que se rechace una entrada o se pierda precisin al almacenarla como un valor money o smallmoney . Los valores money y smallmoney pueden introducirse precedidos o no de un smbolo monetario, como el smbolo de dlar ($), el de yen () o el de libra esterlina (). Para introducir un valor negativo, coloque un signo menos tras el smbolo monetario. No incluya comas en la entrada. No es posible introducir valores money o smallmoney con comas, aunque el formato de impresin predeterminado de los datos money o smallmoney coloca una coma detrs de cada tres dgitos. Cuando se muestran valores money o smallmoney , se redondean al cntimo ms cercano. Todas las operaciones aritmticas excepto el mdulo estn disponibles con datos money .

float, real y double precision


Los tipos de datos numricos aproximados, float , real y double precision , se introducen como una mantisa seguida por un exponente opcional. La mantisa puede incluir un signo positivo o negativo y un punto decimal. El exponente, que comienza tras el carcter "e" o "E" , puede incluir un signo, pero no un punto decimal. Para evaluar los datos numricos aproximados, SQL Server multiplica la mantisa por 10 elevado al exponente dado. A continuacin se muestran algunos ejemplos de datos float , real y double precision : Tabla 8-1: Evaluacin de datos numricos Datos introducidos Mantisa Exponente Valor 10E2 15.3e1 -2.e5 10 15.3 -2 2 1 5 10 * 102 15.3 * 101 -2 * 105
Page 129 of 280

2.2e-1 +56E+2

2,2 56

-1 2

2.2 * 10-1 56 * 102

La precisin binaria de la columna determina el nmero mximo de dgitos binarios permitidos en la mantisa. Para las columnas float, puede especificar una precisin de hasta 48 dgitos, mientras que para las columnas real y double precision, la precisin depende de la mquina. Si un valor excede la precisin binaria de una columna, SQL Server coloca un indicador de error en la entrada.

decimal y numeric
Los tipos de datos numricos exacto s , dec , decimal y numeric , comienzan con un signo positivo o negativo opcional y pueden incluir un punto decimal. El valor de los datos numricos exactos depende de la precisin ( precision ) y escala (s cale ) decimales de la columna, que se definen mediante la siguiente sintaxis: datatype [( precision [, scale ])]

SQL Server trata cada combinacin de precisin y escala como un tipo de datos concreto. Por ejemplo, numeric (10,0) y numeric (5,0) son dos tipos de datos distintos. La precisin y la escala determinan los lmites de los valores que pueden almacenarse en una columna decimal o numeric :

La precisin especifica el nmero mximo de dgitos decimales que pueden almacenarse en la columna. Incluye todos los dgitos situados a la derecha o izquierda del punto decimal. Puede especificar una precisin de entre 1 y 38 dgitos o usar la precisin predeterminada de 18 dgitos. La escala especifica el nmero mximo de dgitos que pueden almacenarse a la derecha del punto decimal y debe ser menor o igual a la precisin. Puede especificar una escala de entre 0 y 38 dgitos o usar la escala predeterminada de 0 dgitos.

Si un valor excede la precisin o la escala de una columna, SQL Server coloca un indicador de error en la entrada. Estos son algunos ejemplos vlidos de datos dec y numeric : Tabla 8-2: Precisiones y escalas vlidas para datos numricos Datos introducidos Tipo de datos Precisin Escala Valor 12.345 -1234.567

numeric (5,3) dec (8,4)

5 8

3 4

12.345 -1234.567

Las siguientes entradas exceden la precisin o la escala de la columna y dan errores como resultados: Tabla 8-3: Precisiones y escalas invlidas para datos numricos Datos introducidos 1234.567 1234.567 Tipo de datos Precisin 3 6 Escala 3 1

numeric (3,3) decimal (6)

int , smallint y tinyint


Se pueden insertar valores numricos en las columnas int , smallint y tinyint con la notacin E descrita en la seccin anterior.

timestamp
No es posible insertar datos en una columna timestamp . Deber insertar un valor nulo explcito, tecleando "NULL" en la columna, o usar un valor nulo implcito, proporcionando una lista de columnas que se salte la columna timestamp . SQL Server actualiza el valor timestamp automticamente tras cada insercin o actualizacin. Consulte "Insercin de datos en columnas especficas" para obtener ms informacin. Adicin de datos nuevos Se puede utilizar el comando insert para aadir filas a la base de datos de dos formas: con la palabra clave values o con una instruccin select .
Page 130 of 280

La palabra clave values se utiliza para especificar valores en algunas o todas las columnas de una fila nueva. Este es un ejemplo simplificado de la sintaxis del comando insert usando la palabra clave values : insert table_name values ( constant1

constant2

, ...)

Se puede emplear una instruccin select dentro de una instruccin insert para obtener valores de una o varias tablas. Este es un ejemplo simplificado de la sintaxis del comando insert usando una instruccin select : insert select from where table_name column_list table_list search_conditions

Sintaxis de insert A continuacin se muestra la sintaxis completa del comando insert : insert [into] [ database .[ owner .]]{ table_name | view_name } [( column_list )] {values ( constant_expression [, constant_expression ]...) | select_statement } Note: Cuando se aaden valores text e image con insert , todos los datos se escriben en el diario de transacciones. El comando writetext permite aadir estos valores sin registrar los grandes bloques de datos que pueden conformar los valores text o image . Consulte "Insercin de datos en columnas especficas" y "Modificacin de datos text e image". Adicin de nuevas filas con values Esta instruccin insert aade una nueva fila a la tabla publishers y asigna un valor a cada columna de la fila: insert into publishers values ('1622', 'Jardin, Inc.', 'Camden', 'NJ') Observe que los valores de los datos se escriben en el mismo orden que los nombres de columna de la instruccin create table original, es decir, primero el nmero de ID, despus el nombre, la ciudad y, finalmente, el estado. Los datos de values se colocan entre parntesis y todos los datos de caracteres van entre comillas simples o dobles. Utilice una instruccin insert distinta para cada fila que aada. Insercin de datos en columnas especficas Es posible aadir datos a algunas columnas de una fila, pero no a todas, especificando estas columnas y los datos que les correspondan. Todas las columnas excluidas de la lista de columnas deben definirse para permitir valores nulos. Las columnas excluidas tambin aceptan valores predeterminados. Si se salta una columna con un valor predeterminado vinculado a ella, se emplea dicho valor. Esta forma del comando puede ser especialmente til para insertar todos los valores de una fila excepto los text o image, y despus utilizar writetext para aadir los valores ms largos sin que se almacenen en el diario de transacciones. Asimismo, se puede emplear esta forma del comando para saltar los datos de tipo timestamp . Para aadir datos slo en dos columnas, por ejemplo, pub_id y pub_name , utilice un comando como el siguiente: insert into publishers (pub_id, pub_name) values ('1756', 'The Health Center') El orden de enumeracin de los nombres de columna debe coincidir con el de los valores. El siguiente ejemplo produce los mismos resultados que el anterior: insert publishers (pub_name, pub_id) values('The Health Center', '1756') Ambas instrucciones insert sitan "1756" en la columna del nmero de identificacin y "The Health Center" en la del nombre del editor. Dado que la columna pub_id de publishers tiene un ndice nico, no es posible ejecutar las dos instrucciones insert . El segundo intento de insertar "1756" en la columna pub_id produce un mensaje de error.
Page 131 of 280

La siguiente instruccin select muestra la fila que se ha aadido a publishers : select * from publishers where pub_name = 'The Health pub_id pub_name ------- ----------------1756 The Health Center

Center' city state ------ ------NULL NULL

SQL Server introduce valores nulos en las columnas city y state porque no se ha indicado ningn valor para ellas en la instruccin insert y la tabla publisher permite valores nulos en estas columnas. Valores generados por SQL Server para columnas IDENTITY Cuando inserta una fila en una tabla con una columna IDENTITY, SQL Server genera automticamente el valor de la columna. No incluya el nombre de la columna IDENTITY en la lista de columnas, ni su valor en la lista de valores. Esta instruccin insert aade una nueva fila a la tabla sales_daily . Observe que la lista de columnas no incluye la columna IDENTITY, row_id : insert sales_daily (stor_id) values ("7896") La siguiente instruccin muestra la fila aadida a sales_daily . SQL Server ha generado automticamente el siguiente valor secuencial, 2, en row_id : select * from sales_daily where stor_id = "7896" row_id stor_id ------ ------2 7896 Valores nulos y predeterminados, columnas IDENTITY y errores Cuando especifica valores slo para algunas columnas de la fila, puede darse una de estas cuatro situaciones en las columnas sin valores:

Se introduce un valor predeterminado, si existe, en la columna o en el tipo de datos definido por el usuario. Consulte el Captulo 12, "Definicin de valores predeterminados y reglas para datos", o la entrada create default del Manual de Referencia de SQL Server para obtener informacin detallada. Se introduce NULL si se especific el valor nulo al crear la tabla y no existe ningn valor predeterminado para la columna o el tipo de datos. Consulte tambin la entrada create table del Manual de Referencia de SQL Server . Se introduce un valor nico y secuencial si la columna tiene la propiedad IDENTITY. Aparece un mensaje de error y la fila no se aade si no se ha especificado el valor nulo y no existe ningn valor predeterminado.

La siguiente tabla muestra lo que aparece bajo estas circunstancias: Tabla 8-4: Columnas sin valores Predeterminada? No nula S No Mensaje de error Nula NULL IDENTITY Siguiente valor secuencial El valor predeterminado El valor predeterminado Siguiente valor secuencial

Se puede usar el procedimiento del sistema sp_help para obtener un informe sobre una tabla o valor predeterminado en particular, o sobre cualquier objeto enumerado en la tabla del sistema sysobjects . Para ver la definicin de un valor predeterminado, utilice el procedimiento del sistema sp_helptext . Insercin explcita de datos en una columna IDENTITY

Page 132 of 280

En ocasiones, desear introducir un valor especfico en una columna IDENTITY, en lugar de aceptar el valor generado por el servidor. Por ejemplo, puede que quiera asignar el valor 101, en lugar del 1, a la columna IDENTITY de la primera fila insertada en la tabla, o insertar de nuevo una fila eliminada por error. Slo el propietario de la tabla, el propietario de la base de datos o el administrador del sistema pueden insertar un valor de forma explcita en una columna IDENTITY. Antes de insertar los datos, el usuario debe activar la opcin identity_insert para la tabla. Slo es posible activar identity_insert para una tabla de la base de datos cada vez. Este ejemplo especifica un valor "semilla" de 101 para la columna IDENTITY: set identity_insert sales_daily on insert into sales_daily (syb_identity, stor_id) values (101, '13-J-9') Observe que la instruccin insert enumera todas las columnas, incluida IDENTITY, para las que se ha especificado un valor. Cuando la opcin identity_insert est activada, todas las instrucciones insert ejecutadas para la tabla deben incluir una lista explcita de columnas. La lista de valores deber incluir un valor para la columna IDENTITY, puesto que esta columna no admite valores nulos. Note: SQL Server no impone la exclusividad del valor insertado. Se puede especificar cualquier nmero entero positivo que est dentro del margen admitido por la precisin declarada de la columna. Para asegurarse de que slo se aceptan valores de columna nicos, deber crear un ndice nico en la columna IDENTITY antes de insertar las filas. Restriccin de los datos de columna: reglas Se puede crear una regla y vincularla a una columna o a un tipo de datos definido por el usuario. Las reglas rigen los tipos de datos que pueden aadirse. Un ejemplo de ello es la columna pub_id de la tabla publishers . Una regla llamada pub_idrule , que especifica los nmeros de identificacin de editores vlidos, est vinculada a la columna. Las IDs vlidas son "1389", "0736", "0877", "1622" y "1756", o cualquier nmero de cuatro dgitos cuyos primeros dos dgitos sean "99". Si trata de introducir cualquier otro nmero, obtendr un mensaje de error. Si recibe este tipo de mensaje de error, ser conveniente examinar la definicin de la regla. Utilice el procedimiento del sistema sp_helptext : sp_helptext pub_idrule --------1 (1 row affected) text --------------------------------------------------create rule pub_idrule as @pub_id in ("1389", "0736", "0877", "1622", "1756") or @pub_id like "99[0-9][0-9]" (1 row affected) Para obtener informacin general sobre una regla especfica, utilice sp_help . Tambin puede emplear sp_help con un nombre de tabla como parmetro para averiguar si alguna de las columnas definidas en la tabla tiene una regla. En el Captulo 12, "Definicin de valores predeterminados y reglas para datos", se describen las reglas con mayor detalle. Adicin de filas nuevas con select Para insertar valores en una tabla procedentes de una o ms tablas diferentes, incluya una clusula select en la instruccin insert . La clusula select permite insertar valores en algunas o todas las columnas de una fila. La insercin de valores en algunas columnas solamente puede ser til si se desea tomar valores de una tabla existente. Despus, puede usar update para aadir los valores de las dems columnas.

Page 133 of 280

Antes de insertar valores en algunas columnas de una tabla, asegrese de que exista un valor predeterminado o se haya especificado el valor nulo para las columnas donde no van a insertarse valores. De lo contrario, recibir un mensaje de error. Cuando se insertan filas de una tabla en otra, ambas tablas deben tener estructuras compatibles, es decir, las columnas coincidentes deben tener el mismo tipo de datos, o bien, tipos de datos que SQL Server convierta automticamente. Note: No es posible insertar datos de una tabla que permite valores nulos en una que no los permite, si alguno de los datos insertados es nulo. Si las columnas estn en el mismo orden en sus instrucciones create table respectivas, no es necesario especificar los nombres de las columnas en ninguna de las tablas. Suponga que existe una tabla newauthors que contiene algunas filas de informacin sobre autores en el mismo formato que authors . Para aadir a authors todas las filas de newauthors : insert authors select * from newauthors Para insertar filas en una tabla basada en los datos de otra tabla, no es necesario que las columnas de ambas estn enumeradas en el mismo orden en sus respectivas instrucciones create table . Puede usar las instrucciones insert o select para ordenar las columnas de modo que coincidan. Por ejemplo, suponga que la instruccin create table de la tabla authors contiene las columnas au_id , au_fname , au_lname y address en este orden, mientras que newauthors contiene au_id , address , au_lname y au_fname . Deber hacer que ambas secuencias coincidan en la instruccin insert , lo cual puede hacerse de estas dos maneras: insert authors (au_id, address, au_lname, au_fname) select * from newauthors insert authors select au_id, au_fname, au_lname, address from newauthors Si la secuencia de columnas de las dos tablas no coincide, SQL Server no puede completar la operacin insert o la completa de forma incorrecta, colocando datos en columnas equivocadas. Por ejemplo, podran aparecer datos de direcciones en la columna au_lname de nombres. Columnas calculadas Se puede usar columnas calculadas en una instruccin select dentro de una instruccin insert . Por ejemplo, suponga que una tabla llamada tmp contiene algunas filas nuevas para la tabla titles con algunos datos obsoletos, y que las cifras de price deben multiplicarse por dos. Una instruccin que permite incrementar los precios e insertar las filas tmp en titles tendra el siguiente aspecto: insert titles select title_id, title, type, pub_id, price*2, advance, total_sales, notes, pubdate, contract from tmp Al realizar clculos en una columna, no es posible usar la sintaxis select * . Cada columna debe especificarse por separado en la lista de seleccin. Insercin de datos en algunas columnas Se puede usar la instruccin select para aadir datos slo a algunas columnas de una fila, exactamente igual que con la clusula values . Simplemente, especifique las columnas a las que desea aadir los datos en la clusula insert . Por ejemplo, existen algunos autores en la tabla authors que no tienen ningn ttulo y que, por consiguiente, no tienen entradas en la tabla titleauthor . Para extraer sus nmeros de au_id de la tabla authors e insertarlos en la tabla titleauthor como marcadores de lugar, puede probar con esta instruccin: insert titleauthor (au_id) select au_id from authors where au_id not in (select au_id from titleauthor)
Page 134 of 280

Sin embargo, esta instruccin no es legal, ya que se requiere un valor para la columna title_id . No se permiten valores nulos y tampoco se ha especificado un valor predeterminado. Puede introducir el valor ficticio "xx1111 " para titles_id empleando una constante, como se indica a continuacin: insert titleauthor (au_id, title_id) select au_id, "xx1111" from authors where au_id not in (select au_id from titleauthor) La tabla titleauthor contiene ahora cuatro filas nuevas con entradas para la columna au_id , entradas ficticias para title_id y valores nulos para las otras dos columnas. Insercin de datos de la misma tabla Se pueden insertar datos en una tabla basados en otros datos de la misma tabla. En esencia, esto significa copiar una fila completa o parte de ella. Por ejemplo, se puede insertar una nueva fila en la tabla publishers basada en los valores de una fila existente de la misma tabla. Asegrese de cumplir la regla de la columna pub_id . As es como se hace: insert publishers select "9999", "test", city, state from publishers where pub_name = "New Age Books" (1 row affected) select * from publishers pub_id ------0736 0877 1389 9999 pub_name --------------------New Age Books Binnet & Hardley Algodata Infosystems test city ------Boston Washington Berkeley Boston state -----MA DC CA MA

(4 rows affected) El ejemplo inserta las dos constantes ("9999" y "test") y los valores de las columnas city y state en la fila que se ajusta a la consulta. Modificacin de datos existentes Se puede utilizar el comando update para modificar filas independientes, grupos de filas o todas las filas de una tabla. El comando update va seguido del nombre de la tabla o vista. Como ocurre con todas las instrucciones de modificacin de datos, slo es posible cambiar los datos de una tabla cada vez. El comando update especifica la fila o filas que se desean modificar y los datos nuevos. Estos ltimos pueden ser una constante o expresin indicadas por el usuario o datos tomados de otras tablas. Si una instruccin update viola una restriccin de integridad, la actualizacin no se lleva a cabo y aparece un mensaje de error. La actualizacin se cancela, por ejemplo, si afecta a la columna IDENTITY de la tabla, o si alguno de los valores aadidos no es del tipo de datos correcto o viola una regla definida para una de las columnas o tipos de datos implicados. SQL Server no impide ejecutar un comando update que actualice la misma fila ms de una vez. Sin embargo, debido a la forma en que se procesa update , las actualizaciones realizadas con una misma instruccin no se acumulan. Es decir, si una instruccin update modifica dos veces la misma fila, la segunda actualizacin no se basa en los valores resultantes de la primera, sino en los originales. Los resultados son imprevisibles, puesto que dependen del orden de procesamiento. Consulte el Captulo 9, "Vistas: limitacin del acceso a datos", para obtener informacin sobre las restricciones de la actualizacin de vistas. Note: El comando update se registra. Si est modificando grandes bloques de datos text o image , ser conveniente emplear el comando writetext , que no se registra. Adems, existe un lmite aproximado de 125K por cada instruccin update . Consulte la explicacin de writetext en "Modificacin de datos text e image".
Page 135 of 280

Sintaxis de update Esta es una versin simplificada de la sintaxis de update para actualizar filas especificadas con una expresin: update table_name set column_name = expression where search_conditions Por ejemplo, si Reginald Blotchet-Halls decide cambiar su nombre por el de Goodbody Health para potenciar su proceso de visualizacin, la manera de modificar su fila en la tabla authors es la siguiente: update authors set au_lname = "Health", au_fname = "Goodbody" where au_lname = "Blotchet-Halls" Esta instruccin de sintaxis simplificada actualiza una tabla basada en datos de otra tabla: update table_name set column_name = expression from table_name where search_conditions El siguiente ejemplo actualiza la columna total_sales de la tabla titles para reflejar las ventas ms recientes registradas en la tabla salesdetail : update titles set total_sales = total_sales + qty from titles, sales, salesdetail where titles.title_id = salesdetail.title_id and salesdetail.stor_id = sales.stor_id and sales.date in (select max(sales.date) from sales) En el ejemplo anterior se supone que slo se registra un conjunto de ventas para un ttulo y una fecha determinados, y que las actualizaciones estn al da. La sintaxis completa de update es: update [[ database .] owner .]{ table_name | view_name } set [[[ database .] owner .]{ table_name . | view_name. }] column_name1 = { expression1 | null | ( select_statement )} [, column_name2 = { expression2 | null | ( select_statement )}]... [from [[ database .] owner .]{ table_name | view_name } [, [[ database .] owner .]{ table_name | view_name }]]... [where search_conditions ] Uso de la clusula set con update La clusula set especifica las columnas y los valores modificados. La clusula where determina qu fila o filas se van a actualizar. Observe que, si no incluye una clusula where , las columnas especificadas de todas las filas se actualizarn con los valores indicados en la clusula set . Note: Antes de realizar los ejemplos de esta seccin, cercirese de que sabe cmo volver a instalar la base de datos pubs2 . Por ejemplo, si todas las editoriales de la tabla publishers trasladan sus sedes principales a Atlanta (Georgia), la tabla se actualiza de la siguiente manera: update publishers set city = "Atlanta", state = "GA" Anlogamente, puede sustituir los nombres de todos los editores por NULL con esta instruccin: update publishers set pub_name = null
Page 136 of 280

Tambin es posible utilizar valores de columnas calculadas en una actualizacin. Para multiplicar por dos todos los precios de la tabla titles , use esta instruccin: update titles set price = price * 2 Puesto que no hay clusula where , el cambio de precios se aplica a todas las filas de la tabla. Uso de la clusula where con update La clusula where especifica qu filas deben actualizarse. Por ejemplo, en el caso poco probable de que se cambiara el nombre de California del norte por el de Pacifica (abreviado como PC) y las personas de Oakland votasen cambiar el nombre de su ciudad por uno ms interesante, como Big Bad Bay City, esta sera la manera de actualizar la tabla authors para todos los anteriores residentes de Oakland, cuyas direcciones ya no estaran al da: update authors set state = "PC", city = "Big Bad Bay City" where state = "CA" and city = "Oakland" Sera necesaria otra instruccin para cambiar el nombre del estado de los residentes de otras ciudades del norte de California. Uso de Clusula from con update Utilice la clusula from para transferir datos de una o ms tablas a la tabla que esta actualizando. Por ejemplo, anteriormente en este captulo se di un ejemplo que insertaba nuevas filas para autores sin ttulos en la tabla titleauthor , rellenando la columna au_id y colocando valores ficticios o nulos en las dems. Si uno de estos autores, Dirk Stringer, escribe un libro, The Psychology of Computer Cooking , se asigna un nmero de identificacin de ttulo a su libro en la tabla titles . Se puede modificar su fila en la tabla titleauthor aadiendo un nmero de identificacin de ttulo para l: update titleauthor set title_id = titles.title_id from titleauthor, titles, authors where titles.title = "The Psychology of Computer Cooking" and authors.au_id = titleauthor.au_id and au_lname = "Stringer" Observe que una instruccin update sin la combinacin au_id cambia todos los title_ids de la tabla titleauthor y les asigna el mismo nmero de identificacin que a The Psychology of Computer Cooking . Si dos tablas son idnticas en estructura, pero una tiene campos NULL y algunos valores nulos y la otra tiene campos NOT NULL, es imposible insertar los datos de la tabla NULL en la tabla NOT NULL con una instruccin select . En otras palabras, un campo que no permite valores nulos no puede actualizarse seleccionando elementos de un campo que s los permite, si alguno de los datos es nulo. Modificacin de datos text e image El comando writetext se usa para modificar valores text o image cuando no se desea almacenar los largos valores de texto en el diario de transacciones de la base de datos. Los comandos update , que tambin pueden emplearse para columnas text o image , siempre se registran. En el modo predeterminado, los comandos writetext no se registran. Note: Para emplear writetext en su estado predeterminado y no registrado, el administrador del sistema debe usar sp_dboption para activar select into/bulkcopy . Esto permite la insercin de datos no registrados. Despus de usar writetext , es necesario ejecutar dump database . Un volcado de transacciones realizado tras la introduccin de cambios no registrados en la base de datos no puede utilizarse en una operacin de load transaction . El comando writetext escribe sobre todos los datos de la columna a la que afecta. Para que writetext funcione correctamente, la columna debe contener un puntero de texto vlido. Existen dos formas de crear un puntero de texto:

Insertar datos reales en la columna text o image mediante insert . Actualizar la columna con datos o un valor nulo mediante update .

Page 137 of 280

Puesto que una columna text "inicializada" usa 2K de espacio de almacenamiento, aunque slo contenga dos palabras, SQL Server ahorra espacio al no inicializar las columnas text cuando se colocan valores nulos explcitos o implcitos en ellas con insert . Este comando no inicializa una columna text : insert blurbs values ("172-32-1176", NULL) Despus de una instruccin insert como la anterior, se puede usar esta instruccin update para inicializar la columna text : update blurbs set copy=NULL where au_id="172-32-1176" Una vez inicializado el puntero, se puede emplear writetext . El siguiente ejemplo de writetext aade un texto a una fila existente de la tabla blurbs : declare @val varbinary(16) select @val = textptr(copy) from blurbs where au_id="172-32-1176" writetext blurbs.copy @val "This book is a must for true data junkies." Este ejemplo coloca el puntero de texto en la variable local @ val. Despus, writetext coloca la cadena de texto nueva en la fila a la que apunta @ val . Eliminacin de datos Al igual que insert y update , delete puede utilizarse para operaciones tanto de una sola fila como de mltiples filas, pero es ms adecuada para lo segundo. Como ocurre con las dems instrucciones de modificacin de datos, es posible eliminar filas basadas en los datos de otras tablas. Por ejemplo, si decide eliminar una fila de publishers (la fila aadida para Jardin, Inc.), escriba: delete publishers where pub_name = "Jardin, Inc." Sintaxis de delete Esta es una versin simplificada de la sintaxis de delete : delete where table_name column_name

expression

Esta es la instruccin con la sintaxis completa, que muestra cmo se pueden eliminar filas segn expresiones especificadas o segn los datos de otras tablas: delete [from] [[ database .] owner .]{ table_name | view_name } [from [[ database .] owner .]{ table_name | view_name [, [[ database .] owner .]{ table_name | view_name }]...] [where search_conditions ]

La clusula opcional from situada justo detrs de la palabra clave delete se incluye por motivos de compatibilidad con otras versiones de SQL. La clusula from de la segunda lnea es una mejora de SQL Server que permite realizar eliminaciones basndose en datos de otras tablas. Uso de la clusula where con delete La clusula where especifica qu filas deben eliminarse. Cuando no se indica ninguna clusula where en la instruccin delete , se quitan todas las filas de la tabla.
Page 138 of 280

Uso de la clusula from con delete La clusula from en la segunda posicin de una instruccin delete es una funcin especial de Transact-SQL que permite seleccionar datos de una o varias tablas y eliminar los datos correspondientes de la tabla indicada en primer lugar. Las filas seleccionadas en la clusula from especifican las condiciones de la operacin delete . Suponga que un complejo acuerdo corporativo tiene como resultado la adquisicin de todos los autores y sus libros de Big Bad Bay City, anteriormente Oakland, por otro editor. Es necesario eliminar todos esos libros de la tabla titles inmediatamente y, sin embargo, no se conocen los ttulos ni los nmeros de identificacin correspondientes a esos autores. La nica informacin que se dispone son sus nombres y direcciones. Se pueden borrar las filas de titles buscando los nmeros de identificacin de los autores cuyas filas tienen Big Bad Bay City como ciudad en la tabla authors y usando estos nmeros para buscar los nmeros de identificacin de los libros en la tabla titleauthor . En otras palabras, se requiere una combinacin de tres componentes para buscar las filas que se desea eliminar de la tabla titles . Las tres tablas estn incluidas en la clusula from de la instruccin delete . Sin embargo, slo se eliminan las filas de la tabla titles que cumplen con las condiciones de la clusula where . Para eliminar las filas relevantes de otras tablas que no sean titles , habra que realizar operaciones independientes. Esta es la instruccin necesaria: delete titles from authors, titles, titleauthor where titles.title_id = titleauthor.title_id and authors.au_id = titleauthor.au_id and city = "Big Bad Bay City" El disparador deltitle de la base de datos pubs2 evita que la eliminacin se lleve a cabo realmente, puesto que no permite borrar los ttulos con ventas registradas en la tabla sales Eliminacin de todas las filas de una tabla Utilice truncate table como mtodo rpido para eliminar todas las filas de una tabla. Casi siempre es ms rpido que una instruccin delete sin condiciones, porque delete registra todos los cambios, mientras que truncate table slo registra la desasignacin de pginas de datos completas. truncate table libera inmediatamente todo el espacio ocupado por los datos e ndices de la tabla. El espacio liberado lo puede usar entonces cualquier objeto. Las pginas de distribucin de todos los ndices tambin quedan desasignadas. No olvide ejecutar update statistics tras aadir nuevas filas a la tabla. Al igual que con delete , una tabla vaciada con el comando truncate table permanece en la base de datos, junto con sus ndices y otros objetos asociados, a no ser que se introduzca un comando drop table . Sintaxis de truncate table La sintaxis de truncate table es: truncate table [[ database .] owner .] table_name

Por ejemplo, para eliminar todos los datos de la tabla sales , escriba: truncate table sales El permiso para usar el comando truncate table , al igual que drop table , corresponde predeterminadamente al propietario de la tabla, y no es transferible. Un comando truncate table no se ve afectado por un disparador delete . Consulte el Captulo 15, "Disparadores: imposicin de la integridad de referencia", para obtener detalles sobre los disparadores. Chapter 9

Page 139 of 280

Vistas: limitacin del acceso a datos


Las vistas se pueden utilizar para centrar, simplificar y personalizar la percepcin de cada usuario de la base de datos. Las vistas tambin proporcionan un mecanismo de seguridad al permitir que los usuarios slo tengan acceso a los datos que necesitan. En este captulo se describen stas y otras ventajas. En este captulo se trata lo siguiente:

Una introduccin general al uso de vistas Creacin de vistas Recuperacin de datos mediante vistas Actualizacin de datos mediante vistas Generacin de informacin sobre vistas Definicin de vista Creacin de vistas Recuperacin de datos mediante vistas Modificacin de datos mediante vistas Omisin de vistas Uso de vistas como mecanismos de seguridad Obtencin de informacin sobre vistas

Definicin de vista Una vista es una forma alternativa de ver los datos de una o ms tablas. Se puede pensar en una vista como un marco a travs del cual pueden verse los datos en los que est interesado. Esta es la razn por la que se habla de ver los datos o cambiar los datos "mediante" una vista. Una vista se deriva de una o ms tablas reales cuyos datos estn almacenados fsicamente en la base de datos. Las tablas que originan la vista se denominan tablas base o tablas subyacentes. Una vista tambin se puede derivar de otra vista. La definicin de una vista, en trminos de las tablas base de las que se deriva, se almacena en la base de datos. No se asocia ninguna copia de datos distinta a esta definicin almacenada. Los datos que se ven se almacenan en las tablas subyacentes. Una vista tiene exactamente el mismo aspecto que cualquier otra tabla de base de datos. Puede mostrarse y usarse prcticamente de la misma manera que cualquier otra tabla. Transact-SQL fue modificado para que no haya ninguna restriccin en las consultas mediante vistas, y menos restricciones de las normales en la modificacin de las vistas. Las excepciones se explican posteriormente en este captulo. Cuando se modifican los datos que se ven mediante una vista, en realidad se estn cambiando los datos de las tablas subyacentes. A su vez, los cambios en los datos de las tablas subyacentes se reflejan automticamente en las vistas que se derivan de ellas. Ventajas de las vistas Los ejemplos de este captulo demuestran que las vistas pueden utilizarse para centrar, simplificar y personalizar la percepcin que cada usuario tiene de la base de datos. Las vistas tambin proporcionan una medida de seguridad de fcil manejo. Adems, pueden ser tiles cuando los cambios se realizan en la estructura de la base de datos y los usuarios prefieren trabajar con la base de datos en la forma en la que acostumbran. Enfoque Las vistas permiten a los usuarios centrarse en los datos concretos que les interesa y en las tareas especficas de las que son responsables. Los datos que no son de inters para un usuario concreto ni para una tarea especfica pueden dejarse fuera de la vista. Simplificacin de la manipulacin de datos

Page 140 of 280

Las vistas no slo simplifican la percepcin que los usuarios tienen de los datos, sino tambin su forma de manipularlos. Las combinaciones, proyecciones y selecciones usadas con frecuencia pueden definirse como vistas para evitar que los usuarios tengan que especificar todas las condiciones y calificaciones cada vez que realicen una operacin adicional con dichos datos. Personalizacin Gracias a las vistas, distintos usuarios pueden ver los mismos datos de formas diferentes, incluso si utilizan los mismos datos al mismo tiempo. Esta ventaja es especialmente importante cuando usuarios con diferentes intereses y niveles de especializacin comparten la misma base de datos. Seguridad Mediante una vista, los usuarios pueden consultar y modificar slo los datos que pueden ver. El resto de la base de datos no es visible ni accesible. Con los comandos grant y revoke , el acceso de cada usuario a la base de datos puede limitarse a objetos de base de datos especificados, incluidas las vistas. Si la vista y todas las tablas y vistas de las que deriva son propiedad del mismo usuario, ste podr conceder permiso a otros usuarios para utilizar la vista y, al mismo tiempo, denegar el permiso para usar sus tablas subyacentes y vistas. Este es un mecanismo de seguridad sencillo pero eficaz. Consulte la Gua de Administracin de Seguridad para obtener informacin detallada sobre los comandos grant y revoke . Mediante la definicin de vistas diferentes y la concesin selectiva de permisos para las mismas, es posible limitar un usuario o cualquier combinacin de usuarios a distintos subconjuntos de datos. A continuacin se ilustra el uso de las vistas con fines de seguridad:

Puede limitarse el acceso a un subconjunto de filas de una tabla base, es decir, un subconjunto dependiente del valor. Por ejemplo, se puede definir una vista que contenga slo las filas de libros de negocios y psicologa, a fin de mantener la informacin sobre otros tipos de libros oculta a ciertos usuarios. Puede limitarse el acceso a un subconjunto de columnas de una tabla base, es decir, un subconjunto independiente del valor. Por ejemplo, se puede definir una vista que contenga todas las filas de la tabla titles , pero que omita las columnas royalty y advance , ya que esta informacin es confidencial. Puede limitarse el acceso a un subconjunto de fila-y-columna de una tabla base. Puede limitarse el acceso a las filas que califican una combinacin de ms de una tabla base. Por ejemplo, se puede definir una vista que combine las tablas titles , authors y titleauthor a fin de ver los nombres de los autores y los libros que han escrito. Esta vista ocultara los datos personales sobre los autores y la informacin financiera sobre los libros. Puede limitarse el acceso a un resumen estadstico de datos de la tabla base. Por ejemplo, mediante la vista category_price , el usuario slo puede tener acceso al precio promedio de cada tipo de libro. Puede limitarse el acceso a un subconjunto de otra vista o una combinacin de vistas y tablas base. Por ejemplo, mediante la vista hiprice_computer , el usuario puede tener acceso al ttulo y el precio de los libros sobre informtica que cumplan las calificaciones de la definicin de vista de hiprice .

A fin de crear una vista, el usuario debe recibir el permiso create view del propietario de la base de datos y tener los permisos apropiados sobre las tablas o vistas a las que se haga referencia en la definicin de vista. Si una vista hace referencia a objetos de base de datos diferentes, los usuarios de la vista deben ser usuarios vlidos o invitados de cada una de las bases de datos. Como propietario de un objeto a partir del cual otros usuarios han creado vistas, tenga en cuenta quin puede ver qu datos mediante qu vistas. Considere esta situacin: el propietario de la base de datos ha concedido el permiso create view a " harold " y un usuario llamado " maude " ha concedido a " harold " el permiso para usar select desde una tabla propiedad de " maude " . Dados estos permisos, " harold " puede crear una vista que seleccione todas las columnas y filas de la tabla de " maude ". Si "maude" despus revoca el permiso de " harold " para usar select desde su tabla, " harold " todava podr ver los datos de " maude " a travs de la vista que l ha creado. Independencia lgica de datos Las vistas ayudan a proteger a los usuarios de los cambios realizados en la estructura de las tablas reales si tales cambios son necesarios. Por ejemplo, supongamos que la base de datos se reestructura usando select into para dividir la tabla titles en estas dos nuevas tablas base y omitiendo titles :

Page 141 of 280

titletext (title_id, title, type, notes) titlenumbers (title_id, pub_id, price, advance, royalty, total_sales, pub_date) Observe que la antigua tabla titles puede "regenerarse" combinando las columnas title_id de las dos tablas nuevas. Para proteger la estructura cambiada de la base de datos de los usuarios, puede crear una vista que sea la combinacin de las dos tablas nuevas. Incluso le puede asignar el nombre titles . Cualquier consulta o procedimiento almacenado que antes haca referencia a la tabla base titles ahora har referencia a la vista titles . En lo que respecta a los usuarios, las operaciones select siguen funcionando exactamente igual que antes. Los usuarios que slo realizan la recuperacin a partir de la vista nueva ni siquiera necesitan saber que se ha producido una reestructuracin. Desafortunadamente, las vistas slo proporcionan independencia lgica parcial. Algunas instrucciones de modificacin de datos no se permiten en la nueva titles debido a determinadas restricciones. Ejemplos de vistas El primer ejemplo es una vista derivada de la tabla titles . Supongamos que slo est interesado en los libros con un precio superior a $15 y para los que se ha pagado un anticipo de ms de $5000. Esta sencilla instruccin select hallara las filas que cumplen las condiciones: select * from titles where price > $15 and advance > $5000 Ahora supongamos que tiene que realizar muchas operaciones de recuperacin y actualizacin en este conjunto de datos. Lgicamente, podra combinar las condiciones mostradas en la consulta anterior con cualquier comando que ejecute. Sin embargo, para mayor comodidad, puede crear una vista en la que slo estn visibles los registros de inters: create view hiprice as select * from titles where price > $15 and advance > $5000 Cuando recibe este comando, SQL Server no ejecuta la instruccin select que sigue a la palabra clave as . En su lugar, almacena la instruccin select , que es de hecho la definicin de la vista hiprice , en la tabla del sistema syscomments . Tambin se realizan entradas en sysobjects y syscolumns para cada columna incluida en la vista. Ahora, cuando se visualiza hiprice o se trabaja con ella, SQL Server combina la instruccin con la definicin almacenada de hiprice . Por ejemplo, puede cambiar todos los precios de hiprice del mismo modo que cambiara cualquier otra tabla: update hiprice set price = price * 2 SQL Server halla la definicin de vista en las tablas del sistema y convierte este comando de actualizacin en la instruccin: update titles set price = price * 2 where price > $15 and advance > $5000 En otras palabras, SQL Server sabe, a partir de la definicin de la vista, que los datos que hay que actualizar estn en titles . Tambin sabe que slo debe aumentar los precios de las filas que cumplen las condiciones de las columnas price y advance , proporcionadas en la definicin de vista, y las de la instruccin de actualizacin. Al emitir la primera instruccin de actualizacin, es decir, la de hiprice , es posible ver su efecto en la vista o en la tabla titles . A la inversa, si hubiera creado la vista y luego hubiera ejecutado la segunda instruccin de actualizacin, que opera directamente en la tabla base, los precios cambiados tambin se hubieran visualizado mediante la vista. La actualizacin de una tabla subyacente de una vista de modo que las diferentes filas califiquen a la vista afectar a la vista. Por ejemplo, suponga que el precio del libro You Can Combat Computer Stress aumenta a $25,95. Dado que ahora este libro cumple las condiciones de calificacin de la instruccin de definicin de la vista, se considera parte de la vista.
Page 142 of 280

Sin embargo, si altera la estructura de la tabla subyacente de una vista mediante la adicin de columnas, las columnas nuevas no aparecern en una vista definida con una clusula select * a menos que la vista se omita y vuelva a definirse. Esto se debe a que la abreviatura mediante asterisco se interpreta y ampla cuando la vista se crea por primera vez. Creacin de vistas Los nombres de vistas deben ser nicos para cada usuario entre las tablas y vistas ya existentes. Si defini set quoted_identifier on , puede utilizar un identificador delimitado para la vista. En caso contrario, el nombre de la vista debe ajustarse a las reglas para identificadores proporcionadas en el Chapter 1. Es posible crear vistas en otras vistas y procedimientos que hagan referencia a vistas. Es posible definir claves primarias, externas y comunes en las vistas. No es posible asociar reglas, valores predeterminados ni disparadores a las vistas, ni tampoco crear ndices en ellas. No es posible crear vistas temporales, ni tampoco generarse vistas en tablas temporales. Sintaxis de create view A continuacin se muestra la sintaxis completa para la creacin de una vista: create view [[ database .] owner .] view_name [( column_name [, column_name ]...)] as select [distinct] select_statement [with check option] Como se mostraba en el ejemplo de la seccin anterior, no es necesario especificar ningn nombre de columna en la clusula create de una instruccin de definicin de vista. SQL Server da a las columnas de la vista los mismos nombres y mismos tipos de datos que las columnas a las que se hace referencia en la lista de seleccin de la instruccin select . La lista de seleccin puede ser " * ", como en el ejemplo, o una lista total o parcial de los nombres de columna de las tablas base. Se pueden crear vistas que no contengan filas duplicadas. Utilice la palabra clave distinct de la instruccin select para garantizar que cada fila de la vista sea nica. Las vistas distinct no pueden actualizarse. Siempre es vlido especificar nombres de columna. Sin embargo, si se cumplen alguna de las siguientes condiciones, los nombres de columna deben especificarse en la clusula create para todas las columnas de la vista:

Si cualquiera de las columnas de la vista se deriva de una expresin aritmtica, un agregado, una funcin incorporada o una constante. En caso contrario, dos o ms columnas de la vista tendran el mismo nombre. Esto suele ocurrir porque la definicin de la vista incluye una combinacin, y las columnas objeto de la combinacin tienen el mismo nombre. Si quiere asignar a una columna de la vista un nombre diferente del de la columna de la que se deriva. Tambin puede cambiar el nombre de las columnas en la instruccin select . Se cambie o no el nombre de una columna de vista, sta hereda el tipo de datos de la columna de la que se deriva.

A continuacin se muestra una instruccin de definicin de vista que cambia el nombre de una columna de la vista de su nombre en la tabla subyacente: create view pub_view (Publisher, city, state) as select pub_name, city, state from publishers A continuacin se muestra un mtodo alternativo de creacin de la misma vista, pero cambiando el nombre de las columnas en la instruccin select : create view pub_view2 as select Publisher = pub_name, city, state from publishers Los ejemplos de instrucciones de definicin de vista proporcionados en una seccin posterior muestran el resto de las reglas para la inclusin de nombres de columnas en la clusula create . En la siguiente seccin se explica la instruccin select , el uso de la palabra clave distinct y la clusula with check option de las definiciones de vista. El comando drop view se explica despus.
Page 143 of 280

Uso de la instruccin select con create view La instruccin select de la instruccin create view define la vista. Es necesario tener el permiso select para seleccionar cualquier objeto referenciado en la instruccin select de una vista que se est creando. Una vista no tiene que ser necesariamente un simple subconjunto de filas y columnas de una tabla concreta, como en el ejemplo. Es posible crear una vista a partir de ms de una tabla y otras vistas, con una instruccin select de cualquier grado de complejidad. Existen ciertas restricciones sobre la instruccin select de una definicin de vista:

No se pueden incluir clusulas order by ni compute . No se puede incluir la palabra clave into . No se puede hacer referencia a una tabla temporal.

Definicin de vista con proyeccin Para crear una vista con todas las filas de la tabla titles , pero slo con un subconjunto de sus columnas, escriba la instruccin: create view titles_view as select title, type, price, pubdate from titles Observe que no se incluye ningn nombre de columna en la clusula create view . La vista titles_view heredar los nombres de columna que aparecen en la lista de seleccin. Definicin de vista con una columna calculada A continuacin se muestra una instruccin de definicin de vista que crea una vista con una columna calculada generada a partir de las columnas price , royalty y total_sales : create view accounts (title, advance, amt_due) as select titles.title_id, advance, (price * royalty /100 ) * total_sales from titles, roysched where price > $15 and advance > $5000 and titles.title_id = roysched.title_id and total_sales between lorange and hirange En este ejemplo, es necesario incluir una lista de columnas en la clusula create , ya que no hay ningn nombre que pueda heredar la columna calculada multiplicando price , royalty y total_sales . A la columna calculada se le da el nombre amt_due . Esta columna debe aparecer en la misma posicin en la clusula create que la de la expresin a partir de la cual se calcula en la clusula select . Definicin de vista con una funcin agregada o incorporada Una definicin de vista que incluya una funcin agregada o incorporada debe incluir nombres de columna en la clusula create . Por ejemplo: create view categories (category, average_price) as select type, avg(price) from titles group by type Si crea un vista por razones de seguridad, debe tener cuidado cuando use las funciones agregadas y la clusula group by . La extensin Transact-SQL que no limita las columnas que pueden incluirse en la instruccin select con group by tambin puede hacer que la vista devuelva ms informacin de la necesaria. Por ejemplo: create view categories (category, average_price) as select type, avg(price) from titles where type = "business"
Page 144 of 280

En el caso anterior, posiblemente se esperaba que la vista limitase sus resultados a las categoras de "negocios", pero los resultados tienen informacin sobre otras categoras. Para obtener ms informacin sobre group by y esta extensin TransactSQL para group by , consulte el Chapter 3. Definicin de vista con una combinacin Es posible crear una vista derivada de ms de una tabla base. A continuacin se muestra un ejemplo de una vista derivada de las tablas authors y publishers . La vista contiene los nombres y ciudades de los autores que viven en la misma ciudad que un editor, junto con el nombre y la ciudad de cada editor. create view cities (authorname, acity, publishername, pcity) as select au_lname, authors.city, pub_name, publishers.city from authors, publishers where authors.city = publishers.city Vistas derivadas de otras vistas Se puede definir una vista en relacin con otra vista, como en el siguiente ejemplo: create view hiprice_computer as select title, price from hiprice where type = 'popular_comp' Vistas distinct Es posible asegurarse de que las filas que contiene una vista son nicas, como se muestra en este ejemplo: create view author_codes as select distinct au_id from titleauthor Una fila es un duplicado de otra fila si todos los valores de sus columnas coinciden de forma exacta con los valores de las mismas columnas contenidos en otra fila. Dos valores nulos se consideran idnticos. SQL Server aplica el requisito distinct a la definicin de vista cuando accede a la vista por primera vez y antes de realizar cualquier proyeccin o seleccin. Las vistas tienen el mismo aspecto y comportamiento que cualquier tabla de base de datos. Si selecciona una proyeccin de la vista distinct (es decir, si selecciona algunas de las columnas de la vista, pero todas sus filas), puede obtener resultados que parezcan duplicados. Sin embargo, cada fila de la vista en s contina siendo nica. Por ejemplo, supongamos que usted crea una vista distinct , myview , con tres columnas, a, b y c , que contiene estos valores: Tabla 9-1: Valores de muestra de la vista distinct myview a 1 1 1 b 1 2 1 c 2 3 0

Cuando introduce esta consulta: select a, b from myview el resultado tiene el siguiente aspecto: a --1 1 1 b --1 2 1

La primera y tercera fila parece que estn duplicadas. Sin embargo, las filas de la vista subyacente siguen siendo nicas.
Page 145 of 280

Vistas que incluyen columnas IDENTITY Se puede definir una vista que incluya una columna IDENTITY, como se muestra en este ejemplo: create view sales_view as select syb_identity, stor_id from sales_daily Se puede seleccionar la columna IDENTITY de la vista utilizando la palabra clave syb_identity , a menos que la vista:

Seleccione la columna IDENTITY ms de una vez, o Incluya columnas de ms de una tabla, o Calcule una columna nueva a partir de la columna IDENTITY, o Incluya una funcin agregada.

Si una o ms de estas condiciones es verdadera, SQL Server no reconoce la columna como una columna IDENTITY con respecto a la vista. Al ejecutar el procedimiento del sistema sp_help en la vista, la columna muestra un valor IDENTITY de 0. Uso de la palabra clave with check option con create view Normalmente, SQL Server no verifica las instrucciones insert y update en vistas para determinar si las filas afectadas estn dentro del alcance de la vista. Una instruccin puede insertar una fila en la tabla base subyacente pero no en la vista, ni cambiar una fila existente para que deje de cumplir los criterios de seleccin de la vista. Cuando se crea una vista con with check option, cada operacin insert y update realizada mediante la vista se valida segn los criterios de seleccin de la vista. Todas las filas insertadas o actualizadas mediante la vista deben permanecer visibles por medio de sta, o la instruccin no se ejecuta correctamente. A continuacin se muestra un ejemplo de una vista, stores_cal , creada con with check option . Esta vista incluye informacin sobre las tiendas ubicadas en California, pero excluye la informacin sobre las tiendas ubicadas en cualquier otro estado. La vista se crea seleccionando todas las filas de la tabla stores cuya columna state tenga el valor "CA": create view stores_cal as select * from stores where state = "CA" with check option Cuando se intenta insertar una fila mediante stores_cal , SQL Server verifica si la nueva fila se encuentra dentro del alcance de la vista. La siguiente instruccin insert no se ejecuta correctamente porque la fila nueva tendra un valor state de "NY", en lugar de "CA": insert stores_cal values ("7100", "Castle Books", "351 West 24 St.", "New York", "NY", "USA", "10011", "Net 30") Cuando se intenta actualizar una fila mediante stores_cal , SQL Server verifica si la actualizacin no har que la fila desaparezca de la vista. La siguiente instruccin update no se ejecuta correctamente porque cambiara el valor de state de "CA" a "MA". Despus de la actualizacin, la fila dejara de estar visible mediante la vista. update stores_cal set state = "MA" where stor_id = "7066" Vistas derivadas de otras vistas Si se crea una vista con with check option , todas las vistas derivadas de la vista "base" deben satisfacer su opcin de verificacin. Cada fila insertada mediante la vista derivada debe estar visible a travs de la vista base. Cada una de las filas actualizadas mediante la vista derivada deben permanecer visibles a travs de la vista base. Considere la vista stores_cal30 , que se deriva de stores_cal . La vista nueva incluye informacin sobre tiendas de California con condiciones de pago "Net 30":

Page 146 of 280

create view stores_cal30 as select * from stores_cal where payterms = "Net 30" Dado que stores_cal se cre con with check option , todas las filas insertadas o actualizadas mediante stores_cal30 deben estar visibles a travs de stores_cal . Se rechazar cualquier fila con un valor state distinto de "CA". Observe que stores_cal30 no tiene ninguna clusula with check option propia. Esto significa que es posible insertar o actualizar una fila con un valor payterms distinto de "Net 30" mediante stores_cal30 . La siguiente instruccin update se ejecutara correctamente, aunque la fila dejara de estar visible mediante stores_cal30 : update stores_cal30 set payterms = "Net 60" where stor_id = "7067" Limitaciones en vistas definidas con combinaciones externas Las vistas definidas con combinaciones externas tienen algunas limitaciones que pueden generar resultados imprevistos cuando se recuperan datos de las mismas. Se debe tener cuidado al utilizar dichas vistas. Si define una vista con una combinacin externa y luego consulta la vista con una calificacin en una columna de la tabla interna de la combinacin externa, los resultados pueden ser distintos de los previstos. La calificacin de la consulta no restringe el nmero de filas devueltas, pero afecta a las filas que contienen el valor NULL. Para las filas que no cumplen la calificacin, aparece un valor NULL en las columnas de la tabla interna de dichas filas. Esto es resultado del hecho de que en Transact-SQL la representacin interna de una consulta en una vista es una combinacin de la definicin de la vista y la calificacin en la vista. Por ejemplo, supongamos que existen las siguientes tablas: Tabla A:

a
1 2 3 Tabla B:

b c
1 10 2 11 6 12 Luego cree una vista a partir de estas dos tablas. La definicin de vista contiene una combinacin externa: create view A_B as select a,b,c from A,B where A.a*=B.b Despus ejecute la siguiente consulta, que genera los siguientes resultados: select a,c from A_B where c = 10 ac ----- ----1 10 2 NULL Combina y califica en c Combina, pero no cumple las calificaciones

Page 147 of 280

3 NULL No combina (3 rows affected) La calificacin (c = 10) no afecta al nmero de filas devueltas. Sin embargo, NULL aparece en la columna de la tabla interna para cada fila que no cumple la calificacin o no se combina con filas de la tabla externa. Recuperacin de datos mediante vistas Al recuperar datos mediante una vista, SQL Server comprueba si todos los objetos de base de datos referenciados en la instruccin existen y si son vlidos en el contexto de la instruccin. Si las verificaciones son satisfactorias, SQL Server combina la instruccin con la definicin almacenada de la vista y la convierte en una consulta de las tablas subyacentes de la vista, como se ha explicado en una seccin anterior. Este proceso se llama resolucin de vista . Considere la instruccin de definicin de vista descrita anteriormente en este captulo y una consulta contra ella: create view hiprice as select * from titles where price > $15 and advance > $5000 select title, type from hiprice where type = 'popular_comp' De forma interna, SQL Server combina la consulta de hiprice con su definicin, convirtiendo la consulta en: select title, type from titles where price > $15 and advance > $5000 and type = 'popular_comp' En general, es posible consultar cualquier vista de cualquier modo como si fuera una tabla real. Se pueden utilizar combinaciones, clusulas group by , subconsultas y otras tcnicas de consulta en las vistas, en cualquier combinacin. Sin embargo, tenga presente que si la vista se define con una combinacin externa o una funcin agregada, al consultar la vista, los resultados pueden ser imprevistos. Consulte la seccin anterior sobre limitaciones en definiciones de vistas. Note: Se puede utilizar select en columnas text e image , pero no se permite el uso de los comandos readtext y writetext . Adems, no es posible seleccionar la columna sensitivity de una vista. Resolucin de vistas Cuando se define una vista, SQL Server comprueba si todas las tablas o vistas especificadas en la clusula from existen, y muestra un mensaje de error si hay algn problema. Se realizan verificaciones similares al efectuar una consulta mediante la vista. Entre el momento en que se define una vista y el momento en que se usa en una instruccin, las cosas pueden cambiar. Por ejemplo, una o ms tablas o vistas indicadas en la clusula from de la definicin de vista pueden haberse omitido. O, tambin, una o ms de las columnas especificadas en la clusula select de la definicin de vista pueden haberse cambiado de nombre. Para resolver una vista totalmente, SQL Server comprueba que:

Todas las tablas, vistas y columnas de las que se deriva la vista todava existen. El tipo de datos de cada columna sobre la que depende una columna de vista no se ha cambiado a un tipo incompatible. Las instrucciones update , insert o delete no violan las restricciones sobre modificacin de vistas. Estas se explican en una seccin posterior de este captulo.

Si falla alguna de estas verificaciones, SQL Server muestra un mensaje de error. Redefinicin de vistas
Page 148 of 280

A diferencia de muchos otros sistemas de administracin de bases de datos, SQL Server permite redefinir una vista sin necesidad de redefinir otras vistas que dependen de ella, a menos que la redefinicin imposibilite que SQL Server convierta la vista dependiente. Como ejemplo, se muestran la tabla authors y tres vistas posibles. Cada vista satisfactoria se define utilizando la vista que la precede: view2 se crea a partir de view1 y view3 se crea a partir de view2 . De esta forma, view2 depende de view1 y view3 depende de las dos vistas precedentes. Cada nombre de vista va seguido de la instruccin select usada para crear la vista. view1 : create view view1 as select au_lname, phone from authors where postalcode like "94%" v iew2 : create view view2 as select au_lname, phone from view1 where au_lname like "[M-Z]%" view3 : create view view3 as select au_lname, phone from view2 where au_lname = "MacFeather" La tabla authors en la que se basan estas vistas se compone de estas columnas: au_id , au_lname , au_fname , phone , address , city , state y postalcode. Se puede omitir view2 y sustituirse por otra vista, llamada tambin view2 , que contenga criterios de seleccin ligeramente diferentes, como au_lname , phone from view_1 where au_lname like "[M-P]". View3 , que depende de view2 , todava es vlida y no es necesario redefinirla. Cuando se utiliza una consulta que haga referencia a view2 o view3 , la resolucin de la vista tiene lugar del modo habitual. Si se redefine view2 de forma que view3 no pueda derivarse de ella, view3 pasar a ser invlida. Por ejemplo, si otra versin nueva de view2 contiene una sola columna, au_lname , en lugar de las dos columnas que view3 espera, view3 ya no puede usarse dado que no puede derivar la columna phone del objeto del que depende. Sin embargo, view3 todava existe y puede volver a utilizarse omitiendo la vista view2 invlida y volviendo a crear view2 con las columnas au_lname y phone . En resumen, se puede cambiar la definicin de una vista intermedia sin afectar a las vistas dependientes siempre que la lista select de las vistas dependientes siga siendo vlida. Si se viola esta regla, una consulta que haga referencia a la vista invlida generar un mensaje de error. Cambio de nombre de las vistas Se puede cambiar el nombre de una vista con el procedimiento del sistema sp_rename , cuya sintaxis es la siguiente: sp_rename ojbname , newname

Por ejemplo, para cambiar el nombre titleview a bookview : sp_rename titles_view, bookview Lgicamente, el nombre nuevo debe seguir las reglas para identificadores (no se puede utilizar sp_rename para especificar un identificador nuevo y delimitado para una vista). Slo se puede cambiar el nombre de las vistas que se poseen. El propietario de la base de datos puede cambiar el nombre de la vista de cualquier usuario. La vista debe estar en la base de datos actual. Alteracin u omisin de objetos subyacentes
Page 149 of 280

Pueden surgir problemas si se cambia el nombre de un objeto subyacente de una vista. Las vistas que dependen de una tabla o vista cuyo nombre ha cambiado pueden funcionar correctamente durante un tiempo. De hecho, funcionan hasta que SQL Server las recompila. La recompilacin tiene lugar por diversas razones y sin notificacin al usuario; por ejemplo, si se carga una base de datos o si un usuario omite y vuelve a crear una tabla u omite un ndice. Debido a esto, los intentos de consultar o modificar la vista pueden hacer que SQL Server devuelva mensajes de error de forma repentina. En este punto, es necesario omitir la vista y volver a crearla, de forma que su texto refleje el nombre nuevo del objeto del que depende. Para evitar dichos problemas, la forma ms segura es no cambiar el nombre de ninguna tabla o vista referenciada por una vista, o bien modificar las definiciones de sus vistas dependientes al cambiar su nombre. La situacin es similar cuando la vista depende de una tabla o vista que se ha omitido. Cuando alguien intenta utilizar la vista, SQL Server genera un mensaje de error. Sin embargo, si se crea una tabla o vista nueva para sustituir a la que se ha omitido, la vista volver a ser utilizable. Si define una vista con una clusula select * y luego altera la estructura de sus tablas subyacentes mediante la adicin de columnas, las columnas nuevas no aparecern. Esto se debe a que la abreviatura mediante asterisco se interpreta y ampla cuando se crea la vista por primera vez. Para ver las columnas nuevas mediante la vista, omita la vista y vuelva a crearla. Modificacin de datos mediante vistas Aunque SQL Server no pone ninguna restriccin en la recuperacin de datos mediante vistas y Transact-SQL pone menos restricciones en la modificacin de datos mediante vistas que otras versiones de SQL, existen varias clases de operaciones de modificacin de datos no permitidas mediante vistas:

No se permiten las operaciones update , insert o delete que hacen referencia a una columna de la vista que es un clculo, es decir, una columna calculada o una funcin incorporada. No se permiten las operaciones update , insert o delete que hacen referencia a una vista que incluye agregados o agregados de fila, es decir, funciones incorporadas y una clusula group by o compute . No se permiten las operaciones insert, delete y update que hacen referencia a una vista distinct . No se permiten instrucciones insert a menos que todas las columnas NOT NULL de las tablas subyacentes o las vistas se incluyan en la vista mediante la que se estn insertando filas nuevas. SQL Server no tiene ningn modo de suministrar valores para las columnas NOT NULL de los objetos subyacentes. Si una vista tiene una clusula with check option , todas la filas insertadas o actualizadas mediante la vista (o mediante cualquier vista derivada) deben cumplir los criterios de seleccin de la vista. No se permiten instrucciones delete en vistas de mltiples tablas. No se permiten instrucciones insert en vistas de mltiples tablas creadas con with check option. Se permiten instrucciones update en vistas de mltiples tablas con with check option . La actualizacin no se efecta de forma correcta si alguna de las columnas afectadas aparece en la clusula where , en una expresin que incluya columnas de ms de una tabla. No se permiten instrucciones insert y update en vistas distinct de mltiples tablas. Las instrucciones update no pueden especificar un valor para una columna IDENTITY. El propietario de la tabla, el propietario de la base de datos o el administrador del sistema pueden insertar (mediante insert ) un valor explcito en una columna IDENTITY despus de definir identity_insert on para la tabla base de la columna. Si inserta o actualiza una fila mediante una vista de mltiples tablas, todas las columnas afectadas deben pertenecer a la misma tabla base. writetext no se permite en las columnas text e image de una vista.

Cuando se intenta ejecutar update , insert o delete para una vista, SQL Server comprueba que no se viola ninguna de las restricciones anteriores ni ninguna de las reglas de integridad de datos. Por qu algunas vistas pueden actualizarse y otras no? Si examina los ejemplos de cada uno de los tipos de vistas que no pueden actualizarse, entender mejor las restricciones. Restricciones en la actualizacin de vistas Columnas calculadas en la definicin de vista La primera restriccin se aplica a las columnas de vistas derivadas de columnas calculadas o funciones incorporadas. Por ejemplo, la columna amt_due de la vista accounts , creada anteriormente, es una columna calculada. create view accounts (title_id, advance, amt_due) as select titles.title_id, advance, (price * royalty/100) * total_sales from titles, roysched
Page 150 of 280

where price > $15 and advance > $5000 and titles.title_id = roysched.title_id and total_sales between lorange and hirange Las filas visibles mediante accounts son: select * from accounts title_id advance --------------PC1035 7,000.00 PC8888 8,000.00 PS1372 7,000.00 TC3218 7,000.00 (4 rows affected) Las operaciones update e insert no se permiten en la columna amt_due porque no hay forma de deducir los valores subyacentes de precio, derechos de autor o ventas anuales hasta la fecha, a partir de los valores que puedan introducirse en la columna amt_due . Las operaciones delete no tienen ningn sentido porque no hay ningn valor subyacente que eliminar.

amt_due --------32,240.16 8,190.00 809.63 785.63

group by o compute en la definicin de vista


La segunda restriccin se aplica a todas las columnas de vistas que contengan valores agregados, es decir, vistas cuya definicin incluya una clusula group by o compute . A continuacin se muestra una vista definida con group by y las filas que se ven a travs de ella: create view categories (category, average_price) as select type, avg(price) from titles group by type select * from categories category average_price ------------------------UNDECIDED NULL business 13.73 mod_cook 11.49 popular_comp 21.48 psychology 13.50 trad_cook 15.96 (6 rows affected) No tendra sentido insertar filas (mediante insert ) en la vista categories . A qu grupo de filas subyacentes pertenecera una fila insertada? No es posible realizar actualizaciones en la columna average_price porque no hay forma de saber cmo deberan cambiar los precios subyacentes a partir de los valores introducidos en dicha columna. En teora, se podran permitir eliminaciones y actualizaciones en la columna category , pero SQL Server no las admite. Valores nulos en objetos subyacentes La tercera restriccin se aplica a instrucciones insert si hubiera alguna columna NOT NULL en las tablas o vistas de las que se deriva la vista. Por ejemplo, supongamos que no se permiten valores nulos en una columna de una tabla sobre la que se basa una vista. Generalmente, cuando se insertan filas nuevas (con insert ) mediante una vista, todas las columnas de las tablas subyacentes que no estn incluidas en la vista reciben valores nulos. Si no se permiten valores nulos en una o ms de estas columnas, no se permitirn inserciones mediante la vista. Considere la vista: create view titleview as select title_id, price, total_sales from titles where type = 'business'
Page 151 of 280

La columna title de la tabla subyacente titles no admite valores nulos, por lo que no es posible realizar ninguna operacin insert mediante titleview . Aunque la columna title ni siquiera existe en la vista, su prohibicin de valores nulos convierte en ilegal cualquier insercin en la vista. De forma similar, si la columna title_id tiene un ndice nico, las actualizaciones o inserciones que duplicaran los valores de la tabla subyacente se rechazan, incluso si la entrada no duplica ningn valor de la vista. Vistas creadas con with check option La cuarta restriccin determina los tipos de modificaciones que pueden realizarse mediante vistas con opciones de verificacin. Si una vista tiene una clusula with check option , cada fila insertada o actualizada mediante la vista debe estar visible dentro de la vista. Esto se cumple ya inserte o actualice la vista directa o indirectamente mediante otra vista derivada. Vistas de mltiples tablas La quinta restriccin determina los tipos de modificaciones que pueden realizarse mediante vistas que combinan columnas de mltiples tablas. SQL Server prohibe las instrucciones delete en las vistas de mltiples tablas, pero permite las instrucciones update y insert que no se permitiran en otros sistemas. Puede insertar o actualizar una vista de mltiples tablas si:

La vista no tiene ninguna clusula with check option . Todas las columnas que se insertan o actualizan pertenecen a la misma tabla base.

Por ejemplo, considere la siguiente vista, que incluye columnas de titles y publishers y no tiene ninguna clusula with check option : create view multitable_view as select title, type, titles.pub_id, state from titles, publishers where titles.pub_id = publishers.pub_id Una sola instruccin insert o de actualizacin puede especificar valores tanto para las columnas de titles como para la columna de publishers . La siguiente instruccin update se ejecuta de forma correcta: update multitable_view set type = "user_friendly" where type = "popular_comp" Pero esta instruccin fracasa porque afecta a columnas de titles y publishers : update multitable_view set type = "cooking_trad", state = "WA" where type = "trad_cook" Vistas que incluyen columnas IDENTITY La ltima restriccin determina los tipos de modificaciones que pueden realizarse en vistas que incluyen columnas IDENTITY. Por definicin, las columnas IDENTITY no son actualizables. Las actualizaciones mediante una vista no pueden especificar un valor de columna IDENTITY. Las inserciones en columnas IDENTITY estn limitadas al propietario de la tabla, el propietario de la base de datos y el administrador del sistema. Para permitir dichas inserciones mediante una vista, defina set identity_insert o n para la tabla base de la columna. No es suficiente con definir set identity_insert o n para la vista mediante la que se est realizando la insercin. Omisin de vistas Para eliminar una vista de la base de datos, utilice el comando drop view , cuya sintaxis es la siguiente:

Page 152 of 280

drop view [[ database [, [[ database .]

.] owner owner .]

.] view_name view_name ]...

Como se ha indicado, puede omitir ms de una vista a la vez. Slo su propietario (o el propietario de la base de datos) puede omitir una vista. A continuacin se muestra el modo de omitir la vista hiprice : drop view hiprice Cuando se ejecuta el comando drop view , la informacin sobre la vista indicada se elimina de las tablas del sistema sysprocedures , sysobjects , syscolumns , syscomments , sysprotects y sysdepends . Tambin se eliminan todos los privilegios para dicha vista. Si una vista depende de una tabla o de otra vista que se ha omitido, SQL Server genera un mensaje de error si alguien intenta utilizar la vista. Si se crea una tabla o vista nueva para sustituir a la que se ha omitido, con el mismo nombre, la vista se convierte de nuevo en utilizable, siempre que existan las columnas referenciadas en la definicin de vista. Uso de vistas como mecanismos de seguridad El permiso para acceder al subconjunto de datos de una vista debe concederse o revocarse de forma explcita, independientemente de los permisos vigentes en las tablas subyacentes de la vista. Los datos de una tabla subyacente que no est incluida en la vista se ocultan de los usuarios que tienen autorizacin para acceder a la vista pero no para acceder a la tabla subyacente. Por ejemplo, posiblemente no se desear que determinados usuarios tengan acceso a las columnas de titles relacionadas con dinero y ventas. En tal caso, se puede generar una vista de titles que omita dichas columnas y luego conceder a todos los usuarios el permiso sobre la vista y nicamente al departamento de ventas el permiso sobre la tabla. Por ejemplo: revoke all on titles to public grant all on bookview to public grant all on titles to sales Para obtener informacin sobre cmo conceder o revocar permisos (mediante grant y revoke , respectivamente), consulte la Gua del Usuario de las Caractersticas de Seguridad . Obtencin de informacin sobre vistas Varios procedimientos del sistema proporcionan informacin sobre las vistas a partir de las tablas del sistema. Se puede obtener un informe sobre una vista con el procedimiento del sistema sp_help . Por ejemplo: sp_help hiprice Name Owner -------------hiprice dbo

type ----view

Created_on ------------------Feb 12 1987 11:57AM

Data_located_on_segment When_created ------------------------------ -------------------Column_name Type Length Precision ----------------- -------------title_id tid 6 NULL title varchar 80 NULL type char 12 NULL pub_id char 4 NULL price money 8 NULL advance money 8 NULL royalty int 4 NULL total_sales int 4 NULL notes varchar 200 NULL pubdate datetime 8 NULL Null Default_name Rule_name Identity ----------------- ---------------0 NULL NULL 0 0 NULL NULL 0 Scale ----NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL

Page 153 of 280

0 1 1 1 1 1 1 0

NULL NULL NULL NULL NULL NULL NULL NULL

NULL NULL NULL NULL NULL NULL NULL NULL

0 0 0 0 0 0 0 0

No existe ninguna clave definida para este objeto. (return status = 0) Para mostrar el texto de la instruccin create view , ejecute el procedimiento del sistema sp_helptext : sp_helptext hiprice ---------1 (1 row affected) text -------------------------------------------create view hiprice as select * from titles where price > $15 and advance > $5000 (1 row affected, return status = 0) El procedimiento del sistema sp_depends muestra todos los objetos que la vista o tabla referencian en la base de datos actual, as como todos los objetos que hacen referencia a dicha vista o tabla. A continuacin se muestra un ejemplo: sp_depends titles Cosas incluidas en la base de datos actual que hacen referencia al objeto. object type --------------------------------------dbo.hiprice vista dbo.titleview vista dbo.reptq1 procedimiento almacenado dbo.reptq2 procedimiento almacenado dbo.reptq3 procedimiento almacenado (return status = 0) Para obtener informacin completa sobre los procedimientos del sistema, consulte el Manual de Referencia de SQL Server . Chapter 10

Uso de funciones incorporadas en consultas


Transact-SQL proporciona distintos tipos de funciones incorporadas que devuelven distintos tipos de informacin desde la base de datos. Estas funciones son extensiones Transact-SQL para SQL. Se pueden utilizar funciones incorporadas en la lista select , en la clusula where y en cualquier parte donde se permita una expresin. Tambin es posible usarlas como parte de un procedimiento almacenado o programa. SQL Server proporciona una gran variedad de funciones incorporadas. En este captulo se trata lo siguiente:

Funciones del sistema, la mayora de las cuales devuelven informacin de las tablas del sistema Funciones de cadena, que manipulan valores char , nchar , varchar , nvarchar , binary y varbinary . Funciones de texto, que manipulan valores text e image Funciones matemticas, que realizan operaciones trigonomtricas y geomtricas, adems de otros tipos de manipulaciones de nmeros
Page 154 of 280

Funciones de fecha, que manipulan valores datetime y smalldatetime Funciones de conversin de tipos de datos, que convierten expresiones de un tipo de datos a otro y que asignan formato a las fechas en una variedad de estilos Funciones del sistema Funciones de cadena Funciones de texto Funciones matemticas Funciones de fecha Funciones de conversin de tipos de datos

Funciones del sistema Las funciones del sistema devuelven informacin especial de la base de datos. Muchas de ellas proporcionan un mtodo abreviado de consultar las tablas del sistema. La sintaxis general de las funciones del sistema es: select function_name ( argument [ s ])

Las funciones del sistema pueden utilizarse en la lista select , la clusula where y en cualquier lugar donde se permita una expresin. Por ejemplo, para buscar el nmero de identificacin de usuario del colaborador que se conecta como " harold ", escriba: select user_id("harold") Suponiendo que la ID de usuario de "harold" es 13, el resultado ser: ------------13 (1 row affected) Generalmente, el nombre de la funcin indica el tipo de informacin que se devuelve. La funcin del sistema user_name toma un nmero de ID como su argumento y devuelve el nombre de usuario: select user_name(13) --------harold (1 row affected) Para hallar el nombre del usuario actual, es decir, su nombre, el argumento se omite: select user_name() --------dbo (1 row affected) Tenga presente que el administrador del sistema se convierte en propietario de la base de datos que est utilizando al asumir la ID de usuario de servidor 1. Al usuario "invitado" siempre se le asigna la ID de usuario de servidor -1. Dentro de una base de datos, el nombre de usuario ( user_name ) del propietario de la base de datos siempre es "dbo"; su ID de usuario es 1. Dentro de una base de datos, la ID de usuario "invitado" siempre es 2. Esta lista proporciona el nombre de cada funcin del sistema, el argumento que usa y el resultado que devuelve: Tabla 10-1: Funciones del sistema, argumentos y resultados
Page 155 of 280

Funcin col_name col_length

Argumento ( object_id , column_id [, database_id ]) ( object_name , column_name )

Resultado Devuelve el nombre de la columna. Devuelve la longitud definida de la columna. Use datalength para ver el tamao de datos real. Devuelve el nmero de pginas libres de una seccin del disco. Si la base de datos est abierta, el valor se toma de la memoria; si la base de datos no est en uso, el valor se toma de la columna u nreservedpgs de sysusages . Devuelve el nmero de pginas usadas por la tabla ( doampg ) o el ndice ( ioampg ). El resultado no incluye las pginas utilizadas para las estructuras internas. Devuelve la longitud de la expresin en bytes. e xpression suele ser un nombre de columna. Si e xpression es una constante de caracteres, debe incluirse entre comillas. Devuelve el nmero de ID de la base de datos. d atabase_name debe ser una expresin de caracteres; si es una expresin de constantes, es necesario incluirla entre comillas. Si no se proporciona ningn d atabase_name , db_id devuelve el nmero de ID de la base de datos actual. Devuelve el nombre de la base de datos. d atabase_id debe ser una expresin numrica. Si no se proporciona ninguna d atabase_id , db_name devuelve el nombre de la base de datos actual. Devuelve la ID de proceso principal del proceso cliente (no el proceso SQL Server). Devuelve el nombre de computadora principal actual del proceso cliente (no el proceso SQL Server).

curunreservedpgs (dbid, lstart, unreservedpgs )

data_pgs

( object_id , { doampg | ioampg }) ( expression )

datalength

db_id

( [ database_name ] )

db_name host_id host_name index_col isnull

([ database_id ]) () ()

( object_name , index_id , key_ Devuelve el nombre de la columna indexada; devuelve NULL si o # [, user_id ]) bject_name no es un nombre de tabla ni de vista. ( expression1 , expression2 ) Sustituye el valor indicado en e xpression2 cuando e xpression1 da como resultado NULL. Los tipos de datos de las expresiones deben convertirse de forma implcita, o es necesario usar la funcin c onvert . Maneja el umbral de ltima oportunidad del segmento de diario. lastchance crea un umbral de ltima oportunidad en la base de datos especificada. ({{ "lastchance" | "logfull" | logfull devuelve 1 si se ha cruzado el umbral de ltima oportunidad de "unsuspend" } , database_id la base de datos especificada y 0 en caso contrario. } | "reserve" , log_pages }) unsuspend activa las tareas suspendidas de la base de datos e inhabilita el umbral de ltima oportunidad si ste se ha cruzado. reserve devuelve el nmero de pginas de diario libres necesarios para volcar de forma correcta un diario de transacciones del tamao indicado.

lct_admin

object_id object_name proc_role reserved_pgs rowcnt show_role suser_id

( object_name ) ( object_id [, database_id ] ) ( "sa_role" | "sso_role" | "oper_role" ) ( object_id , { doampg | ioampg }) ( doampg ) () ([ server_user_name ])

Devuelve la ID del objeto. Devuelve el nombre del objeto. Comprueba si el usuario solicitante tiene el rol correcto para ejecutar el procedimiento. Si el rol es correcto, el resultado es 1. En caso contrario, el resultado es 0. Devuelve el nmero de pginas asignadas a la tabla o ndice. Esta funcin s indica las pginas usadas para las estructuras internas. Devuelve el nmero de filas de una tabla (valor estimado). Devuelve los roles activos actuales del usuario, si hay (sa_role, sso_role u oper_role). Si el usuario carece de roles, el resultado es NULL. Devuelve el nmero de ID del usuario de servidor de s yslogins. Si no se proporciona ningn s erver_user_name , el resultado es la ID de servidor del usuario actual.
Page 156 of 280

suser_name used_pgs

([ server_user_id ]) ( object_id , doampg , ioampg )

Devuelve el nombre del usuario de servidor. Las ID del usuario de servidor estn almacenadas en s yslogins . Si no se proporciona ninguna s erver_user_id , el resultado es el nombre del usuario actual. Devuelve el nmero total de pginas usadas por una tabla y su ndice agrupado. Compara valores t imestamp para evitar operaciones de actualizacin en una fila que se ha modificado desde que se seleccionara para examinarse. t imestamp es la marca horaria de la fila examinada. timestamp2 es la marca horaria de la fila almacenada. Esta funcin permite usar el modo de examinacin sin llamar a DB-Library (consulte la seccin sobre el modo de examinacin). Devuelve el nombre del usuario. Devuelve el nmero de ID del usuario. Indica el nmero de s ysusers en la base de datos actual. Si no se proporciona ningn u ser_name , el resultado es la ID del usuario actual. Devuelve el nombre del usuario, basado en la ID del usuario de la base de datos actual. Si no se proporciona ninguna u ser_id , el resultado es el nombre del usuario actual. Devuelve 0 si c haracter expression no es un identificador vlido (caracteres ilegales o ms de 30 bytes de longitud) y un nmero distinto de cero en caso contrario. Devuelve 1 si la ID especificada es un usuario o alias vlido en al menos una base de datos de este SQL Server. Debe tener el rol s a_role o sso_role para usar esta funcin en una s erver_user_id distinta de la propia.

tsequal

( timestamp , timestamp2 )

user user_id ([ user_name ])

user_name

([ user_id ])

valid_name

( character_expression )

valid_user

( server_user_id )

Cuando el argumento de una funcin del sistema es opcional, se utilizan la base de datos, computadora principal, usuario de servidor o usuario de base de datos actuales. Con la excepcin de user , las funciones incorporadas siempre se usan con parntesis, incluso si el argumento es NULL. Ejemplos del uso de funciones del sistema

col_length
Esta consulta halla la longitud de la columna title de la tabla titles (la "x=" se incluye para que el resultado tenga un encabezado de columna): select x = col_length("titles", "title") x -------80 (1 row affected)

datalength
En contraste con col_length , que halla la longitud definida de una columna, datalength informa de la longitud real, en bytes, de los datos almacenados en cada fila. Esta funcin se utiliza en los tipos de datos varchar , nvarchar , varbinary , text e image , puesto que pueden almacenar longitudes variables. datalength de cualquier dato NULL devuelve NULL. Todos los dems tipos de datos informan de su longitud definida. A continuacin se muestra un ejemplo que halla la longitud de la columna pub_name de la tabla publishers : select Length=datalength(pub_name), pub_name from publishers Length pub_name ------ -----------------------13 New Age Books 16 Binnet & Hardley 20 Algodata Infosystems (3 rows affected)

isnull
Page 157 of 280

Esta consulta halla el promedio de los precios de todos los ttulos, sustituyendo el valor ''$10.00'' para todas las entradas NULL de price : select avg(isnull(price,$10.00)) from titles -----------14.24 (1 row affected)

user_name
Esta consulta busca la fila en sysusers donde el nombre es igual al resultado de aplicar la funcin del sistema user_name a la ID de usuario 1: select name from sysusers where name = user_name(1) name -----------------------dbo (1 row affected) Funciones de cadena Las funciones de cadena se utilizan para diversas operaciones en cadenas de caracteres o expresiones. Algunas funciones de cadena pueden usarse tanto en datos binarios como de caracteres. Tambin es posible concatenar datos binarios, cadenas de caracteres o expresiones. Las funciones de cadena incorporadas devuelven valores que suelen necesitarse para operaciones en datos de caracteres. Los nombres de funciones de cadena no son palabras clave. La sintaxis de las funciones de cadena tiene este formato general: select function_name ( arguments )

Se pueden concatenar expresiones binarias o de caracteres as: select ( expression + expression [+ expression ]...)

Cuando se concatenan expresiones que no son de caracteres ni binarias, es necesario utilizar la funcin convert : select "The price is " + convert(varchar(12),price) from titles La mayora de las funciones de cadena slo pueden utilizarse en tipos de datos char , nchar , varchar y nvarchar , as como en tipos de datos que se convierten implcitamente a char o varchar . Algunas funciones de cadena tambin pueden usarse en datos binary y varbinary . patindex puede utilizarse en columnas text , char , nchar , varchar y nvarchar . La concatenacin puede utilizarse en columnas binary y varbinary , as como en columnas char , nchar , varchar y nvarchar . Sin embargo, no es posible concatener columnas text. Las funciones de cadena pueden estar anidadas y emplearse en cualquier lugar donde se permita una expresin. Cuando se usan constantes con una funcin de cadena, hay que incluirlas entre comillas dobles o simples. La Tabla 10-2 muestra los argumentos utilizados en las funciones de cadena. Si una funcin usa ms de una expresin del mismo tipo, los argumentos se numeran, como char_expr1 , char_expr2. Tabla 10-2: Argumentos usados en funciones de cadena Tipo de argumento Puede sustituirse por
Page 158 of 280

char_expr expression pattern approx_numeric integer_expr start length

Un nombre de columna de tipo de caracteres, variable, o expresin constante de tipo char , varchar , nchar o nvarchar . Las funciones que aceptan nombres de columna text se indican en la explicacin. Las expresiones constantes deben aparecer entre comillas. Un nombre de columna binario o de caracteres, variable o expresin constante. Pueden ser datos char , varchar, ncha r o nvarchar , en cuanto a char_expr , ms binary o varbinary . Una expresin de caracteres de tipo de datos char, nchar, varchar o nvarchar que puede incluir cualquiera de los caracteres comodn de coincidencia con el patrn admitidos por SQL Server. Cualquier numrico aproximado ( float , real o double precision ), nombre de columna, variable o expresin constante. Cualquier nmero entero (como tinyint, smallint o int ), nombre de columna, variable o expresin constante. Los mrgenes de tamao mximo se mencionan a medida que se aplican. Una expresin entera ( integer_expr). Una expresin entera ( integer_expr).

Cada funcin tambin acepta argumentos que pueden convertirse implcitamente al tipo especificado. Por ejemplo, las funciones que aceptan expresiones numricas aproximadas tambin aceptan las expresiones enteras. SQL Server convierte automticamente el argumento al tipo deseado. Tabla 10-3: Funciones de cadena, argumentos y resultados Fun cin ascii char Argument o ( char_expr ) ( integer_expr ) Resultado Devuelve el cdigo ASCII del primer carcter de la expresin. Convierte un valor integer de un solo byte en un valor character . char se utiliza generalmente como el inverso de ascii . integer_expr debe estar entre 0 y 255. Devuelve un tipo de datos char . Si el valor resultante es el primer byte de un carcter multibyte, el carcter puede estar indefinido. Examina expression2 para buscar la primera aparicin de expression1 y devuelve un valor entero que representa su posicin inicial. Si no se encuentra expression1 , devuelve 0. Si expression1 contiene caracteres comodn, charindex los trata como literales. Devuelve un valor entero que representa el nmero de caracteres de una expresin de caracteres o un valor text . Para los datos de longitud variable, char_length quita los espacios en blanco finales de la expresin antes de contar el nmero de caracteres. Para los juegos de caracteres multibyte, el nmero de caracteres de la expresin es generalmente menor que el nmero de bytes; use la funcin del sistema datalength para determinar el nmero de bytes. Devuelve un valor entero que representa la diferencia entre dos valores soundex . Consulte soundex ms adelante. Convierte maysculas en minsculas. Devuelve un valor de caracteres. Quita los espacios en blanco iniciales de la expresin de caracteres. Slo se quitan los valores equivalentes al carcter de espacio en la especificacin de caracteres especiales de SQL. Devuelve un valor entero que representa la posicin inicial de la primera aparicin de pattern en la expresin de caracteres especificada; cero si no se encuentra pattern . De forma predeterminada, patindex devuelve el desplazamiento en caracteres. Para devolver el desplazamiento en bytes, es decir, cadenas de caracteres multibyte, hay que especificar using bytes . El carcter comodn '%' debe preceder y seguir a pattern , excepto cuando se buscan caracteres iniciales o finales. Consulte la seccin sobre caracteres comodn en el Manual de Referencia de SQL Server para obtener una descripcin de los caracteres comodn que pueden emplearse en pattern . Puede utilizarse en datos text . Devuelve una cadena con el mismo tipo de datos que char_expr , que contiene la misma expresin repetida el nmero especificado de veces o tantas veces como quepa en un espacio de 255 bytes, cualquiera que sea inferior. Devuelve el inverso de char_expr ; si char_expr es "abcd", devuelve "dcba". Devuelve la parte de la expresin de caracteres que empieza por el nmero de caracteres desde la derecha. El valor de retorno tiene el mismo tipo de datos que la expresin de caracteres. Quita los espacios en blanco finales. Slo se quitan los valores equivalentes al carcter
Page 159 of 280

charindex

( expression1, expression2 )

char_length ( char_expr )

difference lower ltrim

( char_expr1, char_expr2 ) ( char_expr ) ( char_expr )

patindex

("% pattern %", char_expr [ using { bytes | chars | characters }] )

replicate reverse right rtrim

( char_expr,

integer_expr )
( char_expr ) ( char_expr,

integer_expr )
( char_expr )

de espacio en la definicin de caracteres especiales de SQL. soundex space ( char_expr ) ( integer_expr ) Devuelve un cdigo soundex de cuatro caracteres para cadenas de caracteres que se componen de una secuencia contigua de letras romanas vlidas de un solo byte o de doble byte. Devuelve una cadena con el nmero indicado de espacios de un solo byte. Devuelve una representacin de caracteres del nmero de coma flotante. length define el nmero de caracteres que se devolvern (incluido el punto decimal, todos los dgitos situados a la derecha e izquierda del punto decimal, y los espacios en blanco); decimal define el nmero de dgitos decimales que se devolvern.

str

( approx_numeric [, length [, decimal ] ])

length y decimal son opcionales. Si se especifican, deben ser no negativos. La longitud

predeterminada es 10; el decimal predeterminado es 0. str redondea la porcin decimal del nmero para que los resultados quepan dentro de la longitud especificada. stuff ( char_expr1 , start , length , char_expr2 ) ( expression , start , length ) ( char_expr ) Elimina los caracteres length de char_expr1 en start , despus inserta char_expr2 en char_expr1 en start . Para eliminar caracteres sin insertar otros caracteres, char_expr2 debera ser NULL, no " ", que indica un solo espacio. Devuelve parte de una cadena de caracteres o binaria. start especifica la posicin de carcter donde empieza la subcadena. length especifica el nmero de caracteres de la subcadena. Convierte minsculas en maysculas. Devuelve un valor de caracteres.

substring upper

Ejemplos del uso de funciones de cadena

charindex y patindex
Las funciones charindex y patindex devuelven la posicin inicial de un patrn especificado. Ambas toman dos argumentos, pero funcionan de forma ligeramente diferente, puesto que patindex puede utilizar caracteres comodn, pero charindex no. charindex slo puede utilizarse en columnas char , nchar , varchar y nvarchar ; patindex funciona en estas columnas y en columnas text . Ambas funciones toman dos argumentos. El primero es el patrn cuya posicin se desea. Con patindex , es necesario incluir signos de porcentaje antes y despus del patrn, a menos que se est buscando el patrn como el primer carcter (se omite el % inicial) o el ltimo (se omite el % final) de una columna. Para charindex , el patrn no puede incluir caracteres comodn. El segundo argumento es una expresin de caracteres, generalmente un nombre de columna, en el que SQL Server busca el patrn especificado. Para encontrar la posicin en la que el patrn "wonderful" comienza en una fila determinada de la columna notes de la tabla titles usando ambas funciones, escriba esta consulta: select charindex("wonderful", notes), patindex("%wonderful%", notes) from titles where title_id = "TC3218" ------------- ------------46 46 (1 row affected) Si no limita las filas que deben buscarse, la consulta devolver todas las filas de la tabla y mostrar valores cero para aquellas filas que no contengan el patrn. En el siguiente ejemplo, patindex busca todas las filas de sysobjects que empiecen con "sys" y cuyo cuarto carcter sea a, b, c o d: select name from sysobjects where patindex("sys[a-d]%", name) > 0 name -----------------------------sysalternates sysattributes syscharsets syscolumns syscomments sysconfigures sysconstraints
Page 160 of 280

syscurconfigs sysdatabases sysdepends sysdevices (11 rows affected)

str
La funcin str convierte nmeros en caracteres, con argumentos opcionales para la especificacin de la longitud del nmero (incluido el signo, el punto decimal y los dgitos a la derecha e izquierda del punto decimal) y el nmero de posiciones despus del punto decimal. Los argumentos de longitud y decimal de str (si se proporcionan) deben ser positivos. La longitud predeterminada es 10. El valor decimal predeterminado es 0. La longitud debe ser suficiente como para que quepa el punto decimal y el signo del nmero. La parte decimal del resultado se redondea para que quepa dentro de la longitud especificada. Sin embargo, si la parte entera del nmero no cabe dentro de la longitud, str devuelve una fila de asteriscos con la longitud especificada. Por ejemplo: select str(123.456, 2, 4) -** (1 row affected) Un approx_numeric corto se justifica a la derecha en la longitud especificada y un approx_numeric largo se trunca hasta el nmero especificado de decimales.

stuff
La funcin stuff inserta una cadena dentro de otra. stuff elimina una longitud de caracteres especificada de expr1 en la posicin inicial y luego inserta la cadena expr2 en la cadena expr1 en la posicin inicial. Si la posicin inicial o la longitud es negativa, se devuelve una cadena NULL. Si la posicin inicial es mayor que expr1 , se devuelve una cadena NULL. Si la longitud que debe eliminarse es mayor que expr1 , se elimina hasta el ltimo carcter en expr1 . Por ejemplo: select stuff("abc", 2, 3, "xyz") ---axyz (1 row affected) Para utilizar stuff a fin de eliminar un carcter, sustituya expr2 por NULL, no por comillas vacas. El uso de " " para especificar un carcter nulo lo sustituye por un espacio. select stuff("abcdef", 2, 3, null) --aef (1 row affected) select stuff("abcdef", 2, 3, "") ---a ef (1 row affected)

soundex y difference
La funcin soundex convierte una cadena de caracteres en un cdigo de cuatro dgitos para su uso en una comparacin. Las vocales se ignoran en la comparacin. Los caracteres no alfabticos terminan la evaluacin soundex . Esta funcin siempre devuelve algn valor. Estos dos nombres tienen cdigos soundex idnticos:
Page 161 of 280

select soundex ("smith"), soundex ("smythe") ----- ----S530 S530 La funcin difference compara los valores soundex de dos cadenas y evala la similitud entre ellos, devolviendo un valor de 0 a 4. Un valor de 4 es la mejor coincidencia posible. Por ejemplo: select difference("smithers", "smothers") --------4 (1 row affected) select difference("smothers", "brothers") --------2 (1 row affected) La mayora de las funciones de cadena restantes son fciles de usar y de entender. Por ejemplo: Tabla 10-4: Ejemplos de funciones de cadena Instruccin select right("abcde", 3) select right("abcde", 6) select upper("torso") select ascii("ABC") Resultado cde abcde TORSO 65

substring
El siguiente ejemplo usa la funcin substring . En l se muestra el apellido y la letra inicial de cada autor, por ejemplo, "Bennet A". select au_lname, substring(au_fname, 1, 1) from authors La funcin substring hace lo que su nombre implica: devuelve una parte de una cadena de caracteres o binaria. La funcin substring siempre toma tres argumentos. El primero puede ser una cadena de caracteres o binaria, un nombre de columna o una expresin con valor de cadena que incluya un nombre de columna. El segundo indica la posicin donde debe empezar la subcadena. El tercero especifica la longitud, en nmero de caracteres, de la cadena que ha de devolverse. Este es el aspecto de la sintaxis de substring : substring( expression , start , length )

Por ejemplo, a continuacin se indica cmo especificar los caracteres segundo, tercero y cuarto de la constante de caracteres "abcdef": select x = substring("abcdef", 2, 3) x --------bcd Concatenacin Es posible concatenar expresiones binarias o de caracteres (combinar dos o ms cadenas de caracteres o binarias, datos de caracteres o binarios, o una combinacin de los mismos) mediante el operador de concatenacin de cadenas +. Si concatena cadenas de caracteres, incluya cada expresin de caracteres entre comillas simples o dobles. Esta es la sintaxis de la concatenacin:
Page 162 of 280

select (

expression

expression

[+

expression

]...)

A continuacin se muestra cmo combinar dos cadenas de caracteres: select ("abc" + "def") ------abcdef (1 row affected) Esta consulta muestra los nombres de autor de California bajo el encabezado de columna Moniker , en el orden apellido-nombre y con una coma y un espacio despus del apellido: select Moniker = (au_lname + ", " + au_fname) from authors where state = "CA" Moniker ------------------------------------------------White, Johnson Green, Marjorie Carson, Cheryl O'Leary, Michael Straight, Dick Bennet, Abraham Dull, Ann Gringlesby, Burt Locksley, Chastity Yokomoto, Akiko Stringer, Dirk MacFeather, Stearns Karsen, Livia Hunter, Sheryl McBadden, Heather (15 rows affected) Para concatenar tipos de datos numricos o datetime , es necesario usar la funcin convert : select "The due date is " + convert(varchar(30), pubdate) from titles where title_id = "BU1032" --------------------------------------The due date is Jun 12 1985 12:00AM (1 row affected) Concatenacin y cadenas vacas La cadena vaca ("" o ") se evala como un solo espacio. Esta instruccin: select "abc" + "" + "def" da como resultado: abc def Funciones de cadena anidadas Las funciones de cadena pueden anidarse. Por ejemplo, para mostrar el apellido y la primera inicial del cada autor, con una coma despus del apellido y un punto despus del primer nombre, puede teclear: select (au_lname + "," + " " + substring(au_fname, 1, 1) + ".") from authors where city = "Oakland"
Page 163 of 280

-------------------------------------------Green, M. Straight, D. Stringer, D. MacFeather, S. Karsen, L. (5 rows affected) Para mostrar la pub_id y los dos primeros caracteres de cada title_id de los libros por encima de $20, escriba: select substring(pub_id + title_id, 1, 6) from titles where price > $20 -------------1389PC 0877PS 0877TC (3 rows affected) Funciones de texto Las funciones de texto incorporadas se utilizan para operaciones en datos text e image . Los nombres de funcin de texto, argumentos y resultados se muestran en la Tabla 10-5. Tabla 10-5: Funciones de texto incorporadas para datos text e image Funcin Argumento Resultado Devuelve un valor entero que representa la posicin inicial de la primera aparicin de pattern en la expresin de caracteres especificada; cero si no se encuentra pattern . De forma predeterminada, patindex devuelve el desplazamiento en caracteres; para devolver el desplazamiento en bytes para cadenas de caracteres multibyte, hay que especificar using bytes . El carcter comodn % debe preceder y seguir a pattern , excepto cuando se buscan caracteres iniciales o finales. Consulte la seccin sobre caracteres comodn del Manual de Referencia de SQL Server para obtener una descripcin de los caracteres comodn que se pueden utilizar en pattern . Devuelve el valor del puntero de texto, un valor binario de 16 bytes. El puntero de texto se verifica para garantizar que apunte a la primera pgina de texto. Verifica si es vlido un puntero de texto dado. Tenga en cuenta que el identificador para una columna text o image debe incluir el nombre de la tabla. Devuelve 1 si el puntero es vlido, 0 si el puntero no es vlido. Especifica el lmite, en bytes, de los datos t ext o image que van a ser devueltos con una instruccin select . El valor actual se almacena en la variable global @@textsize . n es un nmero entero que especifica el lmite en el nmero de bytes a devolver; 0 restaura el lmite predeterminado de 32K.

("% pattern %", char_expr [ using { patindex bytes | chars | characters } ] )

textptr textvalid

( text_columname ) (" table_name .. col_name ", textpointer )

set textsize

{n|0}

Adems de estas funciones, datalength (descrita en "Funciones del sistema") funciona en columnas text . Tambin pueden usarse las variables globales @@textcolid , @@textdbid , @@textobjid , @@textptr y @@textsiz e para manipular datos text e image . Ejemplos del uso de funciones de texto Este ejemplo utiliza la funcin textptr para localizar la columna text , blurb , asociada con la title_id BU7832 de la tabla texttest . El puntero de texto, una cadena binaria de 16 bytes, se incluye en una variable local, @val , y se suministra como parmetro del comando readtext . readtext devuelve 5 bytes empezando en el segundo byte, con un desplazamiento de 1. create table texttest (title_id varchar(6),blurb text null, pub_id char(4)) insert texttest values ("BU7832", "Straight Talk About Computers is an annotated analysis of what computers can do for you: a no-hype guide for the critical user", "1389")
Page 164 of 280

declare @val varbinary(16) select @val = textptr(blurb) from texttest where title_id = "BU7832" readtext texttest.blurb @val 1 5

La funcin textptr devuelve una cadena binaria de 16 bytes. Es una buena idea poner esta cadena en una variable local, como en el ejemplo anterior, y utilizarla como referencia. Una alternativa a la funcin textptr del ejemplo anterior es la variable global @@textptr : create table texttest (title_id varchar(6),blurb text null, pub_id char(4)) insert texttest values ("BU7832", "Straight Talk About Computers is an annotated analysis of what computers can do for you: a no-hype guide for the critical user", "1389") readtext texttest.blurb @@textptr 1 5 El valor de @@textptr se define a partir de la ltima operacin insert o update realizada en un campo text o image por el proceso actual de SQL Server. Las inserciones y actualizaciones efectuadas por otros procesos no afectan al proceso actual. La conversin explcita mediante la funcin convert se admite de text a char , nchar , varchar o nvarchar , y de image a varbinary o binary , pero los datos text o image se truncan a 255 bytes. La conversin de datos text o image a tipos de datos distintos de los indicados no se admite, ni implcita ni explcitamente. Funciones matemticas Las funciones matemticas incorporadas devuelven valores que normalmente son necesarios para realizar operaciones en datos matemticos. Las funciones matemticas tienen este formato general: function_name ( arguments )

La tabla a continuacin muestra los tipos de argumentos utilizados en las funciones matemticas incorporadas: Tabla 10-6: Argumentos usados en las funciones matemticas Tipo de argumento Puede sustituirse por Cualquier numrico aproximado ( float , real o double precision ), nombre de columna, variable, expresin constante, o una combinacin de los mismos. Cualquier nmero entero ( tinyint , smallint o int), nombre de columna, variable, expresin constante, o una combinacin de los mismos. Cualquier numrico exacto ( numeric , dec , decimal , tinyint , smallint o int ), numrico aproximado ( float , real o double precision ), o columna money , variable, expresin constante, o una combinacin de los mismos Cualquier numrico exacto, numrico aproximado o columna money , variable, expresin constante, o una combinacin de los mismos.

approx_numeric integer numeric power

Cada funcin tambin acepta argumentos que pueden convertirse implcitamente al tipo especificado. Por ejemplo, las funciones que aceptan tipos numricos aproximados tambin aceptan tipos de enteros. SQL Server convierte automticamente el argumento al tipo deseado. Si una funcin incluye ms de una expresin del mismo tipo, las expresiones estn numeradas (por ejemplo, approx_numeric1 , approx_numeric2 ). A continuacin se muestran las funciones matemticas, sus argumentos y los resultados que devuelven:
Page 165 of 280

Tabla 10-7: Funciones matemticas Func in abs acos asin atan atn2 ceiling cos cot Argumento ( numeric ) ( approx_numeric ) ( approx_numeric ) ( approx_numeric ) ( approx_numeric1 , approx_numeric2 ) ( numeric ) ( approx_numeric ) ( approx_numeric ) Resultado Devuelve el valor absoluto de una expresin dada. Los resultados son del mismo tipo y tienen la misma precisin y escala que la expresin numrica. Devuelve el ngulo (en radianes) cuyo coseno es el valor especificado. Devuelve el ngulo (en radianes) cuyo seno es el valor especificado. Devuelve el ngulo (en radianes) cuya tangente es el valor especificado. Devuelve el ngulo (en radianes) cuya tangente es ( approx_numeric1 / approx_numeric2 ). Devuelve el nmero entero ms pequeo mayor o igual que el valor especificado. Los resultados son del mismo tipo que la expresin numrica. Para expresiones numeric y decimal , los resultados tienen una precisin igual que la de la expresin y una escala de 0. Devuelve el coseno trigonomtrico del ngulo especificado (en radianes). Devuelve la cotangente trigonomtrica del ngulo especificado (en radianes). Convierte radianes en grados. Los resultados son del mismo tipo que la expresin numrica. Para expresiones numeric y decimal , los resultados tiene una precisin interna de 77 y una escala igual a la de la expresin. Cuando se utiliza el tipo de datos money, la conversin interna a float puede provocar una prdida de precisin. Devuelve el valor exponencial del valor especificado. Devuelve el nmero entero ms grande menor o igual que el valor especificado. Los resultados son del mismo tipo que la expresin numrica. Para expresiones de tipo numeric o decimal , los resultados tendrn una precisin igual a la de la expresin y una escala de 0. Devuelve el logaritmo natural del valor especificado. Devuelve el logoritmo de base 10 del valor especificado. Devuelve el valor constante de 3.1415926535897936. Devuelve el valor de numeric elevado a la potencia de power. Los resultados son del mismo tipo que numeric. Para expresiones de tipo numeric o decimal , los resultados tienen una precisin de 77 y una escala igual a la de la expresin. Convierte grados a radianes. Los resultados son del mismo tipo que numeric. Para expresiones de tipo numeric o decimal , los resultados tienen una precisin interna de 77 y una escala igual a la de la expresin numrica. Cuando se utiliza el tipo de datos money, la conversin interna a float puede provocar una prdida de precisin. Devuelve un valor float aleatorio entre 0 y 1, utilizando el integer opcional como valor semilla. Redondea el valor numeric para que tenga dgitos integer significativos. Un valor entero positivo determina el nmero de dgitos significativos a la derecha del punto decimal; un entero negativo, el nmero de dgitos significativos a la izquierda del punto decimal. Los resultados son del mismo tipo que la expresin numrica y, para expresiones numeric y decimal , tienen una precisin interna de 77 y una escala igual a la de la expresin numrica. Devuelve el signo de numeric : positivo (+1), cero (0) o negativo (-1). Los resultados son del mismo tipo y tienen la misma precisin y escala que la expresin numrica. Devuelve el seno trigonomtrico del ngulo especificado (medido en radianes). Devuelve la raz cuadrado del valor especificado. Devuelve la tangente trigonomtrica del ngulo especificado (medido en radianes).

degrees ( numeric ) exp floor log log10 pi power ( approx_numeric ) ( numeric ) ( approx_numeric ) ( approx_numeric ) () ( numeric , power )

radians ( numeric_expr ) rand ([ integer ])

round

( numeric , integer )

sign sin sqrt tan

( numeric ) ( approx_numeric ) ( approx_numeric ) ( approx_numeric )

Ejemplos del uso de funciones matemticas Las funciones matemticas incorporadas operan en datos numricos. Algunas funciones requieren datos de nmero entero y otras datos numricos aproximados. Un nmero de funciones operan en tipos numricos exactos, numricos aproximados, money y float . De forma predeterminada, la precisin de las operaciones incorporadas en los datos de tipo float es de 6 posiciones decimales. Se proporcionan trampas de error para manipular los errores de dominio o margen de las funciones matemticas. Los usuarios pueden definir ( set ) las opciones arithabort y arithignore para determinar el modo en que se manipulan los errores. Para obtener ms informacin sobre estas opciones, consulte la seccin "Errores de conversin". A continuacin se muestran ejemplos sencillos de funciones matemticas:
Page 166 of 280

Tabla 10-8: Ejemplos de funciones matemticas Instruccin select floor(123) select floor(123.45) select floor(1.2345E2) select floor(-123.45) select floor(-1.2345E2) select floor($123.45) select ceiling(123.45) select ceiling(-123.45) select ceiling(1.2345E2) select ceiling(-1.2345E2) select ceiling($123.45) select round(123.4545, 2) select round(123.45, -2) select round(1.2345E2, 2) select round(1.2345E2, -2) Resultado 123 123.000000 123.000000 -124.000000 -124.000000 123.00 124.000000 -123.000000 124.000000 -123.000000 124.00 123.4500 100.00 123.450000 100.000000

La funcin round(numeric, integer) devuelve siempre un valor. Si integer es negativo y supera el nmero de dgitos significativos de numeri c, SQL Server redondea slo el dgito ms significativo. Por ejemplo: select round(55.55, -3) devuelve el valor 100.000000 (el nmero de ceros a la derecha del punto decimal es igual a la escala de numeric ). Funciones de fecha Las funciones de fecha incorporadas se utilizan para mostrar informacin sobre fechas y horas. Estas funciones manipulan valores datetime y smalldatetime, y realizan operaciones aritmticas en ellos. Las funciones de fecha pueden utilizarse en la lista select , la clusula where o cualquier lugar que permita una expresin. Los valores con el tipo de datos datetime son almacenados internamente por SQL Server como dos nmeros enteros de 4 bytes. Los primeros 4 bytes almacenan el nmero de das antes o despus de la fecha base, 1 de enero de 1900 (January 1, 1900). La fecha base es la fecha de referencia del sistema. No se permiten valores datetime anteriores al 1 de enero de 1753. Los otros 4 bytes de la representacin interna de los datos de fecha y hora almacenan la hora del da hasta una precisin de 1/300 de un segundo. El tipo de datos smalldatetime almacena las fechas y horas del da con menos precisin que datetime . Los valores smalldatetime se almacenan como dos nmeros enteros de 2 bytes. Los primeros 2 bytes almacenan el nmero de das despus del 1 de enero de 1900. Los otros 2 bytes almacenan el nmero de minutos desde la medianoche. Las fechas van desde el 1 de enero de 1900 hasta el 6 de junio de 2079, con una precisin al minuto. El formato de visualizacin predeterminado de las fechas tiene el siguiente aspecto: Apr 15 1987 10:23PM Consulte la seccin sobre convert , ms adelante en este captulo, para obtener ms informacin sobre cmo cambiar el formato de visualizacin de datetime o smalldatetime . Cuando se introducen valores datetime o smalldatetime , hay que incluirlos entre comillas simples o dobles. SQL Server reconoce una amplia variedad de formatos de entrada de datos de fecha y hora. Para obtener ms informacin sobre los valores datetime y smalldatetime , consulte el Captulo 7, "Creacin de bases de datos y tablas", y el Captulo 8, "Adicin, modificacin y eliminacin de datos". La siguiente tabla muestra las funciones de fecha y los resultados que generan: Tabla 10-9: Funciones de fecha Funcin getdate Argumento () Resultado Fecha y hora actuales del sistema. Parte de un valor datetime o smalldatetime como una cadena ASCII.
Page 167 of 280

datename ( datepart , date )

datepart datediff dateadd

( datepart , date )

Parte de un valor datetime o smalldatetime , por ejemplo, el mes, como un valor entero. La cantidad de tiempo entre la segunda y la primera de las dos fechas, convertida al componente de fecha especificado, por ejemplo, meses, das, horas.

(datepart, date, date)

(datepart, number, Una fecha generada al aadir componentes de fecha a otra fecha. date)

Las funciones datename , datepart , datediff y dateadd toman como argumentos un componente de fecha (ao, mes, hora, etc.). La siguiente tabla enumera cada componente de fecha, su abreviatura, si hubiera alguna, y los valores enteros posibles para dicho componente de fecha. La funcin datename genera valores ASCII donde se necesitan, como para el da de la semana. Tabla 10-10: Componentes de fecha Componente de fecha Abreviatura Valores year quarter month week day dayofyear weekday hour minute second millisecond yy qq mm wk dd dy dw hh mi ss ms 1753-9999 1-4 1 - 12 1 - 366 1 - 31 1 - 54 1 - 7 (1 es domingo en us_english) 0 - 23 0 - 59 0 - 59 0 - 999

Observe que los valores del componente de fecha weekday se ven afectados por el valor del idioma. Obtencin de la fecha actual: getdate La funcin getdate genera la fecha y hora actuales en el formato interno de SQL Server para valores datetime y smalldatetime . getdate usa el argumento NULL, (). Para hallar la fecha y hora actuales del sistema, escriba: select getdate() -------------------------Jul 29 1991 2:50 PM (1 row affected) Podra utilizar getdate al disear un informe para que la fecha y hora actuales se impriman cada vez que se genere el informe. getdate tambin resulta til para funciones como el registro de la hora en que tuvo lugar una transaccin en una cuenta. Bsqueda de componentes de fecha como nmeros o nombres Las funciones datepart y datename generan el componente especificado de un valor datetime o smalldatetime (el ao, trimestre, da, hora, etc.) como un nmero entero o una cadena ASCII. Dado que smalldatetime slo tiene una precisin de minutos, cuando se utiliza un valor smalldatetime con cualquiera de estas funciones, los segundos y milisegundos siempre son cero. Los siguientes ejemplos toman la fecha del 29 de julio (July 29) que aparece en el ejemplo anterior. select datepart(month, getdate()) -------------7 (1 row affected)
Page 168 of 280

select datename ------------July (1 row affected)

month

getdate

())

Clculo de intervalos o fechas incrementales La funcin datediff calcula la cantidad de tiempo en componentes de fecha entre la segunda y la primera de las dos fechas especificadas; en otras palabras, datediff halla un intervalo entre dos fechas. El resultado es un valor entero con signo igual al date2 - date1 , en componentes de fecha. Esta consulta utiliza la fecha 30 de noviembre de 1985 y halla el nmero de das que han transcurrido entre pubdate y dicha fecha: select newdate = datediff(day, pubdate, "Nov 30 1985") from titles Para las filas de titles que tienen una pubdate del 21 de octubre de 1985, el resultado generado por la consulta anterior es 40, el nmero de das entre el 21 de octubre y el 30 de noviembre. Para calcular un intervalo en meses, la consulta es: select interval = datediff(month, pubdate, "Nov 30 1985") from titles Esta consulta genera el valor 1 para las filas con una pubdate en octubre y el valor 5 para las filas con una pubdate en junio. Cuando la primera fecha de la funcin datediff es posterior a la segunda fecha especificada, el valor resultante es negativo. Dado que dos de las filas de titles tienen valores pubdate que se han asignado utilizando la funcin getdate como valor predeterminado, estos valores se definen segn la fecha en la que se cre la base de datos pubs y devuelven valores negativos en las dos consultas anteriores. Si uno o ambos argumentos de fecha es un valor smalldatetime, se convierten en valores datetime internamente para el clculo. Los segundos y milisegundos de los valores smalldatetime se definen automticamente en 0 de cara al clculo de diferencias. Adicin de un intervalo de fecha: dateadd La funcin dateadd aade un intervalo a una fecha especificada. Por ejemplo, si las fechas de publicacin de todos los libros de la tabla titles se modificasen en tres das, podra obtener las nuevas fechas de publicacin con esta instruccin: select dateadd(day, 3, pubdate) from titles ------------------Jun 15 1985 12:00AM Jun 12 1985 12:00AM Jul 3 1985 12:00AM Jun 25 1985 12:00AM Jun 12 1985 12:00AM Jun 21 1985 12:00AM Sep 11 1986 11:02AM Jul 3 1985 12:00AM Jun 15 1985 12:00AM Sep 11 1986 11:02AM Oct 24 1985 12:00AM Jun 18 1985 12:00AM Oct 8 1985 12:00AM Jun 15 1985 12:00AM Jun 15 1985 12:00AM Oct 24 1985 12:00AM Jun 15 1985 12:00AM Jun 15 1985 12:00AM (18 rows affected) Si el argumento de fecha se proporciona como un valor smalldatetime , el resultado tambin ser smalldatetime . Puede utilizar dateadd para aadir segundos o milisegundos a un smalldatetime , pero slo tiene sentido si la fecha resultante devuelta por dateadd cambia al menos en un minuto.
Page 169 of 280

Funciones de conversin de tipos de datos Las conversiones de tipo de datos cambian una expresin de un tipo de datos a otro y vuelve a dar formato a la informacin de fecha y hora. SQL Server realiza determinadas conversiones de tipo de datos de forma automtica, que reciben el nombre de conversiones implcitas. Por ejemplo, si compara una expresin char y otra datetime , o una expresin smallint y otra int , o expresiones char de longitudes diferentes, SQL Server convierte automticamente un tipo de datos a otro. Otras conversiones de tipo de datos deben solicitarse de forma explcita, utilizando una de las funciones de conversin de tipos de datos incorporadas. Por ejemplo, antes de concatenar expresiones numricas, es necesario convertirlas a expresiones de caracteres. SQL Server proporciona tres funciones de conversin de tipos de datos, convert , inttohex y hextoint . Estas funciones pueden emplearse en la lista select , la clusula where y cualquier lugar donde se permita una expresin. SQL Server no permite convertir ciertos tipos de datos a otros tipos de datos, ni de forma implcita ni explcita. Por ejemplo, no se pueden convertir datos smallint a datetime , ni datos datetime a smallint . Las conversiones no admitidas generan mensajes de error. Conversiones soportadas La Figura 10-1: Conversiones de tipos de datos implcitas, explcitas y no soportadas resume las conversiones de tipos de datos soportadas por SQL Server:

Las conversiones marcadas como "I" se manipulan implcitamente y no requieren ninguna funcin de conversin de tipos de datos, aunque es posible utilizar la funcin convert en ellas sin error. Las conversiones marcadas como "E" deben realizarse explcitamente, con la funcin de conversin de tipo de datos adecuada . Las conversiones marcadas como "IE" se manipulan implcitamente cuando no existe una prdida de precisin o escala y la opcin arithabort numeric_truncation est activada, pero, en caso contrario, requieren una conversin explcita. Las conversiones marcadas como "U" no se soportan. Si intenta realizar una conversin de este tipo, SQL Server generar un mensaje de error. Las conversiones de un tipo en s mismo se marcan como "-" . En general, SQL Server no prohibe la conversin explcita de un tipo en s mismo, pero no tiene sentido. Figure 10-3: Conversiones de tipos de datos implcitas, explcitas y no soportadas

Uso de la funcin de conversin general: convert La funcin de conversin general, convert , se utiliza para realizar conversiones entre una amplia variedad de tipos de datos y especificar un nuevo formato de visualizacin para la informacin de fecha y hora. Su sintaxis es: convert( datatype, expression [, style ] )

A continuacin se muestra un ejemplo que emplea convert en la lista de seleccin: select title, convert(char(5), total_sales) from titles where type = "trad_cook" title ---------------------------------------Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean 125 Fifty Years in Buckingham Palace Kitchens 15096 Sushi, Anyone? 5405 (3 rows affected) En este ejemplo, la columna total_sales , una columna int , se convierte a una columna char (5) para que pueda utilizarse con la palabra clave like :

Page 170 of 280

select title, total_sales from titles where convert(char(5), total_sales) like "15%" and type = "trad_cook" title ------------------------------------Fifty Years in Buckingham Palace Kitchens 15096 (1 row affected) Algunos tipos de datos esperan una longitud o una precisin y escala. Si no especifica una longitud, SQL Server utiliza la longitud predeterminada 30 para los datos de caracteres y binarios. Si no especifica una precisin o escala, SQL Server utiliza los valores predeterminados 18 y 0, respectivamente. Reglas de conversin En las siguientes secciones se describen las reglas que SQL Server tiene en cuenta al convertir tipos diferentes de informacin: Conversin de datos de caracteres a un tipo de datos no de caracteres Los datos de caracteres pueden convertirse a un tipo de datos no de caracteres (como el monetario, fecha y hora, numrico exacto o numrico aproximado) si se componen totalmente de caracteres que son vlidos para el tipo nuevo. Los espacios en blanco iniciales se ignoran. Los errores de sintaxis se generan cuando los datos incluyen caracteres inaceptables. Los siguientes son algunos ejemplos de caracteres que pueden generar errores de sintaxis:

Comas o puntos decimales en datos de nmeros enteros Comas en datos monetarios Letras en datos numricos exactos o aproximados o datos de flujo de bits Nombres de meses mal escritos en datos de fecha y hora

Conversin de un tipo de caracteres a otro Al convertir de un juego de caracteres multibyte a otro de un solo byte, los caracteres sin un equivalente de un solo byte se convierten en espacios en blanco. Las columnas text pueden convertirse explcitamente a char, nchar , varchar o nvarchar . El lmite viene determinado por la longitud mxima de los tipos de datos de caracteres, 255 bytes. Si no especifica la longitud, el valor convertido tiene una longitud predeterminada de 30 bytes. Conversin de nmeros a un tipo de caracteres Los datos numricos exactos y aproximados pueden convertirse a un tipo de caracteres. Si el tipo nuevo es demasiado corto para albergar la cadena completa, se genera un error de espacio insuficiente. Por ejemplo, la siguiente conversin intenta almacenar una cadena de 5 caracteres en un tipo de 1 carcter: select convert(char(1), 12.34) Espacio de resultado insuficiente para la conversin explcita del valor NUMERIC '12.34' en un campo CHAR. Redondeo durante la conversin con tipos monetarios Los tipos money y smallmoney almacenan cuatro dgitos a la derecha del punto decimal, pero redondean hasta la centena ms prxima (.01) para fines de visualizacin. Cuando los datos se convierten a un tipo monetario, se redondean hasta cuatro posiciones. Si es posible, los datos convertidos de un tipo monetario siguen el mismo comportamiento de redondeo. Si el tipo nuevo es un numrico exacto con menos de tres posiciones decimales, los datos se redondean a la escala del tipo nuevo. Por ejemplo, cuando $4.50 se convierte a un valor entero, el resultado es 4: select convert(int, $4.50)
Page 171 of 280

----------4 Los datos convertidos a money o smallmoney se supone que estn en unidades monetarias completas, como dlares, en lugar de unidades fraccionarias, como cntimos. Por ejemplo, el valor entero 4 se convertira al equivalente monetario de 4 dlares, no 4 cntimos, en us_english. Conversin de informacin de fecha y hora Los datos que son reconocibles como una fecha pueden convertirse a datetime o smalldatetime . Los nombres de meses incorrectos provocan errores de sintaxis. Las fechas que se encuentran fuera del margen aceptable del tipo de datos generan errores de desbordamiento aritmtico. Cuando los valores datetime se convierten a smalldatetime , se redondean al minuto ms prximo. Conversin entre tipos numricos Los datos pueden convertirse de un tipo numrico a otro. Si el tipo nuevo es un numrico exacto cuya precisin o escala no es suficiente para albergar los datos, se pueden producir errores. Use las opciones arithabort y arithignore se para determinar el modo en que se manipulan estos errores. Note: Las opciones arithabort y arithignore se han redefinido para SQL Server, Versin 10.0. Si utiliza estas opciones en sus aplicaciones, examnelas para asegurarse de que todava funcionan correctamente. Conversin de datos de tipo binario Los datos binary y varbinary de SQL Server son especficos de la plataforma; el tipo de hardware que se utiliza determina el modo en que se almacenan e interpretan los datos. Algunas plataformas consideran el primer byte despus del prefijo 0x como el ms significativo; otras consideran el primer byte como el menos significativo. La funcin convert trata los datos binarios de Sybase como si fueran una cadena de caracteres, en lugar de informacin numrica. convert no tiene en cuenta la importancia del orden de los bytes al convertir una expresin binaria a un valor entero o una expresin de nmero entero a un valor binario. Debido a esto, los resultados de la conversin pueden variar de una plataforma a otra. Antes de convertir una cadena binaria a un nmero entero, convert elimina su prefijo 0x. Si la cadena se compone de un nmero de dgitos impar, SQL Server inserta un cero inicial. Si los datos son demasiado largos para el tipo entero, convert los trunca. Si los datos son demasiado cortos, convert los justifica a la derecha y los rellena con ceros. Supongamos que se quiere convertir la cadena 0x00000100 a un nmero entero. En algunas plataformas, esta cadena representa el nmero 1; en otras, el nmero 256. Dependiendo de la plataforma que ejecute la funcin, convert devuelve 1 o 256 en otras. Conversin de datos hexadecimales Para los resultados de conversin que son fiables a travs de plataformas, utilice las funciones hextoint e inttohex . hextoint acepta literales o variables que se componen de dgitos y las letras de la A a la F en maysculas y minsculas, con o sin un prefijo 0x. Estos son usos vlidos de hextoint : hextoint("0x00000100FFFFF") hextoint("0x00000100") hextoint("100") hextoint elimina el prefijo 0x. Si los datos superan los ocho dgitos, hextoint los trunca. Si los datos tienen menos de ocho dgitos, hextoint los justifica a la derecha y los rellena con ceros. A continuacin, hextoint devuelve el valor entero equivalente independiente de la plataforma. Las expresiones descritas anteriormente devuelven el mismo valor, 256, independientemente de la plataforma que ejecute la funcin hextoint . La funcin inttohex acepta datos de valor entero y devuelve una cadena hexadecimal de 8 caracteres sin prefijo 0x. inttohex siempre devuelve los mismos resultados, independientemente de la plataforma que se est utilizando.
Page 172 of 280

Conversin de datos image a binary o varbinary La funcin convert se puede utilizar para convertir una columna image a binary o varbinary . Los tipos de datos binary tienen una longitud mxima, que es de 255 bytes. Si no se especifica la longitud, el valor convertido tiene una longitud predeterminada de 30 caracteres. Errores de conversin En las siguientes secciones se describen los tipos de errores que pueden producirse durante las conversiones de tipos de datos. Errores de desbordamiento aritmtico y de divisin por cero Los errores de divisin por cero se producen cuando SQL Server intenta dividir un valor numrico por cero. Los errores de desbordamiento aritmtico se generan cuando las posiciones decimales del tipo nuevo no son suficientes para albergar los resultados. Esto ocurre durante:

Conversiones explcitas o implcitas a tipos exactos con una precisin o escala inferior. Conversiones de datos explcitas o implcitas que se encuentran fuera del margen aceptable para un tipo monetario o de fecha y hora. Conversiones de cadenas superiores a 4 bytes mediante hextoint.

Los errores de desbordamiento aritmtico y de divisin por cero se consideran graves, independientemente de que se produzcan durante conversiones implcitas o explcitas. Use la opcin arithabort arith_overflow para determinar el modo en que SQL Server manipula estos errores. El valor predeterminado, arithabort arith_overflow on , revierte toda la transaccin o lote donde se genera el error. Si define arithabort arith_overflow off , SQL Server aborta la instruccin que origina el error, pero contina procesando otras instrucciones de la transaccin o lote. Puede utilizar la variable global @@error para verificar los resultados de la instruccin. Utilice la opcin arithignore arith_overflow para determinar si SQL Server muestra un mensaje despus de estos errores. El valor predeterminado, off , muestra un mensaje de advertencia cuando se produce un error de divisin por cero o una prdida de precisin. La definicin de arithignore arith_overflow on suprime los mensajes de advertencia tras estos errores. La palabra clave arith_overflow puede omitirse sin efecto alguno. Errores de escala Cuando los resultados de una conversin explcita originan una prdida de escala, los resultados se truncan sin ninguna advertencia. Por ejemplo, cuando convierte explcitamente un tipo numrico float , numeric o decimal a un integer , SQL Server supone que en realidad desea que el resultado sea un nmero entero y trunca todos los nmeros a la derecha del punto decimal. Durante las conversiones implcitas a tipos numeric o decimal , la prdida de escala genera un error de escala. Use la opcin arithabort numeric_truncation para determinar la gravedad de un error de ese tipo. El valor predeterminado, arithabort numeric_truncation on , aborta la instruccin que origina el error, pero contina procesando otras instrucciones de la transaccin o lote. Si define arithabort numeric_truncation off , SQL Server trunca los resultados de la consulta y sigue procesando. Errores de dominio La funcin convert genera un error de dominio cuando el argumento de la funcin se encuentra fuera del margen sobre el que se define la funcin. Esto debera ocurrir con poca frecuencia. Conversiones entre tipos binary e integer Los tipos binary y varbinary almacenan datos de tipo hexadecimal que se componen de un prefijo 0x seguido de una cadena de dgitos y letras. Estas cadenas se interpretan de forma distinta en plataformas diferentes. Por ejemplo, la cadena 0x0000100 representa 65536 en las mquinas que consideran el byte 0 como el ms significativo y 256 en las mquinas que consideran el byte 0 como el menos significativo. La funcin convert y las conversiones implcitas Los tipos binarios pueden convertirse a valores enteros explcitamente, con la funcin convert , o implcitamente. Los datos pierden el prefijo 0x y despus se rellenan con ceros si son demasiado cortos para el tipo nuevo, o se truncan si son demasiado largos. convert y las conversiones de tipos de datos implcitas evalan los datos binarios de forma distinta en plataformas diferentes. Debido a esto, los resultados pueden variar de una plataforma a otra. Emplee la funcin hextoint para la conversin
Page 173 of 280

independiente de la plataforma de cadenas de caracteres hexadecimales a valores enteros y la funcin inttohex para la conversin independiente de la plataforma de valores enteros a valores hexadecimales. La funcin hextoint La funcin hextoint se utiliza para las conversiones independientes de la plataforma de datos hexadecimales a valores enteros. hextoint acepta una cadena hexadecimal vlida, con o sin un prefijo 0x, entre comillas, o el nombre de una columna de tipo de caracteres o variable. hextoin t devuelve el entero equivalente de la cadena hexadecimal. La funcin siempre devuelve el mismo entero equivalente para una cadena de caracteres hexadecimal dada, independientemente de la plataforma en la que se ejecute. La funcin inttohex La funcin inttohex se utiliza para conversiones independientes de la plataforma de valores enteros a cadenas hexadecimales. inttohex acepta cualquier expresin que d como resultado un nmero entero. La funcin siempre devuelve el mismo equivalente hexadecimal para una expresin dada, independientemente de la plataforma en la que se ejecute. Conversin de columnas image a tipos binary La funcin convert puede utilizarse para convertir una columna image a binary o varbinary . Los tipos de datos binary tienen una longitud mxima, que es de 255 bytes. Si no especifica la longitud, el valor convertido tiene una longitud predeterminada de 30 caracteres. Conversin de otros tipos de datos al tipo de bits Los tipos numricos exactos y aproximados pueden convertirse al tipo de bits de forma implcita. Los tipos de caracteres requieren una funcin convert explcita. La expresin objeto de la conversin debe componerse slo de dgitos, un punto decimal, un smbolo monetario y un signo de suma o resta. La presencia de otros caracteres genera errores de sintaxis. El equivalente bit de 0 es 0. El equivalente bit de cualquier otro nmero es 1. Cambio del formato de visualizacin de las fechas El parmetro style de convert proporciona una gran variedad de formatos de visualizacin de fechas al convertir datos datetime o smalldatetime a char o varchar . El argumento de nmero proporcionado como parmetro style determina el modo en que se muestran los datos. El ao puede presentarse en dos o cuatro dgitos. Para obtener un ao de 4 dgitos, incluido el siglo (yyyy), aada 100 a un valor style . A continuacin se muestra una tabla con los posibles valores de style y la variedad de formatos de fecha que puede utilizarse. Cuando utilice style con smalldatetime , los estilos que incluyen segundos o milisegundos mostrarn ceros en dichas posiciones. Tabla 10-11: Conversin de formatos de fecha con el parmetro style Sin siglo (yy) Con siglo (yyy0) Norma 1 2 3 4 5 6 7 8 10 11 12 0 o 100 101 2 103 104 105 106 107 108 9 o 109 110 111 112 EE.UU. Japn ISO Valor predeterminado EE.UU. Norma SQL Ingls/francs Alemn Salida

mon dd yyyy hh:mm AM (o PM) mm/dd/yy yy.mm.dd dd/mm/yy dd.mm.yy dd-mm-yy dd mon yy mon dd, yy hh:mm:ss

Valor predeterminado + milisegundos mon dd yyyy hh:mm:sss AM (o PM)

mm-dd-yy yy/mm/dd yymmdd

Los valores predeterminados, estilo 0 o 100, y 9 o 109, siempre devuelven el siglo (yyyy). A continuacin se muestra un ejemplo del uso del parmetro style de convert :
Page 174 of 280

select convert(char(12), getdate(), 3) Esto convierte la fecha actual al estilo ''3'', dd/mm/yy . Chapter 11

Creacin de ndices en tablas


Es posible crear uno o ms ndices en una tabla a fin de acelerar el proceso de recuperacin de datos. Los ndices son transparentes para los usuarios que acceden a los datos de esa tabla; SQL Server decide automticamente cundo usar los ndices creados para las tablas. En este captulo se trata lo siguiente:

Introduccin general a los ndices y algunas indicaciones sobre cundo deben usarse Creacin de ndices para una tabla Uso de ndices agrupados y no agrupados Especificacin de opciones de ndices Omisin de ndices Determinacin de los ndices que existen en una tabla

Definicin de ndice Los ndices ayudan a SQL Server a localizar datos. Aceleran el proceso de recuperacin de informacin indicando a SQL Server la posicin que ocupan los datos de una columna de tabla en el disco. Las tablas pueden tener ms de un ndice. Los ndices son transparentes para los usuarios. SQL no incluye ninguna sintaxis para hacer referencia a un ndice en una consulta. Slo es posible crear u omitir ndices de una tabla; SQL Server decide si usarlos o no para cada una de las consultas ejecutadas para esa tabla. A medida que los datos de una tabla van cambiando con el tiempo, SQL Server puede cambiar los ndices de la tabla de modo que reflejen esas modificaciones. Tambin estos cambios son transparentes para los usuarios, SQL Server lleva a cabo esta tarea por su cuenta. SQL Server admite los siguientes tipos de ndices:

Indices compuestos : estos ndices abarcan ms de una columna. Este tipo de ndice se usa cuando es ms conveniente buscar dos o ms columnas como unidad, debido a la relacin lgica existente entre ellas. Indices nicos : estos ndices no permiten que dos filas de las columnas especificadas tengan el mismo valor. SQL Server verifica si existen valores duplicados cuando se crea el ndice (si ya existen datos) y cada vez que se aaden datos. Indices agrupados o no agrupados : los ndices agrupados obligan a SQL Server a que ordene y vuelva a ordenar continuamente las filas de la tabla de modo que su orden fsico sea siempre el mismo que el orden lgico (o indexado). Slo se permite un ndice agrupado por tabla. Los ndices no agrupados no requieren que el orden fsico de las filas sea el mismo que el orden indexado. Todos los ndices no agrupados pueden proporcionar acceso a los datos con un criterio de ordenacin diferente.

Estos tipos de ndices se describen con mayor detalle ms adelante en este captulo. Comparacin de las dos formas de creacin de ndices Es posible crear ndices en las tablas usando la instruccin create index (descrita en este captulo), o bien usando las restricciones de integridad unique o primary key del comando create table . Sin embargo, estas restricciones de integridad estn limitadas de las siguientes formas:

No podr crear ndices no nicos. No podr usar las opciones proporcionadas por el comando create index para adaptar el funcionamiento de los ndices. Slo podr omitir estos ndices como una restriccin usando la instruccin alter table .

Si la aplicacin que usa requiere estas funciones, deber crear los ndices mediante create index . De lo contrario, las restricciones de integridad unique o primary key ofrecen una forma ms sencilla de definir un ndice para una tabla. Para
Page 175 of 280

obtener informacin sobre las restricciones unique y primary key , consulte el Captulo 7, "Creacin de bases de datos y tablas". Indicaciones para el uso de ndices Los ndices aceleran la recuperacin de datos. La inclusin de un ndice en una columna supone con frecuencia la diferencia entre una respuesta inmediata a una consulta y una larga espera. Si esto es as, sera lgico suponer que lo adecuado es incluir un ndice en cada columna. La razn ms importante por la que esto no es as, es que la construccin de un ndice lleva tiempo y ocupa espacio de almacenamiento. Por ejemplo, tenga en cuenta que los ndices no agrupados se vuelven a crear de forma automtica cuando un ndice agrupado se reconstruye. Otra razn es que la insercin, eliminacin o actualizacin de datos de columnas indexadas lleva ms tiempo que el precisado por las no indexadas. Sin embargo, este coste se ve compensado con creces gracias a la enorme mejora que supone el uso de ndices para el rendimiento de los procesos de recuperacin. A continuacin se indican algunas directrices sobre cundo utilizar ndices:

Si planea realizar inserciones manuales en la columna IDENTITY, cree un ndice nico a fin de garantizar que las inserciones no asignen un valor que ya se haya usado. Una columna a la que se acceda con frecuencia segn criterios de ordenacin, es decir, una especificada en la clusula order by , probablemente debera indexarse a fin de que SQL Server pudiera beneficiarse del orden indexado. Las columnas que se usan de forma regular en combinaciones siempre deberan indexarse, dado que el sistema puede llevar a cabo la combinacin con mayor rapidez si las columnas estn ordenadas segn criterios de ordenacin. La columna que almacena la clave primaria de la tabla tiene con frecuencia un ndice agrupado, especialmente si se combina a menudo con columnas de otras tablas (no olvide que slo hay un ndice agrupado por tabla). Una columna en la que se realizan bsquedas frecuentes de mrgenes de valores puede ser una opcin adecuada para la asignacin de un ndice agrupado. Una vez encontrada la fila con el primer valor del margen, se garantiza que las filas con los valores subsiguientes sern fsicamente adyacentes. Un ndice agrupado no ofrece ventajas tan importantes para las bsquedas sobre valores nicos.

Existen algunos casos en los que los ndices no son tiles:

Las columnas a las que casi nunca o nunca se hace referencia en las consultas no obtienen ninguna ventaja de los ndices, puesto que el sistema casi nunca o nunca tiene que buscar filas basndose en los valores de dichas columnas. Las columnas que slo tienen dos o tres valores, como varn y mujer, o s y no, tampoco se benefician de los ndices.

Si el sistema tiene que buscar en una columna no indexada, lo hace examinando las filas una a una. El tiempo que se tarda en llevar a cabo este tipo de barrido es directamente proporcional al nmero de filas de la tabla. Creacin de ndices para acelerar la recuperacin de datos Los ndices se crean en las columnas para acelerar la recuperacin de datos. El formato ms sencillo del comando create index es: create index index_name on table_name ( column_name

Para crear un ndice en la columna au_id de la tabla authors , el comando es el siguiente: create index au_id_ind on authors(au_id) El nombre del ndice debe cumplir con las reglas para identificadores. Los nombres de columna y tabla especifican la columna que se desea indexar y la tabla que la contiene. No es posible crear ndices en columnas que tienen los tipos de datos bit , text o image .

Page 176 of 280

Es necesario ser el propietario de una tabla para poder ejecutar create o drop a fin de crear u omitir un ndice. El propietario de una tabla puede crear u omitir un ndice en cualquier momento, independientemente de que haya datos en la tabla. Es posible crear ndices en tablas de otra base de datos calificando el nombre de la tabla. Sintaxis de create index La sintaxis completa del comando create index es: create [unique] [clustered | nonclustered] index index_name on [[ database .] owner .] table_name ( [, column_name ]...) [with {{fillfactor | max_rows_per_page}= x, ignore_dup_key, sorted_data, [ignore_dup_row | allow_dup_row]}] [on segment_name ]

column_name

En los siguientes apartados se explican las diversas opciones del comando create index . Note: La extensin on segment_name de create index permite colocar el ndice en un segmento que apunte a un dispositivo de bases de datos especfico o a un conjunto de dispositivos de bases de datos. Antes de crear un ndice en un segmento, consulte al administrador del sistema o al propietario de la base de datos a fin de obtener una lista de los segmentos que puede utilizar. Algunos segmentos pueden estar asignados a tablas o ndices especficos por razones de rendimiento, o por otras consideraciones. Indexacin de ms de una columna: ndices compuestos Es necesario especificar uno o ms nombres de columna si se desea crear un ndice compuesto sobre los valores combinados de todas las columnas especificadas. Los ndices compuestos se usan cuando es conveniente buscar dos o ms columnas como una unidad. Por ejemplo, la tabla friends_etc tiene un ndice compuesto en pname y sname . Ponga todas las columnas que deben incluirse en el ndice compuesto segn los criterios de ordenacin dentro del parntesis despus del nombre de la tabla, como a continuacin: create index nmind on friends_etc(pname, sname) Las columnas de un ndice compuesto no tienen que estar en el mismo orden que las columnas de la instruccin create table . El orden de pname y sname se puede invertir en la instruccin de creacin de ndices anterior. Es posible combinar hasta 16 columnas en un mismo ndice compuesto. Todas las columnas de un ndice compuesto deben estar en la misma tabla. El tamao mximo permitido de los valores de ndice combinados es de 256 bytes. Es decir, la suma de las longitudes de las columnas que componen el ndice compuesto no puede exceder de 256. Es posible especificar dos o ms nombres de columna al crear un ndice. Estas columnas, junto con la columna sensitivity , forman un ndice compuesto de los valores combinados de las columnas. Los ndices compuestos se emplean cuando es conveniente buscar dos o ms columnas como una unidad. Por ejemplo, la tabla friends_etc tiene un ndice compuesto en pname , sname y sensitivity (aadida de forma automtica por SQL Server). Cuando especifique las columnas en la instruccin create index , ponga todas las columnas que deben incluirse en el ndice compuesto, salvo sensitivity , entre parntesis segn los criterios de ordenacin despus del nombre de la tabla, como a continuacin: create index nmind on friends_etc(pname, sname) Las columnas de un ndice compuesto no tienen que estar en el mismo orden que las columnas de la instruccin create table . El orden de pname y sname podra invertirse en la instruccin de creacin de ndices anterior. SQL Server siempre aade sensitivity como la ltima columna de cada ndice. Uso de la opcin unique Un ndice nico es aqul en el que no se permite que dos filas tengan el mismo valor de ndice, incluido el valor NULL. El sistema verifica la existencia de valores duplicados cuando el ndice se crea, si ya existen datos, y realiza esta verificacin cada vez que se aaden o modifican datos con una instruccin insert o update .
Page 177 of 280

La especificacin de un ndice nico slo es til cuando la unicidad es una caracterstica de los datos propiamente dichos. Por ejemplo, no es conveniente asignar un ndice nico a una columna last_name (de apellidos), puesto que es probable que haya ms de un "Smith" o "Wong" en tablas incluso de algunos centenares de filas. Sin embargo, s es adecuado asignar un ndice nico a la columna que contiene los nmeros de la seguridad social. En este caso, la unicidad es una caracterstica propia de los datos, puesto que cada persona tiene un nmero de seguridad social diferente. Adems, un ndice nico puede hacer las veces de una verificacin de integridad. Por ejemplo, la existencia de un nmero de seguridad social duplicado refleja con toda probabilidad un error en la introduccin de los datos o por parte de la administracin pblica. Si intenta crear un ndice nico en datos existentes que incluyen valores duplicados, el comando se aborta y SQL Server muestra un mensaje de error que indica el primer duplicado. No es posible crear un ndice nico en una columna que contiene valores nulos en ms de una fila; stos se consideran valores duplicados para fines de indexacin. Si intenta modificar datos que tienen asignado un ndice nico, el resultado depende de si ha usado la opcin ignore_dup_key . Consulte la seccin dedicada a las opciones de ndices ms adelante en este captulo. Es posible usar la palabra clave unique en ndices compuestos. Esto no se ha llevado a cabo para el ndice friends_etc creado anteriormente. Inclusin de columnas IDENTITY en ndices no nicos La opcin identity in nonunique index incluye de forma automtica una columna IDENTITY en las claves de ndice de una tabla para que todos los ndices creados en la tabla sean nicos. Esta opcin de base de datos hace que los ndices lgicamente no nicos sean nicos internamente y permite usarlos para procesar cursores actualizables y lecturas de nivel de aislamiento 0. La tabla ya debe contener una columna IDENTITY para que la opcin de base de datos identity in nonunique index funcione, ya sea por una instruccin create table o al definir la opcin de base de datos auto identity como true antes de crear la tabla. Use identity in nonunique index si planea utilizar cursores y lecturas de nivel de aislamiento 0 en tablas con ndices no nicos. El ndice nico hace que el cursor se coloque en la fila correcta la siguiente vez que se efecta una operacin fetch con dicho cursor. Uso de las opciones fillfactor y max_rows_per_page Casi nunca es necesario incluir las opciones fillfactor o max_rows_per_page en la instruccin create index . Estas opciones se proporcionan para mejorar el rendimiento y slo son tiles cuando se crea un nuevo ndice sobre datos existentes.

fillfactor
Con la opcin fillfactor , el usuario puede especificar en qu medida debe llenar SQL Server cada pgina de ndice. La cantidad de espacio libre en una pgina de ndice se debe controlar porque cuando una pgina de ndice se llena una vez que se han aadido suficientes filas, el sistema debe emplear algn tiempo en dividirla a fin de dejar espacio para nuevas filas. El valor predeterminado es 0, que es el valor que se usa cuando no se especifica ningn factor de llenado. El administrador del sistema puede cambiar el valor predeterminado con el procedimiento del sistema sp_configure . Consulte la Gua de Administracin del Sistema para obtener ms informacin sobre fillfactor . Los valores vlidos de fillfactor especificados por el usuario estn entre 1 y 100. A continuacin se muestra una instruccin create index que usa la opcin fillfactor : create index postalcode_ind on friends_etc(postalcode) with fillfactor = 100 Un valor fillfactor de 100 llena completamente todas las pginas y slo es til cuando se sabe de antemano que nunca va a cambiar ninguno de los valores de ndice de la tabla.

max_rows_per_page
Page 178 of 280

La opcin max_rows_per_page limita el nmero de filas que SQL Server puede incluir en cada pgina de ndice. Un valor max_rows_per_page bajo reduce la contienda de bloqueo y slo resulta til para las tablas a las que se accede con frecuencia. Los valores bajos tambin hacen que el ndice ocupe espacio. El valor predeterminado es 0, que se emplea cuando no se especifica un valor mximo. El usuario puede cambiar el valor con el procedimiento del sistema sp_relimit . Los valores max_rows_per_page especificados por el usuario estn entre 1 y 256. La siguientes instruccin create index utiliza la opcin max_rows_per_page : create index postalcode_ind on friends_etc(postalcode) with max_rows_per_page = 10 Uso de ndices agrupados o no agrupados Con un ndice agrupado, SQL Server ordena las filas de forma continuada de modo que su orden fsico sea el mismo que el orden lgico, es decir, el indexado. El nivel inferior o de hoja de un ndice agrupado contiene las pginas de datos reales de la tabla. Los ndices agrupados deben crearse antes que los no agrupados, ya que estos ltimos se reconstruyen automticamente cuando se crea un ndice agrupado. Por definicin, slo puede haber un ndice agrupado por tabla. Este se crea a menudo en la clave primaria , es decir, la columna o columnas que identifican la fila de forma nica. Lgicamente, una clave primaria viene determinada por el diseo de la base de datos. Sin embargo, es posible definir de forma explcita las claves primarias, las claves externas y las claves comunes (pares de claves que se combinan con frecuencia) con los procedimientos del sistema sp_primarykey , sp_foreignkey y sp_commonkey . Puede mostrar informacin sobre las claves y sobre las columnas que son probables candidatos de combinacin mediante sp_helpkey y sp_helpjoins , respectivamente. Como alternativa, es posible especificar restricciones primary key con las instrucciones create table o alter table a fin de crear un ndice e imponer los atributos de clave primaria para las columnas de la tabla. Para mostrar informacin sobre las restricciones, utilice sp_helpconstraint . Para obtener una definicin de las claves primarias y externas, consulte el Captulo 15, "Disparadores: imposicin de la integridad de referencia". Para obtener informacin completa sobre los procedimientos del sistema, consulte el Manual de

Referencia de SQL Server.

Con un ndice no agrupado, el orden fsico de las filas no es el mismo que el indexado. El nivel de hoja de un ndice no agrupado contiene punteros hacia las filas de las pginas de datos. Ms concretamente, cada pgina hoja contiene un valor indexado y un puntero hacia la fila que contiene dicho valor. En otras palabras, un ndice no agrupado tiene un nivel adicional entre la estructura de ndice y los datos propiamente dichos. Cada uno de los hasta 249 ndices no agrupados permitidos en una tabla puede proporcionar acceso a los datos segn un criterio de ordenacin distinto. La bsqueda de datos mediante un ndice agrupado es casi siempre ms rpido que mediante un ndice no agrupado. Adems, los ndices agrupados suponen una ventaja cuando se recuperan muchas filas con valores clave contiguos, es decir, en las columnas donde se efectan bsquedas frecuentes de mrgenes de valores. Una vez que se encuentra la fila con el primer valor clave , se garantiza que las filas con valores indexados subsiguientes sern fsicamente adyacentes, y no ser necesaria ninguna bsqueda adicional. Si no se usa la palabra clave clustered ni la palabra clave nonclustered , se crea un ndice no agrupado. A continuacin se muestra la forma de crear el ndice de la columna title_id de la tabla titles (si desea ejecutar este comando, primero debe omitir el ndice con drop index ): create clustered index titleidind on titles(title_id) Puesto que piensa que ser necesario ordenar con frecuencia las personas de la tabla friends_etc segn su cdigo postal, debera crear un ndice no agrupado en la columna postalcode de la siguiente manera:
Page 179 of 280

create nonclustered index postalcodeind on friends_etc(postalcode) Un ndice nico no tendra ningn sentido en este caso, puesto que es probable que algunos de sus contactos tengan el mismo cdigo postal. Un ndice agrupado no sera adecuado tampoco, puesto que el cdigo postal no es la clave primaria. El ndice agrupado de friends_etc debera ser un ndice compuesto sobre las columnas de nombre y apellidos. Para crear este ndice agrupado, primero omita el ndice no agrupado nmind : drop index friends_etc.nmind Y luego cree el ndice agrupado: create clustered index nmind on friends_etc(pname, sname) Note: Dado que el nivel inferior (o de hoja) de un ndice agrupado y sus pginas de datos son iguales por definicin, la creacin de un ndice agrupado ( clustered ) y el uso de la extensin on segment_name traslada efectivamente la tabla desde el dispositivo donde se cre hasta el segmento indicado. Consulte al administrador del sistema o al propietario de la base de datos antes de crear tablas o ndices en los segmentos; algunos segmentos pueden estar reservados por razones de rendimiento. Especificacin de opciones de ndices Las opciones de ndices ignore_dup_key, ignore_dup_row y allow_dup_row controlan lo que ocurre cuando se crea una clave o fila duplicada con insert o update . A continuacin se muestra una tabla que indica cundo se deben usar estas opciones de ndices: Tabla 11-1: Opciones de ndices Tipo de ndice Agrupado Agrupado nico No agrupado Opciones ignore_dup_row | allow_dup_row ignore_dup_key Ninguna

No agrupado nico ignore_dup_key No agrupado nico ignore_dup_row Uso de la opcin ignore_dup_key Si intenta insertar un valor duplicado en una columna que tiene un ndice nico, el comando se cancela. Es posible evitar que se cancele una transaccin grande incluyendo la opcin ignore_dup_key con un ndice unique . El ndice unique puede ser agrupado o no agrupado. Cuando se comienza la introduccin de datos, cada intento de insercin de una clave duplicada se cancela, con un mensaje de error. Las claves no duplicadas se insertan de la forma habitual. Note: Si intenta ejecutar una instruccin update que crea una clave duplicada, la actualizacin se cancela. Tras la cancelacin, todas las transacciones que estaban activas en ese momento pueden continuar como si la actualizacin con update no hubiese tenido lugar. No se puede crear un ndice nico en una columna que ya incluye valores duplicados, independientemente de que ignore_dup_key est definida. Si lo intenta, SQL Server imprime un mensaje de error y una lista de valores duplicados. Hay que eliminar los duplicados antes de crear un ndice nico en la columna. A continuacin se muestra un ejemplo del uso de la opcin ignore_dup_key : create unique clustered index phone_ind on friends_etc(phone) with ignore_dup_key Uso de las opciones ignore_dup_row y allow_dup_row
Page 180 of 280

ignore_dup_row y allow_dup_row son opciones para la creacin de un ndice agrupado y no nico. Estas opciones no son relevantes al crear un ndice no agrupado y no nico. Puesto que un ndice no agrupado de SQL Server anexa internamente un nmero de identificacin de fila nico, no es necesario preocuparse por las filas duplicadas, ni siquiera por los valores de datos idnticos. ignore_dup_row y allow_dup_row se excluyen mutuamente. Si se define allow_dup_row , es posible crear un ndice nuevo no nico y agrupado en una tabla que incluye filas duplicadas y, a continuacin, crear filas duplicadas subsiguientes con insert o update . Si alguno de los ndices de la tabla es nico, el requisito de unicidad, que es el requisito ms restrictivo, prevalece sobre la opcin allow_dup_row . Por tanto, allow_dup_row slo se aplica a tablas con ndices no nicos. No puede usar esta palabra clave si hay un ndice agrupado nico en alguna de las columnas de la tabla. La opcin ignore_dup_row se utiliza para eliminar los duplicados de un lote de datos. Cuando se introduce una fila duplicada, esta fila se ignora y el comando insert en cuestin se cancela, con un mensaje de error informativo. Las filas no duplicadas se insertan de la forma habitual. La opcin ignore_dup_row se aplica slo a las tablas con ndices no nicos: no puede usar esta palabra clave si hay un ndice nico en alguna de las columnas de la tabla. Note: Si intenta ejecutar una instruccin update que cree una fila duplicada, la actualizacin se cancelar. Tras la cancelacin, las transacciones que estaban activas en ese momento pueden continuar como si la actualizacin no hubiese tenido lugar. Esta tabla ilustra la forma en que allow_dup_row y ignore_dup_row afectan a los intentos de creacin de un ndice agrupado no nico en una tabla que incluye filas duplicadas y a los intentos de introduccin de filas duplicadas en una tabla. Tabla 11-2: Opciones de filas duplicadas en ndices Opcin Ninguna opcin definida allow_dup_row definida ignore_dup_row<Default Para Font> definida Duplicados existentes El comando create index no se ejecuta de forma correcta. El comando se ejecuta de forma correcta. Se crea el ndice, pero las filas duplicadas se eliminan; mensaje de error. Introduccin de duplicados El comando de introduccin de filas duplicadas no se ejecuta de forma correcta. El comando se ejecuta de forma correcta. Se aceptan todas las filas, excepto las duplicadas; mensaje de error. Consulte la advertencia anterior.

Uso de la opcin sorted_data La opcin sorted_data acelera la creacin de un ndice cuando los datos de la tabla ya estn clasificados segn criterios de ordenacin, por ejemplo, cuando se ha usado bcp para copiar datos que ya se han ordenado en una tabla vaca. La velocidad aumenta de forma considerable en las tablas de gran tamao y es varias veces superior en las tablas de ms de un gigabyte. Esta opcin puede utilizarse con cualquier otra opcin create index sin ningn efecto sobre su funcionamiento. Si se especifica sorted_data , pero los datos no estn ordenados, aparece un mensaje de error y el comando se aborta. Esta opcin agiliza la creacin de ndices slo para ndices agrupados o ndices no agrupados nicos. Sin embargo, la creacin de un ndice no agrupado y no nico tendr xito siempre que no haya filas con claves duplicadas. Si existen filas con claves duplicadas, aparece un mensaje de error y el comando se aborta. Uso de la opcin on segment_name La clusula on segment_name permite especificar el nombre del segmento de base de datos donde debe crearse el ndice. Es posible crear un ndice no agrupado en un segmento distinto del de las pginas de datos. Por ejemplo: create index titleind on titles(title) on seg1 Omisin de ndices
Page 181 of 280

El comando drop index se usa para quitar un ndice de la base de datos. Su sintaxis es: drop index table_name . index_name [, table_name . index_name ]... Cuando se ejecuta este comando, SQL Server quita los ndices especificados de la base de datos, dejando libre el espacio de almacenamiento. Slo el propietario del ndice puede omitirlo. El permiso drop index no puede transferirse a otros usuarios. El comando drop index no puede usarse en ninguna de las tablas del sistema de la base de datos master ni en la base de datos de usuario. Es posible que quiera omitir un ndice si no se usa en la mayora de las consultas o en ninguna. Para omitir el ndice phone_ind de la tabla friends_etc , el comando es: drop index friends_etc.phone_ind Determinacin de los ndices que existen en una tabla Para ver los ndices que existen en una tabla, es posible usar el procedimiento del sistema sp_helpindex . A continuacin se muestra un informe sobre la tabla friends_etc : sp_helpindex friends_etc index_name index_description -------------- ---------------------------nmind clustered located on default postalcode_ind nonclustered located on default postalcodeind nonclustered located on default

index_keys ------------pname, sname postalcode postalcode

(3 rows affected, return status = 0) sp_help tambin informa sobre los ndices de una tabla. Actualizacin de estadsticas sobre los ndices El comando update statistics ayuda a SQL Server a tomar las mejores decisiones sobre qu ndices debe usar cuando procesa una consulta, proporcionndole informacin actualizada sobre la distribucin de los valores clave de los ndices. Este comando debe utilizarse cuando se han aadido, modificado o eliminado grandes cantidades de datos de una columna indexada. El permiso para ejecutar el comando update statistics est asignado de forma predeterminada al propietario de la tabla, y no es transferible. Su sintaxis es: update statistics table_name [ index_name ]

Si no se especifica un nombre de ndice, el comando actualiza las estadsticas de distribucin de todos los ndices de la tabla indicada. Si se especifica el nombre de un ndice, slo se actualizan las estadsticas de ese ndice. Se pueden buscar los nombres de los ndices con el procedimiento del sistema sp_helpindex . Este procedimiento toma como parmetro un nombre de tabla. A continuacin se muestra cmo enumerar los ndices de la tabla authors : sp_helpindex authors index_name index_description ---------- ----------------auidind clustered, unique aunmind nonclustered (2 rows affected) index_keys -----------------au_id au_lname, au_fname

Page 182 of 280

Para actualizar las estadsticas de todos los ndices, escriba: update statistics authors Para actualizar las estadsticas slo del ndice de la columna au_id , escriba: update statistics authors auidind Dado que Transact-SQL no requiere que los nombres de ndice sean nicos en una base de datos, se debe indicar el nombre de la tabla a la que est asociado el ndice. SQL Server ejecuta update statistics de forma automtica cuando se crea un ndice en los datos existentes. Chapter 12

Definicin de valores predeterminados y reglas para datos


Es posible definir un valor predeterminado para una columna de tabla o un tipo de datos definido por el usuario que inserte un valor automticamente si no se introduce explcitamente un valor para dicha columna o tipo de datos. Tambin es posible definir reglas para esa columna de tabla o tipo de datos a fin de restringir los tipos de valores que pueden insertarse en ellos. En este captulo se trata lo siguiente:

Introduccin general a los valores predeterminados y las reglas Creacin y omisin de valores predeterminados Efecto de los valores predeterminados sobre los valores nulos Creacin y omisin de reglas Obtencin de informacin sobre valores predeterminados y reglas Definicin de valor predeterminado y de regla Creacin de valores predeterminados Omisin de valores predeterminados Efecto de los valores predeterminados sobre los valores nulos Creacin de reglas Omisin de reglas Obtencin de informacin sobre valores predeterminados y reglas

Definicin de valor predeterminado y de regla Un valor predeterminado es un valor que SQL Server inserta en una columna cuando el usuario no introduce uno explcitamente. En el campo de la administracin de bases de datos, una regla especifica lo que est o no est permitido introducir en una columna concreta o en las columnas con un tipo de datos definido por el usuario. Los valores predeterminados y las reglas pueden usarse para mantener la integridad de los datos en toda la base de datos. En un sistema de administracin de bases de datos relacionales, todos los elementos de datos, es decir, cada columna determinada de cada fila concreta, deben contener algn valor, incluso aunque ste sea NULL (nulo). Tal como se describe en el Captulo 7, "Creacin de bases de datos y tablas", algunas columnas no aceptan el valor nulo. En estos casos, es necesario insertar otro valor, ya sea un valor introducido por el usuario de forma explcita o un valor predeterminado introducido por SQL Server. Los valores predeterminados permiten especificar un valor que SQL Server deber insertar en caso de que no se introduzca ningn valor explcito en una columna NULL o NOT NULL. Por ejemplo, puede crear un valor predeterminado que tenga el valor "???" o el valor "fill in later" ("llenar ms tarde"). Las reglas imponen la integridad de los datos mediante sistemas cubiertos no slo por el tipo de datos de una columna. Las reglas se pueden conectar a una columna especfica, a varias columnas especficas o a un tipo de datos definido por el usuario concreto. Cada vez que un usuario introduce un valor con una instruccin insert o update , SQL Server lo compara con la ltima regla vinculada a la columna en cuestin. Los datos introducidos antes de la creacin y vinculacin de una regla no se verifican.
Page 183 of 280

Note: Es posible vincular una regla de tipo de caracteres a una columna de tipo numrico, aunque no tenga ningn sentido hacerlo. Las reglas se contrastan cuando se intenta ejecutar una instruccin insert o update , no en el momento de vincularlas. En este captulo se explica cmo crear valores predeterminados y reglas mediante create default y create rule , y cmo asociar valores predeterminados y reglas a una columna o a un tipo de datos definido por el usuario mediante los procedimientos del sistema sp_bindefault , sp_bindrule , sp_unbindefault y sp_unbindrule . Comparacin de valores predeterminados y reglas con restricciones de integridad Como alternativa al uso de valores predeterminados y reglas, es posible usar la clusula default y la restriccin de integridad check de la instruccin create table para llevar a cabo algunas de las mismas tareas. Sin embargo, dichos elementos son especficos a esa tabla y no pueden vincularse a columnas de otras tablas ni a tipos de datos definidos por el usuario. Para obtener ms informacin acerca de las restricciones de integridad, consulte el Captulo 7, "Creacin de bases de datos y tablas". Creacin de valores predeterminados Es posible crear y omitir valores predeterminados en cualquier momento, antes o despus de haber introducido los datos en una tabla. Cree un valor predeterminado con el comando create default y omtalo con el comando drop default . Un valor predeterminado puede conectarse a una columna en particular, a varias columnas o a todas las columnas de la base de datos que tengan un tipo de datos definido por el usuario determinado. Utilice el procedimiento del sistema sp_bindefault para asociar un valor predeterminado a una columna o tipo de datos definido por el usuario. Quite la asociacin mediante sp_unbindefault . A continuacin se muestran algunos puntos que hay que comprobar al crear y vincular valores predeterminados:

Cercirese de que el tamao de la columna es suficiente para el valor predeterminado. Una columna char (2) no puede contener una cadena de caracteres de 17 bytes como "Nobody knows yet". Tenga cuidado cuando introduzca valores predeterminados distintos en un tipo de datos definido por el usuario y en una columna individual de dicho tipo. Si vincula primero el valor predeterminado del tipo de datos y luego el de la columna, este ltimo sustituye al valor predeterminado del tipo de datos definido por el usuario nicamente para la columna indicada. El valor predeterminado del tipo de datos definido por el usuario se vincula a todas las dems columnas que tengan ese tipo de datos. Sin embargo, una vez vinculado otro valor predeterminado a una columna que tena un valor predeterminado asociado a su tipo, la columna deja de estar bajo la influencia de los valores predeterminados vinculados a su tipo de datos. Este tema se trata con mayor detalle ms adelante en este captulo. Est atento a los conflictos que puedan producirse entre los valores predeterminados y las reglas. Cercirese de que la regla permite el valor predeterminado, ya que, de lo contrario, la regla podra eliminarlo. Si una regla permite entradas entre 1 y 100, por ejemplo, y el valor predeterminado est definido en 0, la regla har que el valor predeterminado se rechace cada vez que se intente insertar y el resultado ser un error, a no ser que la columna acepte valores NULL, en cuyo caso se introducir NULL. Ser necesario cambiar el valor predeterminado o la regla.

Sintaxis de create default La sintaxis del comando create default es: create default [ owner .] as constant_expression default_name

Los valores predeterminados deben cumplir las reglas para identificadores. Slo es posible crear valores predeterminados en la base de datos actual. Dentro de una base de datos, los nombres de los valores predeterminados deben ser nicos para cada usuario. No puede crear dos valores predeterminados con el nombre phonedflt . Sin embargo, como usuario "invitado", puede crear un valor predeterminado phonedflt aunque dbo. phonedflt ya exista porque los nombres de los propietarios los diferencian entre s. A continuacin se indica cmo crear el valor predeterminado "Oakland" para usarlo con la columna city de la tabla friends_etc (la tabla cuya creacin se trat en el Captulo 7, "Creacin de bases de datos y tablas") y posiblemente con otras columnas o tipos de datos de usuario. Mientras sigue este ejemplo, puede usar cualquier nombre de ciudad que resulte til para la distribucin demogrfica de las personas que tenga previsto introducir en su tabla personal. Para crear el valor predeterminado:

Page 184 of 280

create default citydflt as "Oakland" Despus de as puede usar cualquier constante. Las constantes de caracteres y de fecha deben incluirse entre comillas; las constantes de tipo monetario, de nmeros enteros y de punto flotante no las requieren. Los datos binarios deben ir precedidos de 0x y los datos monetarios, de un smbolo de dlar ($). El valor predeterminado tiene que ser compatible con el tipo de datos de la columna. No puede usar "ninguno", por ejemplo, como valor predeterminado para una columna numrica, pero 0 (cero) s es adecuado. Si especifica NOT NULL al crear una columna y no asocia un valor predeterminado a esa columna, SQL Server generar un mensaje de error siempre que alguien olvide introducir una entrada en dicha columna. Con frecuencia, los valores predeterminados se generan al crear la tabla. Sin embargo, en una sesin en la que desee introducir mltiples filas con los mismos valores en una o ms columnas, puede ser conveniente crear un valor predeterminado especial para dicha sesin antes de comenzar. Vinculacin de valores predeterminados Una vez creado un valor predeterminado, utilice el procedimiento del sistema sp_bindefault para vincular el valor a una columna o un tipo de datos definido por el usuario. create default phonedflt as "UNKNOWN" Se ha definido un valor predeterminado. Ahora es necesario vincularlo a la columna o tipo de datos definido por el usuario adecuados con el procedimiento del sistema sp_bindefault . sp_bindefault phonedflt, "authors.phone" El valor predeterminado tendr efecto slo si no hay ninguna entrada en la columna phone de la tabla authors . No introducir ninguna entrada es distinto de insertar un valor nulo. Note: Para obtener el valor predeterminado, debe ejecutar un comando insert o update con una lista de columnas que no incluya la columna con el valor predeterminado. El valor predeterminado slo se aplica a las filas nuevas y no cambia de forma retroactiva las filas existentes. Lgicamente, dicho valor slo tiene efecto cuando no se realiza ninguna entrada. Si el usuario suministra un valor para la columna, aunque sea NULL, el valor predeterminado no tiene ningn efecto. A continuacin se muestra cmo vincular citydflt a la columna city de friends_etc : sp_bindefault citydflt, "friends_etc.city" Observe que el nombre de la tabla y la columna estn entre comillas debido a la puntuacin incrustada, es decir, el punto. Note: No es posible vincular un valor predeterminado a un tipo de datos del sistema, porque el objeto de destino sera demasiado extenso. Tampoco se puede vincular un valor predeterminado a una columna timestamp , porque SQL Server genera valores para columnas de este tipo. Es posible vincular un valor predeterminado a la columna IDENTITY o a un tipo de datos definido por el usuario con la propiedad IDENTITY, pero estos valores predeterminados se ignoran. Cada vez que se inserta una fila en una tabla sin especificar un valor para la columna IDENTITY, SQL Server asigna un valor mayor en una unidad que el ltimo valor asignado. Si crea un tipo de datos especial para todas las columnas de ciudades de todas las tablas de la base de datos, puede vincular citydflt al tipo de datos con la completa seguridad de que "Oakland" aparecer slo en los casos en que sea apropiado un nombre de ciudad. Por ejemplo, si el tipo de datos se llama citytype , a continuacin se indica cmo se vinculara citydflt al mismo: sp_bindefault citydflt, citytype El parmetro futureonly puede usarse cuando se vincula un valor predeterminado a un tipo de datos de usuario. Este parmetro evita que las columnas existentes de ese tipo de datos de usuario hereden el nuevo valor predeterminado. Nunca se utiliza cuando se vincula un valor predeterminado a una columna. A continuacin se indica cmo crear y vincular el nuevo valor
Page 185 of 280

predeterminado "Berkeley" al tipo de datos citytype para su uso slo en las columnas de tabla nuevas. "Oakland" seguir apareciendo como valor predeterminado para todas las columnas de tabla existentes que usen citytype . create default newcitydflt as "Berkeley" sp_bindefault newcitydflt, citytype, futureonly Si la mayor parte de las personas de la tabla viven en la misma zona de cdigo postal, puede crear un valor predeterminado para ahorrar tiempo de introduccin de datos. A continuacin se indica uno adecuado para una seccin de Oakland, junto con su vinculacin: create default zipdflt as "94609" sp_bindefault zipdflt, "friends_etc.postalcode" Esta es la sintaxis completa del procedimiento del sistema sp_bindefault : sp_bindefault defname, objname [, futureonly]

defname es el nombre del valor predeterminado creado con create default . objname es el nombre de la tabla y la columna, o
del tipo de datos definido por el usuario, a la que debe vincularse el valor predeterminado. Si el parmetro no tiene el formato table . column , el sistema supone que se trata de un tipo de datos definido por el usuario.

Todas las columnas de un tipo de datos definido por el usuario especificado quedan asociadas al valor predeterminado indicado, a no ser que:

Utilice el tercer parmetro opcional, futureonly , que evita que las columnas existentes de ese tipo de datos de usuario hereden el valor predeterminado; o bien El valor predeterminado de la columna se haya cambiado previamente, en cuyo caso se mantiene el valor predeterminado original.

Los valores predeterminados vinculados a las columnas siempre tienen precedencia sobre los valores vinculados a los tipos de datos de usuario. Al vincular un valor predeterminado a una columna, se sustituir el valor predeterminado vinculado al tipo de datos definido por el usuario de dicha columna, pero si se vincula un valor predeterminado a un tipo de datos, no se sustituye el valor predeterminado de una regla de una columna correspondiente al tipo de datos de que se trate definido por el usuario. En la siguiente tabla se indica la precedencia cuando se vinculan valores predeterminados a columnas y tipos de datos definidos por el usuario para los que ya existen valores predeterminados: Tabla 12-1: Precedencia de valores predeterminados Valor predeterminado nuevo vinculado a: Valor predeterminado antiguo vinculado a: Tipo de datos de usuario Tipo de datos de usuario Column a Sustituye al valor predeterminado antiguo. Sustituye al valor predeterminado antiguo. Column a Ningn cambio; valor predeterminado antiguo. Sustituye al valor predeterminado antiguo.

Las columnas existentes del tipo de datos definido por el usuario heredan el nuevo valor predeterminado, a no ser que su valor predeterminado se haya cambiado previamente o que el valor del tercer parmetro opcional sea futureonly . Las columnas nuevas del tipo de datos definido por el usuario siempre heredan el valor predeterminado. Por ejemplo, supongamos que se crea una tabla llamada foes con una columna llamada city del tipo citytype , que es un tipo de datos definido por el usuario. Inicialmente, el tipo de datos definido por el usuario citytype no tiene ningn valor predeterminado. Tras crearse un valor predeterminado llamado citydflt , se vincula a la columna foes.city . Luego se vincula otro valor predeterminado, newcitydflt , al tipo de datos definido por el usuario citytype . Aunque foes.city es una columna citytype , el nuevo valor predeterminado no se vincula a ella, puesto que se ha cambiado previamente. Note: No es posible vincular valores predeterminados a columnas y usarlos durante el mismo lote. sp_bindefault no puede estar en el mismo lote que las instrucciones insert que ejecutan el valor predeterminado. Desvinculacin de valores predeterminados

Page 186 of 280

Desvincular un valor predeterminado significa desconectarlo de una columna o tipo de datos definido por el usuario en particular. Un valor predeterminado desvinculado sigue estando almacenado en la base de datos y est disponible para su uso en el futuro. Utilice el procedimiento del sistema sp_unbindefault para quitar la vinculacin entre un valor predeterminado y una columna o tipo de datos. A continuacin se indica cmo desvincular el valor predeterminado actual de la columna city de la tabla friends_etc : execute sp_unbindefault "friends_etc.city" Ahora el valor predeterminado an existe, pero no tiene ningn efecto sobre la columna city porque no est conectado a la misma. Para desvincular un valor predeterminado del tipo de datos definido por el usuario citytype , ejecute este comando: sp_unbindefault citytype La sintaxis completa del procedimiento del sistema sp_unbindefault es: sp_unbindefault objname [, futureonly]

Si el parmetro objname indicado no tiene el formato table . column , SQL Server supone que se trata de un tipo de datos definido por el usuario. Cuando se desvincula un valor predeterminado de un tipo de datos definido por el usuario, el valor predeterminado se desvincula de todas las columnas de ese tipo, a no ser que:

Indique el segundo parmetro opcional futureonly , que evita que las columnas existentes de ese tipo de datos pierdan su vinculacin con el valor predeterminado, o bien El valor predeterminado de una columna con ese tipo de datos definido por el usuario se haya cambiado y su valor actual sea distinto del valor predeterminado que se est desvinculando.

A continuacin se muestra un ejemplo que ilustra el caso anterior: 1. 2. 3. 4. 5. Cree un tipo de datos definido por el usuario llamado nm . Use nm en las instrucciones create correspondientes a las tablas friends_etc y enemies para crear las columnas friends_etc . pname , friends_etc . sname y enemies . nickname. Cree un valor predeterminado llamado nmdflt y vinclelo a nm . Cambie el valor predeterminado de enemies.nickname creando un nuevo valor predeterminado llamado nastydflt y vinculndolo a enemies . nickname . Ahora, si desvincula nmdflt de nm , slo se vern afectadas friends.pname y friends.sname . Puesto que el valor predeterminado original de enemies.nickname se ha cambiado, el valor predeterminado de esa columna no se desvincula, aunque est definido como del tipo nm .

Omisin de valores predeterminados Si desea quitar un valor predeterminado totalmente de una base de datos, utilice el comando drop default . El valor predeterminado debe desvincularse de todas las columnas y tipos de datos definidos por el usuario antes de poder omitirlo. Si trata de omitir un valor predeterminado que todava est vinculado, SQL Server muestra un mensaje de error y el comando drop default no se ejecuta correctamente. Sin embargo, no es necesario desvincular y luego omitir un valor predeterminado para poder vincular otro nuevo. Basta con vincular otro valor predeterminado en su lugar. A continuacin se indica cmo quitar citydflt : drop default citydflt La sintaxis completa del comando drop default es: drop default [ owner .] default_name [, [ owner .] default_name ] ... Slo su propietario puede omitir un valor predeterminado. Efecto de los valores predeterminados sobre los valores nulos
Page 187 of 280

Si especifica NOT NULL al crear una columna y no genera un valor predeterminado para la misma, SQL Server muestra un mensaje de error cada vez que alguien inserta una fila y no introduce datos en dicha columna. Cuando se omite un valor predeterminado de una columna NULL, SQL Server inserta NULL en esa posicin cada vez que el usuario aade filas sin introducir ningn valor para esa columna. Cuando se omite un valor predeterminado de una columna NOT NULL, el programa muestra un mensaje de error cada vez que el usuario aade filas y no introduce de forma explcita ningn valor para esa columna. La siguiente tabla ilustra la relacin entre la existencia de un valor predeterminado y la definicin de una columna como NULL o NOT NULL. Las entradas de la tabla muestran el resultado: Tabla 12-2: Valores predeterminados y valores NULL Definicin de columna NULL NOT NULL Creacin de reglas Las reglas se crean con el comando create rule y luego se vinculan a una columna o tipo de datos definido por el usuario con el procedimiento del sistema sp_bindrule . Es posible desvincular una regla de la columna o tipo de datos usando el procedimiento del sistema sp_unbindrule o vinculando una nueva regla a la columna o tipo de datos. Sintaxis de create rule La sintaxis del comando create rule es: create rule [ owner .] rule_name as condition_expression Los nombres de las reglas deben ajustarse a las reglas para identificadores. Slo es posible crear reglas en la base de datos actual. Dentro de una base de datos, los nombres de las reglas deben ser nicos para cada usuario. Un usuario no puede crear dos reglas diferentes llamadas socsecrule . Sin embargo, dos usuarios distintos pueden crear una regla llamada socsecrule , porque sus respectivos nombres de usuario las diferencian entre s. A continuacin se indica cmo crear una regla que permite cinco nmeros pub_id distintos y un valor ficticio (99 seguido de dos dgitos cualesquiera): create rule pub_idrule as @pub_id in ("1389", "0736", "0877", "1622", "1756") or @pub_id like "99[0-9][0-9]" La clusula as contiene el nombre del argumento de la regla, con el prefijo "@", y la definicin de la regla propiamente dicha. El argumento hace referencia al valor de columna que se ve afectado por la instruccin update o insert . En el ejemplo anterior, el argumento es @ pub_id , un nombre adecuado puesto que esta regla se va a vincular a la columna pub_id . Puede usar cualquier nombre para el argumento, pero el primer carcter debe ser "@". El uso del nombre de la columna o tipo de datos a que se va a vincular la regla puede ayudar a recordar cul es su funcin. La definicin de la regla puede contener cualquier expresin vlida en una clusula where e incluir operadores aritmticos, operadores de comparacin, like , in , between , etc.. Sin embargo, la definicin de una regla no puede hacer referencia a ninguna columna ni a ningn otro objeto de base de datos directamente. Se pueden incluir funciones incorporadas que no hacen referencia a objetos de base de datos. El siguiente ejemplo crea una regla que obliga a que los valores introducidos por el usuario sean compatibles con una "imagen" concreta. En este caso, cada valor introducido en la columna deber comenzar por los dgitos "415", seguidos de siete o ms caracteres:
Page 188 of 280

Sin entrada Sin valor predeterminado Nulo Error

Sin entrada, Con valor predeterminado Valor predeterminado Valor predeterminado

Se introduce Se introduce null null Valor Sin valor predeterminado predeterminado Nulo Error Nulo Error

create rule phonerule as @phone like '415_ _ _ _ _ _ _' Para asegurarse de que las edades introducidas para sus amigos estn entre 1 y 120, pero nunca 17, intente con este comando: create rule agerule as @age between 1 and 120 and @age !=17 Vinculacin de reglas Una vez creada una regla, use el procedimiento del sistema sp_bindrule para vincular la regla a una columna o un tipo de datos definido por el usuario. A continuacin se muestra la sintaxis completa de sp_bindrule : sp_bindrule rulename , objname [, futureonly]

rulename es el nombre de la regla creada con create rule . objname es el nombre de la tabla y la columna, o del tipo de datos definido por el usuario, a la que debe vincularse la regla. Si el parmetro no tiene el formato table.column , el sistema supone
que se trata de un tipo de datos definido por el usuario.

El tercer parmetro opcional, futureonly , slo tiene sentido cuando se vincula una regla a un tipo de datos definido por el usuario. Todas las columnas del tipo de datos definido por el usuario indicado quedan asociadas a la regla especificada, a no ser que se especifique futureonly , que evita que las columnas existentes del tipo de datos de usuario hereden la regla. Si la regla asociada a un tipo de datos definido por el usuario determinado se ha cambiado previamente, la regla cambiada se mantiene para las columnas existentes de ese tipo de datos definido por el usuario. Note: No es posible vincular una regla a una columna del tipo de datos text , image o timestamp . Vinculacin de reglas a columnas Para vincular una regla a una columna, utilice el procedimiento del sistema sp_bindrule con el nombre de la regla, y el nombre de tabla y de columna entre comillas. A continuacin se indica cmo se vincula pub_idrule a publishers.pub_id : sp_bindrule pub_idrule, "publishers.pub_id" Como ejemplo adicional, a continuacin se indica una regla que garantiza que los tres primeros dgitos de todos los cdigos postales sean 946: create rule postalcoderule946 as @postalcode like "946[0-9][0-9]" Para vincularla a la columna postalcode de friends_etc , haga lo siguiente: sp_bindrule postalcoderule946, "friends_etc.postalcode" No es posible vincular columnas y usarlas durante el mismo lote. sp_bindrule no puede estar en el mismo lote que las instrucciones insert que ejecutan la regla. Vinculacin de reglas a tipos de datos definidos por el usuario No se puede vincular una regla a un tipo de datos del sistema, pero s a un tipo de datos definido por el usuario. Para vincular phonerule a un tipo de datos definido por el usuario llamado p# , escriba: sp_bindrule phonerule, "p#" Precedencia de las reglas Las reglas vinculadas a las columnas siempre tienen precedencia sobre las vinculadas a los tipos de datos definidos por el usuario. Al vincular una regla a una columna, se sustituye la regla vinculada al tipo de datos definido por el usuario de esa
Page 189 of 280

columna, pero al vincular una regla a un tipo de datos, no se sustituir la regla vinculada a una columna de ese tipo de datos de usuario. Una regla vinculada a un tipo de datos definido por el usuario se activa slo cuando se intenta insertar un valor en una columna de base de datos del tipo de datos definido por el usuario, o actualizar dicha columna. Dado que las reglas no verifican las variables, evite asignar un valor a una variable de un tipo de datos definido por el usuario que pueda ser rechazada por una regla vinculada a una columna del mismo tipo de datos. La siguiente tabla indica la precedencia cuando se vinculan reglas a columnas y tipos de datos de usuario donde ya existen reglas: Tabla 12-3: Precedencia de las reglas Regla nueva vinculada a : Regla antigua vinculada a: Tipo de datos de usuario Tipo de datos de usuario Columna Columna Sustituye a la regla antigua. Sin cambios. Sustituye a la regla antigua. Sustituye a la regla antigua.

Al introducir datos que requieren restricciones temporales especiales en algunas columnas, se puede crear una nueva regla que ayude a verificar los datos. Por ejemplo, supongamos que se aaden datos a la columna debt de la tabla friends_etc . Se sabe que todas las deudas que se desean registrar hoy estn entre $5 y $200. Para evitar la introduccin accidental de una cantidad fuera de este margen, cree una regla como la siguiente (la definicin de regla permite una entrada de $0.00 para mantener el valor predeterminado definido anteriormente para esta columna). create rule debtrule as @debt = $0.00 or @debt between $5.00 and $200.00 Vincule debtrule a la columna debt as: sp_bindrule debtrule, "friends_etc.debt" Note: Una vez creada y vinculada una regla, verifquela siempre insertando datos. Muchos errores de creacin y vinculacin de reglas slo pueden detectarse si se verifican mediante una instruccin insert o update . Desvinculacin de reglas Desvincular una regla significa desconectarla de una columna o tipo de datos definido por el usuario en particular. La definicin de una regla desvinculada permanece almacenada en la base de datos y queda disponible para su uso en el futuro. Existen dos formas de desvincular una regla:

Use el procedimiento del sistema sp_unbindrule para quitar la vinculacin entre una regla y una columna o tipo de datos definido por el usuario. Use el procedimiento del sistema sp_bindrule para vincular una nueva regla a esa columna o tipo de datos. El valor antiguo queda desvinculado automticamente.

A continuacin se muestra cmo cancelar la asociacin entre debtrule (o cualquier otra regla vinculada) y friends_etc.debt : sp_unbindrule "friends_etc.debt" La regla permanece en la base de datos, pero no tiene ninguna conexin con friends_etc.debt . Para desvincular una regla del tipo de datos definido por el usuario p#, ejecute el siguiente comando: sp_unbindrule "p#" La sintaxis completa del procedimiento del sistema sp_unbindrule es: sp_unbindrule objname [, futureonly]

Page 190 of 280

Si el parmetro objname indicado no tiene el formato " table.column " , SQL Server supone que se trata de un tipo de datos definido por el usuario. Cuando se desvincula una regla de un tipo de datos definido por el usuario, la regla se desvincula de todas las columnas de ese tipo, a no ser que:

Indique el segundo parmetro opcional futureonly , que evita que las columnas existentes de ese tipo de datos pierdan su vinculacin con la regla; o bien La regla de una columna de ese tipo de datos definido por el usuario se haya modificado de modo que su valor actual sea distinto de la regla que se est desvinculando.

Omisin de reglas Si desea quitar una regla de la base de datos completamente, use el comando drop rule . La regla debe desvincularse de todas las columnas y tipos de datos de usuario antes de poder omitirse. Si intenta omitir una regla que an est vinculada, SQL Server muestra un mensaje de error y el comando drop rule no se ejecuta correctamente. Sin embargo, no es necesario desvincular y luego omitir una regla para poder vincular una nueva. Basta con vincular otra en su lugar. A continuacin se muestra cmo quitar phonerule despus de desvincularla: drop rule phonerule La sintaxis completa del comando drop rule es: drop rule [ owner .] rule_name [, [ owner .] rule_name ] ... Despus de omitir una regla, los datos nuevos que se introduzcan en las columnas anteriormente regidas por sta se introducirn sin restricciones. Los datos existentes no se vern afectados de ningn modo. Slo su propietario puede omitir una regla. Obtencin de informacin sobre valores predeterminados y reglas El procedimiento del sistema sp_help , cuando se usa con un nombre de tabla, muestra las reglas y los valores predeterminados vinculados a las columnas. Este ejemplo muestra informacin sobre la tabla authors de la base de datos pubs , incluidas las reglas y los valores predeterminados: sp_help authors El procedimiento del sistema sp_help tambin informa sobre una regla vinculada a un tipo de datos definido por el usuario. Para verificar si una regla est vinculada al tipo de datos definido por el usuario p # , ejecute este comando: sp_help "p#" El procedimiento sp_helptext informa sobre la definicin (la instruccin create ) de una regla o valor predeterminado. Chapter 13

Uso de lotes y lenguaje de control de flujo


Transact-SQL permite agrupar una serie de instrucciones como un lote, ya sea de forma interactiva o desde un archivo del sistema operativo. Tambin se pueden utilizar las estructuras de control de flujo ofrecidas por Transact-SQL para conectar las instrucciones utilizando estructuras de tipo de programacin. En este captulo se trata lo siguiente:

Una introduccin general a los lotes y al lenguaje de control de flujo Las reglas asociadas con el uso de instrucciones en lotes Uso del lenguaje de control de flujo Definicin de lote y de lenguaje de control de flujo
Page 191 of 280

Reglas asociadas a lotes Uso del lenguaje de control de flujo

Definicin de lote y de lenguaje de control de flujo Hasta aqu, cada ejemplo de la Gua del Usuario de Transact-SQL consisti de una instruccin individual. Las instrucciones individuales se ejecutan en SQL Server de una en una, introduciendo instrucciones y recibiendo resultados de forma interactiva. SQL Server tambin puede procesar instrucciones mltiples ejecutadas como un lote, tanto de forma interactiva como desde un archivo. Un lote de instrucciones SQL se termina mediante una seal de fin de lote que indica a SQL Server que contine y ejecute las instrucciones. La seal de fin de lote para la utilidad SQL autnoma isql es la palabra "go" sola en una lnea. Para obtener ms detalles, consulte el manual de programas de utilidad de SQL Server. Desde el punto de vista tcnico, una sola instruccin SQL puede constituir un lote, pero normalmente se piensa en un lote como un conjunto de instrucciones mltiples. Con frecuencia, un lote de instrucciones se escribe en un archivo del sistema operativo antes de enviarse a isql . Transact-SQL proporciona palabras clave especiales llamadas lenguaje de control de flujo que permiten controlar el flujo de ejecucin de las instrucciones. El lenguaje de control de flujo se puede utilizar en instrucciones sencillas, lotes, procedimientos almacenados y disparadores. Sin el lenguaje de control de flujo, las instrucciones SQL se llevan a cabo de forma secuencial, conforme se producen. Las subconsultas correlacionadas, explicadas en el Captulo 5, "Subconsultas: uso de consultas dentro de otras consultas", son una excepcin parcial. El lenguaje de control de flujo permite que las instrucciones se conecten y se relacionen entre s utilizando estructuras de tipo de programacin. El lenguaje de control de flujo, como if...else para la ejecucin condicional de comandos y while para la ejecucin repetitiva, permite refinar y controlar el funcionamiento de las instrucciones SQL. El lenguaje de control de flujo de Transact-SQL transforma el SQL estndar en un lenguaje de programacin de muy alto nivel. Reglas asociadas a lotes Existen reglas que controlan qu instrucciones SQL pueden combinarse en un solo lote. Estas reglas de lotes incluyen lo siguiente:

Algunos comandos de base de datos no pueden combinarse con otras instrucciones en un lote. Se trata de los siguientes: create procedure create rule create default create trigger create view Los comandos que s pueden combinarse con otras instrucciones SQL en un lote incluyen: create database (salvo que no puede crear una base de datos y generar o acceder a los objetos de la base de datos nueva en un solo lote) create table create index Las reglas y valores predeterminados no pueden vincularse a columnas y utilizarse durante el mismo lote. sp_bindrule y sp_bindefault no pueden estar en el mismo lote que las instrucciones insert que ejecutan la regla o valor predeterminado. use debe ejecutarse en un lote anterior antes que las instrucciones que hacen referencia a los objetos de dicha base de datos. No es posible realizar una operacin drop con un objeto y despus hacer referencia a ste o volver a crearlo en el mismo lote. Cualquier opcin definida con una instruccin set tendr efecto al final del lote. Es posible combinar instrucciones set y consultas en el mismo lote, pero las opciones de set no se aplicarn a las consultas de dicho lote.

Ejemplos del uso de lotes Los ejemplos de esta seccin describen lotes que utilizan el formato de la utilidad isql , que tiene una clara seal de fin de lote: la palabra "go" sola en una lnea. A continuacin se muestra un lote que contiene dos instrucciones select en un solo lote: select count(*) from titles select count(*) from authors go ------------18
Page 192 of 280

(1 row affected) ------------23 (1 row affected) Se puede crear una tabla y hacer referencia a ella en el mismo lote. Este lote crea una tabla, inserta una fila en ella y despus selecciona todo lo que contiene: create table test (column1 char(10), column2 int) insert test values ("hello", 598) select * from test go (1 row affected) column1 column2 ------- ------hello 598 (1 row affected) Una instruccin create view debe ser la nica instruccin de un lote. Este lote contiene una sola instruccin, que crea una vista: create view testview as select column1 from test go Se puede combinar una instruccin use con otras instrucciones siempre que los objetos a los que haga referencia en las instrucciones subsiguientes estn en la base de datos donde empez. Este lote selecciona de una tabla de la base de datos master y despus abre la base de datos pubs 2 . El lote supone que se encuentra en la base de datos master del principio. Tras la ejecucin del lote, pubs2 es la base de datos actual. select count(*) from sysdatabases use pubs2 go ------------9 (1 row affected) Se puede combinar una instruccin drop con otras instrucciones siempre que no haga referencia o vuelva a crear el objeto omitido en el mismo lote. El ejemplo de lote final combina una instruccin drop con otra select : drop table test select count(*) from titles go -----------18 (1 row affected) Si hay un error de sintaxis en algn punto del lote, no se ejecutar ninguna de las instrucciones. Por ejemplo, a continuacin se muestra un lote con un error de escritura en la ltima instruccin, y los resultados: select count(*) from titles select count(*) from authors slect count(*) from publishers go Msg 156, Level 15, State 1: SQL Server 'MAGOO', LIne 3: Sintaxis incorrecta junto a la palabra clave 'count'. Los lotes que violan una regla del lote tambin generan mensajes de error. A continuacin se muestran algunos ejemplos de lotes ilegales:
Page 193 of 280

create table test (column1 char(10), column2 int) insert test values ("hello", 598) select * from test create view testview as select column1 from test go Msg 111, Level 15, State 3: Server 'hq', Line 6: CREATE VIEW debe ser el primer comando en un batch de consulta. create view testview as select column1 from test insert testview values ("goodbye") go Msg 127, Level 15, State 1: Server 'hq', Procedure 'testview', Line 3: Este CREATE puede slo contener 1 sentencia. El siguiente lote funcionar si todava est en la base de datos especificada en la instruccin use . Si lo intenta desde otra base de datos como master , recibir un mensaje de error. use pubs2 select * from titles go Msg 208, Level 16, State 1: Server 'hq', Line 2: Invalid object name 'titles'. drop table test create table test (column1 char(10), column2 int) go Msg 2714, Level 16, State 1: Server 'hq', Line 2: Ya hay un objeto llamado 'test' en la base de datos. Lotes enviados como archivos Se pueden enviar uno o ms lotes de instrucciones SQL a isql desde un archivo del sistema operativo. Un archivo puede incluir ms de un lote, es decir, ms de una serie de instrucciones, cada uno terminado con la palabra "go". Por ejemplo, un archivo del sistema operativo podra contener los siguientes tres lotes: use pubs2 go select count(*) from titles select count(*) from authors go create table test (column1 char(10), column2 int) insert test values ("hello", 598) select * from test go Estos son los resultados de enviar este archivo a la utilidad isql : ------------18 (1 row affected) ------------23 (1 row affected) (1 row affected) column1 column2 ----------------hello 598 (1 row affected)
Page 194 of 280

Consulte la seccin sobre la utilidad isql del manual de programas de utilidad de SQL Server para obtener informacin especfica del entorno sobre la ejecucin de lotes almacenados en archivos. Uso del lenguaje de control de flujo El lenguaje de control de flujo se puede utilizar con instrucciones interactivas, en lotes y en procedimientos almacenados. El control de flujo y las palabras clave relacionadas y sus funciones son: Tabla 13-1: Control de flujo y palabras clave relacionadas Palabra clave if ...else begin ...end while break ...continue declare goto label return waitfor print raiserror /* coment ario */ Funcin Define una ejecucin condicional. Define una ejecucin alternativa cuando la condicin if es falsa. Comienzo de un bloque de instrucciones. Final de un bloque de instrucciones. Repite la ejecucin de instrucciones mientras la condicin es verdadera. Sale del final del siguiente bucle while ms exterior. Reinicio del bucle while . Declara variables locales. Va a un rtulo ( label:) , una posicin en un bloque de instrucciones. Sale de forma incondicional. Define el retardo para la ejecucin del comando. Imprime un mensaje definido por el usuario o una variable local en la pantalla del usuario. Imprime un mensaje definido por el usuario o una variable local en la pantalla del usuario y define un indicador del sistema en la variable global @@ error . Inserta un comentario en cualquier punto de una instruccin SQL.

if...else begin...end while y break...continue declare y variables locales goto return print raiserror Mensajes definidos por el usuario para print y raiserror waitfor Comentarios

if ... else
La palabra clave if , con o sin la compaa de else , se utiliza para introducir una condicin que determina si se ejecutar la instruccin siguiente. La instruccin SQL se ejecuta si la condicin se cumple, es decir, si devuelve TRUE (verdadero). La palabra clave else introduce una instruccin SQL alternativa que se ejecuta cuando la condicin if devuelve FALSE (falso). La sintaxis para if y else es: if boolean_expression statement [else [if boolean_expression statement ] ]

Page 195 of 280

Una expresin booleana es una expresin que devuelve TRUE o FALSE. En ella se puede incluir un nombre de columna, una constante, cualquier combinacin de nombres de columna y constantes conectados por operadores aritmticos o basados en bits, o una subconsulta, siempre que sta devuelva un solo valor. Si la expresin booleana contiene una instruccin select , debe incluirse entre parntesis y devolver un solo valor. A continuacin se muestra un ejemplo del uso de if sola: if exists (select postalcode from authors where postalcode = '94705') print "Berkeley author" Si uno o ms de los cdigos postales de la tabla de autores tiene el valor "94705", se imprimir el mensaje "Berkeley author". La instruccin select de este ejemplo devuelve un solo valor, TRUE o FALSE, porque se usa con la palabra clave exists . Esta palabra clave funciona aqu al igual que en las subconsultas. Consulte el Captulo 5, "Subconsultas: uso de consultas dentro de otras consultas". A continuacin se muestra un ejemplo con if y else que verifica la presencia de objetos creados por el usuario, todos los que tienen nmeros de ID superiores a 50. Si existen objetos de usuario, la clusula else selecciona sus nombres, tipos y nmeros de ID. if (select max(id) from sysobjects) < 50 print "There are no user-created objects in this database." else select name, type, id from sysobjects where id > 50 and type = "U" (0 rows affected) name type id --------------------authors U 1088006907 publishers U 1120007021 roysched U 1152007135 sales U 1184007249 titleauthor U 1216007363 titles U 1248007477 stores U 1280007591 discounts U 1312007705 test U 1648008902 (9 rows affected) Las estructuras if...else se utilizan frecuentemente en procedimientos almacenados en los que se verifica la existencia de algn parmetro. Las pruebas if pueden estar anidadas dentro de otras pruebas if , ya sea dentro de otra construccin if o despus de una else . La expresin de la prueba if slo puede devolver un valor. Adems, para cada estructura if...else , puede existir una instruccin select para if y otra para else . Para incluir ms de una instruccin select , hay que utilizar las palabras clave begin...end . El nmero mximo de pruebas if que pueden anidarse vara con la complejidad de las instrucciones select (u otras estructuras de lenguaje) que se incluyan con cada estructura if...else .

begin...end
Las palabras clave begin y end se utilizan para englobar una serie de instrucciones a fin de que sean tratadas como una unidad por las estructuras de control de flujo como if...else . Una serie de instrucciones englobadas por begin y end se denomina bloque de instrucciones . La sintaxis de begin...end es: begin statement block end He aqu un ejemplo: if (select avg(price) from titles) < $15 begin update titles
Page 196 of 280

set price = price * 2 select title, price from titles where price > $28 end Sin begin ni end , la condicin if slo se aplicara a la primera instruccin SQL. La segunda instruccin se ejecutara independientemente de la primera. Los bloques begin ... end pueden anidarse dentro de otros bloques begin...end .

while y break...continue
while se utiliza para definir una condicin para la ejecucin repetida de una instruccin o un bloque de instrucciones. Las instrucciones se ejecutan reiteradamente siempre que la condicin especificada sea verdadera. La sintaxis es: while boolean_expression statement En este ejemplo, las instrucciones select y update se repiten siempre que el precio promedio permanezca por debajo de $30: while (select avg(price) from titles) < $30 begin select title_id, price from titles where price > $20 update titles set price = price * 2 end (0 rows affected) title_id price -----------PC1035 22.95 PS1372 21.59 TC3218 20.95 (3 rows affected) (18 rows affected) (0 rows affected) title_id price -----------BU1032 39.98 BU1111 23.90 BU7832 39.98 MC2222 39.98 PC1035 45.90 PC8888 40.00 PS1372 43.18 PS2091 21.90 PS3333 39.98 TC3218 41.90 TC4203 23.90 TC7777 29.98 (12 rows affected) (18 rows affected) (0 rows affected) break y continue controlan el funcionamiento de las instrucciones dentro de un bucle while . break permite salir del bucle while . Todas las instrucciones que aparecen despus de la palabra clave end , que marca el final del bucle, se ejecutan. continue hace que el bucle while se inicie de nuevo, omitiendo cualquier instruccin despus de continue menos dentro del bucle. break y continue se activan frecuentemente mediante una prueba if . La sintaxis de break...continue es:

Page 197 of 280

while boolean expression begin statement [ statement ]... break [ statement ]... continue [ statement ]... end A continuacin se muestra un ejemplo con while , break , continue e if que invierte el aumento producido en los ejemplos anteriores. Siempre que el precio promedio permanezca por encima de $20, todos los precios se reducen a la mitad. Despus se selecciona el precio mximo. Si es inferior a $40, se sale del bucle while ; en caso contrario, intenta realizar el bucle de nuevo. continue permite que la instruccin print se ejecute slo cuando el promedio est por encima de $20. Despus de que termina el bucle while , se imprime un mensaje y una lista de los libros con el precio mximo. while (select avg(price) from titles) > $20 begin update titles set price = price / 2 if (select max(price) from titles) < $40 break else if (select avg(price) from titles) < $20 continue print "Average price still over $20" end select title_id, price from titles where price > $20 print "Not Too Expensive" (18 rows affected) (0 rows affected) (0 rows affected) Average price still over $20 (0 rows affected) (18 rows affected) (0 rows affected) title_id price -------------PC1035 22.95 PS1372 21.59 TC3218 20.95 (3 rows affected) Not Too Expensive Si hay dos o ms bucles while anidados, la instruccin break sale al siguiente bucle exterior. Primero se ejecutan todas las instrucciones que aparecen despus de la palabra clave end del bucle interno y luego se reinicia el bucle externo .

declare y variables locales


Una variable es una entidad a la que se asigna un valor. Este valor puede cambiar durante el lote o el procedimiento almacenado donde se utiliza la variable. SQL Server tiene dos tipos de variables: locales y globales. Las variables locales estn definidas por el usuario, mientras que las variables globales las suministra el sistema y estn predefinidas. Las variables locales se declaran, nombran y escriben mediante la palabra clave declare , y reciben un valor inicial mediante una instruccin select . Dichas variables deben declararse, recibir un valor y utilizarse en su totalidad dentro del mismo lote o procedimiento. Las variables locales se utilizan frecuentemente en un lote o procedimiento almacenado como contadores de bucles while o bloques if...else . Cuando se usan en procedimientos almacenados, las variables locales se declaran para su uso automtico no interactivo por parte del procedimiento cuando ste se ejecuta. Los nombres de las variables locales deben empezar con el smbolo "@" y despus seguir las reglas para identificadores. A cada variable local se le debe asignar un tipo de datos definido por el usuario o un tipo de datos suministrado por el sistema distinto de text , image o sysname .
Page 198 of 280

Las variables locales se declaran con esta sintaxis: declare @ variable_name [, @ variable_name datatype datatype ]...

Cuando se declara una variable, tiene el valor NULL. Los valores se asignan a las variables locales con una instruccin select . A continuacin se muestra la sintaxis: select @ variable_name = { expression | ( select_statement { expression | ( select_statement ) } ...] [from clause ] [where clause ] [group by clause ] [having clause ] [order by clause ] [compute clause ] Las variables locales deben declararse y utilizarse en el mismo lote o procedimiento. La instruccin select que asigna un valor a la variable local generalmente devuelve un solo valor. Una subconsulta que asigna un valor a la variable local debe devolver un slo valor. A continuacin se muestran algunos ejemplos: declare @veryhigh money select @veryhigh = max(price) from titles if @veryhigh > $20 print "Ouch!" declare @one varchar(18), @two varchar(18) select @one = "this is one", @two = "this is two" if @one = "this is one" print "you got one" if @two = "this is two" print "you got two" else print "nope" declare @tcount int, @pcount int select @tcount = (select count(*) from titles), @pcount = (select count(*) from publishers) select @tcount, @pcount Las instrucciones select que utilizan expresiones que devuelven ms de un valor asignan a la variable el ltimo valor devuelto. Es ms eficaz en trminos de uso de memoria y de rendimiento escribir: select @a = 1, @b = 2, @c = 3 que escribir: select @a = 1 select @b = 2 select @c = 3 Una regla similar se aplica a las instrucciones declare . Es ms eficaz escribir: declare @a int, @b char(20), @c float que escribir: declare @a int declare @b char(20) declare @c float La instruccin select que asigna valores a variables slo tiene esa nica misin; no puede utilizarse para devolver datos al usuario. La primera instruccin select del siguiente ejemplo asigna el precio mximo a la variable local @ veryhigh ; la segunda instruccin select es necesaria para mostrar el valor: declare @veryhigh money select @veryhigh = max(price) from titles select @veryhigh
Page 199 of 280

) } [, @

variable

Si la instruccin select que asigna valores a una variable devuelve ms de un valor, se asigna a la variable el ltimo valor devuelto. Esta consulta asigna a la variable el ltimo valor devuelto por "select advance from titles": declare @m money select @m = advance from titles select @m (18 rows affected) -----------------------8,000.00 (1 row affected) Observe que la instruccin de asignacin indica el nmero de filas afectadas (devueltas) por la instruccin select. Si una instruccin select que asigna valores a una variable no devuelve ningn valor, la instruccin deja la variable intacta. Las variables locales pueden utilizarse como argumentos para print o raiserror . Variables y valores nulos A las variables locales se les asigna el valor NULL cuando se declaran, y se les puede asignar el valor nulo mediante una instruccin select . El significado especial de NULL requiere que la comparacin entre variables con valores nulos y otros valores nulos se ajuste a reglas especiales. Esta tabla muestra los resultados de comparaciones entre columnas con valores nulos y expresiones con valores nulos usando operadores de comparacin diferentes (una expresin puede ser una variable, un literal, o una combinacin de variables, literales y operadores aritmticos). Tabla 13-2: Comparacin de valores nulos Usando los operadores =, != o <> Usando los operadores <, >, <=, !< o !> Comparando c olumn_value y c olumn_value FALSE Comparando c olumn_value y e xpression Comparando e xpression y c olumn_value Comparando e xpression y e xpression Por ejemplo, esta prueba: declare @v int, @i int if @v = @i select "null = null, true" if @v > @i select "null > null, true" muestra que slo la primera comparacin devuelve un valor verdadero: ----------------null = null, true (1 row affected) Este ejemplo devuelve todas las filas de la tabla titles donde advance tiene el valor NULL: declare @m money select title_id, advance from titles where advance = @m title_id advance -------- ---------------MC3026 NULL PC9999 NULL TRUE TRUE TRUE FALSE FALSE FALSE FALSE

declare y variables locales

Page 200 of 280

Las variables globales son variables predefinidas suministradas por el sistema. Se distinguen de las variables locales por tener dos smbolos "@" precediendo a sus nombres, por ejemplo, @@ error . Estas son las variables globales: Tabla 13-3: Variables globales de SQL Server Variable Contenido Contiene 0 si la conversin del juego de caracteres no est en efecto. Contiene 1 si la conversin del juego de caracteres est en efecto. Contiene el nombre del juego de caracteres del cliente. Se define como NULL si el juego de caracteres del cliente nunca fue inicializado; en caso contrario, contiene el nombre del ltimo juego de caracteres utilizado. Contiene la ID del juego de caracteres del cliente. Se define como -1 si el juego de caracteres del cliente nunca fue inicializado; en caso contrario, contiene la id de syscharsets del ltimo juego de caracteres usado. Contiene el nmero de logins o intentos de login. Contiene la cantidad de tiempo, en pulsos, que la CPU emple en realizar el trabajo de SQL Server desde la ltima vez que se inici. Contiene 0 si la ltima transaccin se ejecut de forma correcta; en caso contrario, contiene el ltimo nmero de error generado por el sistema. La variable global @@error se utiliza generalmente para verificar el estado de error, se haya ejecutado correctamente o no, de la ltima instruccin emitida. Una instruccin como if @@error != 0 seguida de return origina una salida por error. Contiene el ltimo valor insertado en una columna IDENTITY mediante una instruccin insert o select into . @@identity se define cada vez que se inserta una fila en una tabla. Si una instruccin inserta mltiples filas, @@ identity refleja el valor IDENTITY de la ltima fila insertada. Si la tabla afectada no contiene una columna IDENTITY, @@identity se define en 0. El valor de @@identity no se ve afectado por el fallo de una instruccin insert o select into , ni por la reversin de la transaccin que la contena. @@ identity conserva el ltimo valor insertado en una columna IDENTITY, aunque la instruccin que la haya insertado no se consigne.

@@char_convert @@client_csname

@@client_csid @@connections @@cpu_busy

@@error

@@identity

@@idle @@io_busy @@isolation @@langid @@language @@maxcharlen

Contiene la cantidad de tiempo, en pulsos, que SQL Server estuvo inactivo. Contiene la cantidad de tiempo, en pulsos, que SQL Server emple para efectuar operaciones de entrada y salida. Contiene el nivel de aislamiento actual del programa Transact-SQL. @@isolation toma el valor del nivel activo (1 o 3). Define la ID de idioma local del idioma en uso, segn el valor de syslanguages.langid . Define el nombre del idioma en uso, segn el valor de syslanguages.name . Contiene la longitud mxima, en bytes, de los caracteres multibyte del juego de caracteres predeterminado.

Contiene el nmero mximo de conexiones simultneas que se pueden realizar con SQL Server en este entorno informtico. El usuario puede configurar SQL Server para cualquier nmero de conexiones @@max_connections menor o igual que el valor de @@max_connections con sp_configure " number of user connections ".

@@ncharsize @@nestlevel @@pack_received @@pack_sent @@packet_errors @@procid @@rowcount @@servername @@spid @@sqlstatus

Contiene la longitud media, en bytes, de un carcter nacional. Contiene el nivel de anidacin de la ejecucin actual, inicialmente cero. Cada vez que un procedimiento almacenado o disparador llama a otro procedimiento almacenado o disparador, se incrementa el nivel de anidacin. Si se supera el mximo de 16, la transaccin se aborta. Contiene el nmero de paquetes de entrada ledos por SQL Server. Contiene el nmero de paquetes de salida escritos por SQL Server. Contiene el nmero de errores generados mientras SQL Server enviaba y reciba paquetes. Contiene la ID de procedimiento almacenado del procedimiento en ejecucin. Contiene el nmero de filas afectadas por la ltima consulta. @@rowcount es definida como cero por cualquier comando que no devuelve filas, como una instruccin if . Contiene el nombre de este SQL Server. Contiene el nmero de la ID de proceso de servidor del proceso actual. Contiene informacin de estado resultante de la ltima instruccin fetch .
Page 201 of 280

@@textcolid @@textdbid @@textobjid @@textptr @@textsize @@textts

Contiene la ID de columna de la columna referenciada por @@ textptr . El tipo de datos de esta variable es tinyint . Contiene la ID de base de datos de una base de datos que contiene un objeto con la columna referenciada por @@ textptr . El tipo de datos de esta variable es smallint. Contiene la ID de objeto de un objeto que contiene la columna referenciada por @@ textptr . El tipo de datos de esta variable es int Contiene el puntero de texto de la ltima columna text o image insertada o actualizada por un proceso. El tipo de datos de esta variable es binary(16) (no confunda esta variable con la funcin textptr ). Contiene el lmite del nmero de bytes de datos text o image devueltos por una instruccin select . El lmite predeterminado es 32K bytes para isql ; el valor predeterminado depende del software del cliente. Puede cambiarse el lmite de una sesin mediante set textsize . Contiene la marca horaria de texto de la columna referenciada por @@ textptr . El tipo de datos de esta variable es varbinary(8) . Contiene la disminucin de espacio libre necesaria para activar un umbral. Esta cantidad, tambin a la que se pueden colocar los umbrales en un segmento de base de datos.

@@thresh_hysteresis conocida como valor de histresis, se mide en pginas de base de datos de 2K. Determina la proximidad @@timeticks @@total_errors @@total_read @@total_write @@tranchained @@trancount @@transtate @@version
Contiene el nmero de microsegundos por pulso. La cantidad de tiempo por pulso es dependiente de la mquina. Contiene el nmero de errores generados mientras SQL Server realizaba una lectura o escritura. Contiene el nmero de lecturas de disco realizadas por SQL Server desde la ltima vez que se inici. Contiene el nmero de escrituras de disco realizadas por SQL Server desde la ltima vez que se inici. Contiene el modo de transaccin actual del programa Transact-SQL. @@tranchained devuelve 0 para no encadenadas o 1 para encadenadas. Contiene el nmero de transacciones activas del usuario actual. Contiene el estado actual de una transaccin despus que se ejecuta una instruccin. Sin embargo, @@transtate no se borra para cada instruccin, al contrario de lo que ocurre con @@error . Contiene la fecha de la versin actual de SQL Server.

Para obtener informacin sobre el contenido de muchas de estas variables globales, hay que ejecutar el procedimiento del sistema sp_monitor . Para obtener informacin completa sobre los procedimientos del sistema, consulte el Manual de Referencia de SQL Server . Si un usuario declara una variable local que tiene el mismo nombre que una variable global , dicha variable se trata como una variable local.

goto
La palabra clave goto origina una bifurcacin incondicional a un rtulo definido por el usuario. goto y los rtulos pueden utilizarse en procedimientos almacenados y lotes. El nombre del rtulo debe ajustarse a las reglas para identificadores e ir seguido de un signo de dos puntos (:) la primera vez que se introduce. No va seguido de un signo de dos puntos cuando se utiliza con goto . A continuacin se muestra la sintaxis: label : goto label A continuacin se muestra un ejemplo que utiliza goto y un rtulo, un bucle while u una variable local como contador: declare @count smallint select @count = 1 restart: print "yes" select @count = @count + 1 while @count <=4 goto restart Como en este ejemplo, goto generalmente se hace dependiente de un bucle while o una prueba if , o alguna otra condicin, a fin de evitar un bucle infinito entre goto y el rtulo.
Page 202 of 280

return
La palabra clave return sale de un lote o procedimiento de forma incondicional y puede usarse en cualquier momento de un lote o procedimiento. Cuando se utiliza en procedimientos almacenados, return puede aceptar un argumento opcional para devolver un estado al solicitante. Las instrucciones que aparecen despus de return no se ejecutan. La sintaxis es simplemente: return [ int_expression ]

A continuacin se muestra un ejemplo de un procedimiento almacenado que utiliza return , as como if...else y begin...end : create procedure findrules @nm varchar(30) = null as if @nm is null begin print "You must give a user name" return end else begin select sysobjects.name, sysobjects.id, sysobjects.uid from sysobjects, master..syslogins where master..syslogins.name = @nm and sysobjects.uid = master..syslogins.suid and sysobjects.type = "R" end Si no se proporciona ningn nombre de usuario como parmetro cuando se llama a findrules , la palabra clave return hace que el procedimiento se detenga despus de que el usuario haya recibido un mensaje en su pantalla. Si se proporciona un nombre de usuario, los nombres de las reglas propiedad del usuario se recuperan de las tablas del sistema correspondientes. return es similar a la palabra clave break usada dentro de los bucles while . Los ejemplos que utilizan valores de retorno se incluyen en el Captulo 14, "Uso de procedimientos almacenados".

print
La palabra clave print , utilizada en el ejemplo anterior, muestra un mensaje definido por el usuario o el contenido de una variable local en la pantalla del usuario. La variable local debe declararse dentro del mismo lote o procedimiento en el que se utiliza. El mensaje en s puede tener hasta 255 bytes de longitud. La sintaxis es: print { @@ format_string | @ local_variable | global _ variable } [, arg_list ]

He aqu otro ejemplo: if exists (select postalcode from authors where postalcode = '94705') print "Berkeley author" A continuacin se indica cmo utilizar print para mostrar el contenido de una variable local: declare @msg char(50) select @msg = "What's up doc?" print @msg print reconoce los marcadores de lugar de la cadena de caracteres que va a imprimirse. Las cadenas de formato pueden contener hasta 20 marcadores de lugar nicos colocados en cualquier orden. Estos marcadores se sustituyen por el contenido formateado de cualquier argumento que aparezca despus de format_string cuando el texto del mensaje se enva al cliente. Para permitir la reordenacin de los argumentos cuando las cadenas de formato se traducen a un idioma con una estructura gramatical diferente, los marcadores de lugar se numeran. El marcador de lugar de un argumento aparece en este formato:
Page 203 of 280

%nn! . Los componentes son un signo de porcentaje, un valor entero entre 1 y 20, y un signo de admiracin. El valor entero

representa la posicin del marcador de lugar en la cadena en el idioma original. "%1!" es el primer argumento en la versin original, "%2!" es el segundo argumento, y as sucesivamente. Indicar la posicin del argumento de este modo hace posible traducir correctamente, incluso cuando el orden en que aparecen los argumentos en el idioma de destino es distinto del orden en el idioma de origen. Por ejemplo, suponga que el siguiente mensaje est en ingls: %1! is not allowed in %2!. La versin en alemn de este mensaje es: %1! ist in %2! nicht zulssig.

La versin en japons del mensaje es: En este ejemplo, "%1!" en los tres idiomas representa el mismo argumento, y "%2!" tambin representa un solo argumento en los tres idiomas. Este ejemplo muestra la reordenacin de los argumentos que, en ocasiones, es necesaria en el formato traducido. No es posible omitir los nmeros de los marcadores de lugar cuando stos se usan en una cadena de formato, aunque los marcadores no tienen que utilizarse en orden numrico. Por ejemplo, no se pueden tener los marcadores de lugar 1 y 3 en una cadena de formato sin tener el marcador 2 en la misma cadena. El parmetro opcional arg_list puede ser una serie de variables o de constantes. Un argumento puede ser cualquier tipo de datos excepto text o image ; se convierte al tipo de datos char antes de incluirse en el mensaje final. Si no se proporciona ninguna lista de argumentos, la cadena de formato debe ser el mensaje que ha de imprimirse, sin ningn marcador de lugar. La longitud mxima de la cadena de salida de format_string ms todos los argumentos despus de la sustitucin es de 512 bytes.

raiserror
raiserror muestra un error definido por el usuario o un mensaje de variable local en la pantalla del usuario y define un indicador del sistema para registrar el hecho de que se ha producido un error. Al igual que ocurre con print , la variable local debe declararse en el mismo lote o procedimiento en que se utiliza. El mensaje puede tener hasta 255 caracteres de longitud. A continuacin se muestra la sintaxis de raiserror : raiserror error_number [{ format_string | @ local_variable }] [, arg_list ] [ extended_value = extended_value [{, extended_value

extended_value

}...]]

El nmero de error ( error_number ) se sita en la variable global @@ error , que almacena el ltimo nmero de error generado por SQL Server, independientemente de que est asociado a un mensaje de error suministrado por el sistema o uno definido por el usuario. Los nmeros de error de los mensajes de error definidos por el usuario deben ser superiores a 17000. Si error_number est entre 17000 y 19999, y no se ha especificado una cadena de formato ( format_string ) o sta se encuentra vaca (""), SQL Server recupera texto de mensaje de error de la tabla sysmessages de la base de datos master . Estos mensajes de error los utilizan principalmente los procedimientos del sistema. La longitud de la cadena de formato (format_string) est limitada a 255 bytes; la longitud mxima de la salida de format_string ms todos los argumentos es de 512 bytes. Las variables locales utilizadas para los mensajes de raiserror deben ser char o varchar . La cadena de formato o la variable son opcionales. Si no se incluye ninguna, SQL Server usa el mensaje correspondiente al error_number de sysusermessages en el idioma predeterminado. Al igual que sucede con print , es posible sustituir variables o constantes definidas por arg_list en format_string . Como opcin, se pueden definir datos de error extendidos para que los use la aplicacin Open Client(TM) (cuando se incluyen valores extendidos con raiserror ). Para obtener ms informacin sobre los datos de error extendidos, consulte la documentacin de Open Cliente o raiserror en el Manual de Referencia de SQL Server .

Page 204 of 280

Use raiserror en lugar de print cuando desee almacenar un nmero de error en @@ error . Por ejemplo, a continuacin se indica cmo podra utilizar raiserror en el procedimiento findrules : raiserror 99999 "You must give a user name" El nivel de gravedad de todos los mensajes de error definidos por el usuario es 16. Este nivel indica que el usuario ha cometido un error no fatal. Mensajes definidos por el usuario para print y raiserror Se puede llamar a mensajes de sysusermessages para que los use print o raiserror con el procedimiento del sistema sp_getmessage . Utilice el procedimiento del sistema sp_addmessage para crear un conjunto de mensajes. El ejemplo que aparece a continuacin utiliza sp_addmessage , sp_getmessage y print para instalar un mensaje en sysusermessages en ingls y alemn, recuperarlo para su uso en un procedimiento almacenado definido por el usuario e imprimirlo. /* ** Instalar mensajes ** Primero, en ingls (langid = NULL) */ set language us_english go sp_addmessage 25001, "There is already a remote user named '%1!' for remote server '%2!'." go /* Luego, en alemn*/ sp_addmessage 25001, "Remotebenutzername '%1!' existiert bereits auf dem Remoteserver '%2!'.","german" go create procedure test_proc @remotename varchar(30), @remoteserver varchar(30) as declare @msg varchar(255) declare @arg1 varchar(40) /* ** verificar que no hay ningn ** @remotename para el @remoteserver. */ if exists (select * from master.dbo.sysremotelogins l, master.dbo.sysservers s where l.remoteserverid = s.srvid and s.srvname = @remoteserver and l.remoteusername = @remotename) begin exec sp_getmessage 25001, @msg output select @arg1=isnull(@remotename,"null") print @msg, @arg1, @remoteserver return (1) end return(0) go

waitfor
La palabra clave waitfor especifica una hora determinada del da, un intervalo de tiempo o un evento en el que debe tener lugar la ejecucin de un bloque de instrucciones, un procedimiento almacenado o una transaccin. A continuacin se muestra la sintaxis: waitfor {delay " time " | time " time " | errorexit | processexit | mirrorexit}

La palabra clave delay indica a SQL Server que espere hasta que haya transcurrido el tiempo especificado. time indica a SQL Server que espere hasta la hora especificada, proporcionada en uno de los formatos aceptables para datos datetime .

Page 205 of 280

Sin embargo, no es posible especificar fechas, no se permite el componente de fecha del valor datetime . El tiempo especificado con waitfor time o waitfor delay puede incluir horas, minutos y segundos, hasta un mximo de 24 horas. Emplee el formato "hh:mm:ss". Por ejemplo, waitfor time "16:23" indica a SQL Server que espere hasta las 4:23 pm. La instruccin waitfor delay "01:30" indica a SQL Server que espere una hora y 30 minutos. Para obtener una revisin de los formatos aceptables para los valores de time , consulte el Captulo 8, "Adicin, modificacin y eliminacin de datos". errorexit indica a SQL Server que espere hasta que un proceso termine de forma anormal. processexit espera hasta que un proceso termina por cualquier razn. mirrorexit espera hasta que falla una lectura o una escritura de un dispositivo duplicado. waitfor errorexit se puede utilizar con un procedimiento que destruya el proceso terminado de forma anormal a fin de liberar los recursos del sistema que de otro modo seran ocupados por un proceso infectado. Para averiguar cul es el proceso infectado, verifique la tabla sysprocesses con el procedimiento del sistema sp_who . Este ejemplo indica a SQL Server que espere hasta las 2:20 p.m. Despus, actualiza la tabla chess con el siguiente movimiento y ejecuta un procedimiento almacenado llamado sendmessage , que inserta un mensaje en una de las tablas de Judy, informndole que ahora existe un nuevo movimiento en la tabla chess . He aqu el ejemplo: begin waitfor time "14:20" insert chess(next_move) values('Q-KR5') execute sendmessage 'judy' end Para enviar el mensaje a Judy despus de 10 segundos en lugar de esperar hasta las 2:20, sustituya esta instruccin waitfor en el ejemplo anterior: waitfor delay "0:00:10" Una vez emitido el comando waitfor , no puede utilizar su conexin a SQL Server hasta que llegue la hora o tenga lugar el evento especificado. Comentarios La notacin del comentario se utiliza para anexar comentarios a instrucciones, lotes y procedimientos almacenados. Un comentario tiene el siguiente aspecto: /* texto del comentario */ Los comentarios no tienen una longitud mxima y pueden insertarse en cualquier lugar, en una lnea independiente o al final de una lnea. Los comentarios con mltiples lneas tambin son correctos, siempre que cada comentario comience con una barra invertida y un asterisco, y finalice con un asterisco y una barra invertida. Todo lo que se encuentra entre "/*" y "*/" se trata como parte del comentario. Los comentarios se pueden anidar. Una convencin estilstica utilizada frecuentemente para comentarios de varias lneas es comenzar la primera lnea con "/*" y las lneas posteriores con "**". El comentario finaliza con "*/" como siempre. A continuacin se muestra el aspecto que tiene: select * from titles /* Un comentario incluido aqu puede explicar las ** reglas relacionadas con el uso de un asterisco ** como una abreviatura en la lista de seleccin.*/ where price > $5 A continuacin se muestra un procedimiento que incluye un par de comentarios: /* este procedimiento busca las reglas por nombre ** de usuario*/ create procedure findrules2 @nm varchar(30) = null as if @nm is null /* si no se indica ningn ** parmetro*/ print "You must give a user name" else begin select sysobjects.name, sysobjects.id,
Page 206 of 280

sysobjects.uid from sysobjects, master..syslogins where master..syslogins.name = @nm and sysobjects.uid = master..syslogins.suid and sysobjects.type = "R" end Chapter 14

Uso de procedimientos almacenados


Se pueden agrupar instrucciones SQL y el lenguaje de control de flujo en un procedimiento almacenado para mejorar el funcionamiento de SQL Server. Adems, puede utilizar un grupo de procedimientos predefinidos, llamados procedimientos almacenados del sistema, para realizar tareas administrativas y actualizar las tablas del sistema. En este captulo se trata lo siguiente:

Introduccin general a los procedimientos almacenados Creacin y ejecucin de procedimientos almacenados Obtencin de informacin a partir de procedimientos almacenados Reglas asociadas a procedimientos almacenados Omisin y cambio de nombre de procedimientos almacenados Uso de procedimientos almacenados del sistema Obtencin de informacin sobre procedimientos almacenados Definicin de procedimiento almacenado Creacin y ejecucin de procedimientos almacenados Obtencin de informacin a partir de procedimientos almacenados Reglas asociadas a procedimientos almacenados Omisin de procedimientos almacenados Cambio de nombre de los procedimientos almacenados Uso de procedimientos almacenados como mecanismos de seguridad Procedimientos del sistema Obtencin de informacin sobre procedimientos almacenados

Definicin de procedimiento almacenado Los procedimientos almacenados son grupos formados por instrucciones SQL y el lenguaje de control de flujo. Cuando se ejecuta un procedimiento, se prepara un plan de ejecucin para que la subsiguiente ejecucin sea muy rpida. Los procedimientos almacenados pueden:

Incluir parmetros Llamar a otros procedimientos Devolver un valor de estado a un procedimiento de llamada o lote para indicar el xito o el fracaso del mismo y la razn de dicho fallo Devolver valores de parmetros a un procedimiento de llamada o lote Ejecutarse en SQL Server remotos

La posibilidad de escribir procedimientos almacenados mejora notablemente la potencia, eficacia y flexibilidad de SQL. Los procedimientos compilados mejoran la ejecucin de las instrucciones y lotes de SQL de forma dramtica. Adems, los procedimientos almacenados pueden ejecutarse en otros SQL Server si el servidor del usuario y el remoto estn configurados para permitir logins remotos. Escriba disparadores en su SQL Server local que ejecuten procedimientos en un servidor remoto siempre que determinados eventos, como las eliminaciones, actualizaciones o inserciones, tengan lugar a nivel local. Los procedimientos almacenados se diferencian de las instrucciones SQL ordinarias y de los lotes de instrucciones SQL en que estn precompilados. La primera vez que se ejecuta un procedimiento, el procesador de consultas de SQL Serverlo analiza y prepara un plan de ejecucin que se almacena de forma definitiva en una tabla del sistema . Posteriormente, el procedimiento se ejecuta segn el plan almacenado. Puesto que ya se ha realizado la mayor parte del trabajo de procesamiento de consultas, los procedimientos almacenados se ejecutan casi de forma instantnea.

Page 207 of 280

SQL Server proporciona una gran variedad de procedimientos almacenados como herramientas adecuadas para el usuario. Estos procedimientos almacenados se llaman procedimientos del sistema. Los procedimientos almacenados se crean con create procedure . Para ejecutar un procedimiento almacenado, ya sea un procedimiento del sistema o uno definido por el usuario, use el comando execute . Tambin puede utilizar el nombre del procedimiento almacenado solo, siempre que sea la primera palabra de una instruccin o lote. Ejemplos de creacin y uso de procedimientos almacenados La sintaxis para la creacin de un procedimiento almacenado sencillo, sin funciones especiales como parmetros, es: create procedure procedure_name as SQL_statements Los procedimientos almacenados son objetos de base de datos, y sus nombres deben ajustarse a las reglas para identificadores. Es posible incluir cualquier nmero y cualquier tipo de instruccin SQL, salvo las instrucciones create . Consulte "Reglas asociadas a procedimientos almacenados". Un procedimiento puede ser tan sencillo como una sola instruccin que enumere los nombres de todos los usuarios de una base de datos: create procedure namelist as select name from sysusers Para ejecutar un procedimiento almacenado, emplee la palabra clave execute y el nombre del procedimiento almacenado, o simplemente especifique el nombre del procedimiento, siempre que se enve a SQL Server solo o sea la primera instruccin de un lote. Puede ejecutar namelist de cualquiera de las siguientes formas: namelist execute namelist exec namelist Para ejecutar un procedimiento almacenado en un SQL Server remoto, debe proporcionar el nombre del servidor. La sintaxis completa de una llamada de procedimiento remoto es: execute server_name .[ database_name ].[ owner ]. procedure_name

Los siguientes ejemplos ejecutan el procedimiento namelist en la base de datos pubs2 en el servidor GATEWAY: execute gateway.pubs2..namelist gateway.pubs2.dbo.namelist exec gateway...namelist El ltimo ejemplo slo funciona si pubs 2 es la base de datos predeterminada del usuario. El nombre de la base de datos es opcional slo si el procedimiento almacenado se encuentra en la base de datos predeterminada del usuario. El nombre del propietario es opcional slo si el propietario de la base de datos ( " dbo " ) es el propietario del procedimiento o si el usuario lo posee. Lgicamente, es necesario tener permiso para ejecutar el procedimiento. Un procedimiento puede incluir ms de una instruccin. create select select select procedure showall as count(*) from sysusers count(*) from sysobjects count(*) from syscolumns

Cuando se ejecuta el procedimiento, los resultados de cada comando se muestran en el orden en que la instruccin aparece en el procedimiento. showall -----------5 (1 row affected)
Page 208 of 280

-----------88 (1 row affected) -----------349 (1 row affected, return status = 0) Cuando el comando create procedure se ejecuta de forma correcta, el nombre del procedimiento se almacena en sysobjects y su texto en syscomments . Se puede mostrar el texto de un procedimiento con el procedimiento del sistema sp_helptext : sp_helptext showall # Lines of Text --------------1 (1 row affected) text ---------------------------------------create procedure showall as select count(*) from sysusers select count(*) from sysobjects select count(*) from syscolumns (1 row affected, return status = 0) Procedimientos almacenados y permisos Los procedimientos almacenados pueden servir de mecanismos de seguridad, ya que un usuario puede recibir el permiso para ejecutar un procedimiento almacenado aunque no tenga permisos en las tablas o vistas referenciadas en el mismo ni permiso para ejecutar comandos especficos. Para obtener ms detalles, consulte la Gua del Usuario de las Caractersticas de Seguridad . Procedimientos almacenados y rendimiento Conforme cambia la base de datos, los planes de consulta originales utilizados para acceder a sus tablas pueden volver a optimizarse recompilndolos con el procedimiento del sistema sp_recompile . Esto evitar tener que buscar, omitir y volver a crear cada procedimiento almacenado y disparador. El siguiente ejemplo marca cada procedimiento almacenado y disparador que accede a la tabla titles para que se recompile la prxima vez que se ejecute. sp_recompile titles Para obtener informacin detallada sobre sp_recompile , consulte el Manual de Referencia de SQL Server . Creacin y ejecucin de procedimientos almacenados La sintaxis completa de create procedure es: create procedure [owner.]procedure_name[;number] [[ (]@parameter_name datatype default] [output] [, @parameter_name datatype [= default] [output]]...[)]] [with recompile] as sql_statements Slo se puede crear un procedimiento en la base de datos actual. El permiso para emitir create procedure est asignado de forma predeterminada al propietario de la base de datos, que puede transferirlo a otros usuarios. A continuacin se muestra la instruccin de sintaxis completa de execute : [execute] [@return_status = ] [[[ server .] database .] [[@ parameter_name =] [=

owner value

.] |

procedure_name

[;

number

]
Page 209 of 280

[@ parameter_name =] @ variable [output] [,[@ parameter_name =] value | [@ parameter_name =] @ variable [output]...]] [with recompile] Note: Las llamadas de procedimientos remotos no se consideran parte de una transaccin. Si ejecuta una llamada de procedimientos remotos despus de begin transaction y luego usa rollback transaction , los cambios realizados por la llamada en los datos remotos no se revierten. El diseador del procedimiento almacenado debe asegurarse de que se comprueban todas las condiciones que puedan originar una reversin antes de ejecutar una llamada de procedimientos remotos que altere los datos remotos. Parmetros Un parmetro es un argumento de un procedimiento almacenado. Es posible declarar uno o ms parmetros de forma opcional en una instruccin create procedure . El usuario debe suministrar el valor de cada parmetro indicado en una instruccin create procedure al ejecutarse el procedimiento. Los nombres de los parmetros deben estar precedidos del smbolo "@" y ajustarse a las reglas para identificadores. Es necesario asignarles un tipo de datos del sistema o uno definido por el usuario, y una longitud si es necesario para el tipo de datos. Los nombres de los parmetros son locales para el procedimiento que los crea; los mismos nombres de parmetros pueden utilizarse en otros procedimientos. Los nombres de parmetro, incluido el smbolo "@", pueden tener una longitud mxima de 30 bytes. A continuacin se muestra un procedimiento almacenado que resulta til en la base de datos pubs2 . Dado el apellido y nombre de un autor, el procedimiento muestra los nombres de los libros escritos por la persona en cuestin, as como el editor de cada libro. create proc au_info @lastname varchar(40), @firstname varchar(20) as select au_lname, au_fname, title, pub_name from authors, titles, publishers, titleauthor where au_fname = @firstname and au_lname = @lastname and authors.au_id = titleauthor.au_id and titles.title_id = titleauthor.title_id and titles.pub_id = publishers.pub_id Ahora ejecute au_info : au_info Ringer, Anne au_lname au_fname title pub_name -------- -------- --------------------- ---------Ringer Anne The Gourmet Microwave Binnet & Hardley Ringer Anne Is Anger the Enemy? New Age Books (2 rows affected, return status = 0) El siguiente procedimiento almacenado consulta las tablas del sistema. Dado un nombre de tabla como parmetro, el procedimiento muestra el nombre de la tabla, el nombre del ndice y la ID del ndice. create proc showind @table varchar(30) as select table_name = sysobjects.name, index_name = sysindexes.name, index_id = indid from sysindexes, sysobjects where sysobjects.name = @table and sysobjects.id = sysindexes.id Los encabezados de columna, por ejemplo , table_name , se aadieron para facilitar la lectura de los resultados. A continuacin se muestran los formatos de sintaxis aceptables para la ejecucin de este procedimiento almacenado: execute showind titles exec showind titles execute showind @table = titles execute GATEWAY.pubs2.dbo.showind titles showind titles

Page 210 of 280

El ltimo formato de sintaxis, sin exec ni execute , es aceptable siempre que la instruccin sea la nica o la primera de un lote. A continuacin se muestran los resultados de ejecutar showind en la base de datos pubs2 con titles como parmetro: table_name index_name index_id ---------- ---------- ---------titles titleidind 1 titles titleind 2 (2 rows affected, return status = 0) Note: Si proporciona los parmetros con el formato "@ parameter = value ", puede especificarlos en cualquier orden. En caso contrario, debe proporcionar los parmetros en el orden de su instruccin create procedure . Si suministra un valor con el formato "@ parameter = value ", todos los parmetros subsiguientes han de suministrarse de este modo. Parmetros predeterminados Se puede asignar un valor predeterminado al parmetro de la instruccin create procedure . Este valor, que puede ser cualquier constante, se toma como el argumento del procedimiento si el usuario no proporciona ninguno. A continuacin se muestra un procedimiento que muestra los nombres de todos los autores que han escrito un libro publicado por el editor introducido como parmetro. Si no se proporciona ningn nombre de editor, el procedimiento muestra los autores publicados por Algodata Infosystems. create proc pub_info @pubname varchar(40) = "Algodata Infosystems" as select au_lname, au_fname, pub_name from authors a, publishers p, titles t, titleauthor ta where @pubname = p.pub_name and a.au_id = ta.au_id and t.title_id = ta.title_id and t.pub_id = p.pub_id Tenga en cuenta que si el valor predeterminado es una cadena de caracteres que contiene espacios en blanco o signos de puntuacin incrustados, es necesario incluirlo entre comillas simples o dobles. Cuando ejecuta pub_info , puede proporcionar cualquier nombre de editor como valor del parmetro. Si no suministra ningn parmetro, SQL Server utiliza el predeterminado, Algodata Infosystems. exec pub_info au_lname au_fname pub_name -------------- ------------ -------------------Green Marjorie Algodata Infosystems Bennet Abraham Algodata Infosystems O'Leary Michael Algodata Infosystems MacFeather Stearns Algodata Infosystems Straight Dick Algodata Infosystems Carson Cheryl Algodata Infosystems Dull Ann Algodata Infosystems Hunter Sheryl Algodata Infosystems Locksley Chastity Algodata Infosystems (9 rows affected, return status = 0) En este procedimiento, showind2 , se asigna "titles" como valor predeterminado del parmetro @ table : create proc showind2 @table varchar(30) = titles as select table_name = sysobjects.name, index_name = sysindexes.name, index_id = indid from sysindexes, sysobjects where sysobjects.name = @table and sysobjects.id = sysindexes.id Los encabezados de columna, por ejemplo , table_name , clarifican la presentacin de los resultados. A continuacin se indica lo que el procedimiento muestra para la tabla authors :
Page 211 of 280

showind2 authors table_name index_name index_id ----------- ---------------------authors auidind 1 authors aunmind 2 (2 rows affected, return status = 0) Si el usuario no proporciona ningn valor, SQL Server utiliza el valor predeterminado, titles . showind2 table_name index_name index_id ----------- ----------- --------titles titleidind 1 titles titleind 2 (2 rows affected, return status =0) Si se espera un parmetro, pero no se suministra ninguno y no se proporciona ningn valor en la instruccin create procedure , SQL Server muestra un mensaje de error con los parmetros que espera el procedimiento. NULL como parmetro predeterminado El valor predeterminado puede ser el valor NULL. En este caso, si el usuario no suministra ningn parmetro, SQL Server ejecuta el procedimiento almacenado sin mostrar ningn mensaje de error. La definicin del procedimiento puede especificar una accin para llevarse a cabo si el usuario no proporciona ningn parmetro verificando si el valor del parmetro es nulo. A continuacin se muestra un ejemplo: create procedure showind3 @table varchar(30) = null as if @table is null print "Please give a table name" else select table_name = sysobjects.name, index_name = sysindexes.name, index_id = indid from sysindexes, sysobjects where sysobjects.name = @table and sysobjects.id = sysindexes.id Si el usuario no proporciona ningn parmetro, SQL Server imprime el mensaje del procedimiento en la pantalla. Para otros ejemplos de definicin del valor predeterminado como NULL, examine el texto de los procedimientos del sistema utilizando sp_helptext . Caracteres comodn en el parmetro predeterminado El valor predeterminado puede incluir los caracteres comodn (%, _, [] y [^]) si el procedimiento utiliza el parmetro con la palabra clave like . Por ejemplo, showind puede modificarse para mostrar informacin sobre las tablas del sistema si el usuario no proporciona ningn parmetro, como se muestra a continuacin: create procedure showind4 @table varchar(30)="sys%" as select table_name = sysobjects.name, index_name = sysindexes.name, index_id = indid from sysindexes, sysobjects where sysobjects.name like @table and sysobjects.id = sysindexes.id Uso de ms de un parmetro A continuacin se muestra una variante del procedimiento almacenado au_info que tiene valores predeterminados con caracteres comodn para ambos parmetros:

Page 212 of 280

create proc au_info2 @lastname varchar(30) = "D%", @firstname varchar(18) = "%" as select au_lname, au_fname, title, pub_name from authors, titles, publishers, titleauthor where au_fname like @firstname and au_lname like @lastname and authors.au_id = titleauthor.au_id and titles.title_id = titleauthor.title_id and titles.pub_id = publishers.pub_id Si au_info2 se ejecuta sin parmetros, se muestran todos los autores cuyos apellidos comienzan por "D": au_info2 au_lname au_fname -------- ------Dull Ann DeFrance Michel (2 rows affected)

title ------------------------Secrets of Silicon Valley The Gourmet Microwave

pub_name ------------Algodata Infosystems Binnet & Hardley

Si hay valores predeterminados disponibles para parmetros, stos pueden omitirse en la ejecucin, comenzando por el ltimo parmetro. No puede saltarse un parmetro a menos que NULL sea su valor predeterminado suministrado. Note: Si proporciona los parmetros en el formato " @parameter = value ", puede suministrarlos en cualquier orden. Tambin puede omitir un parmetro para el que se ha suministrado un valor predeterminado. Si proporciona un valor en el formato " @parameter = value ", todos los parmetros subsiguientes tambin debern suministrarse de este modo. Como ejemplo de omisin del segundo parmetro cuando se han definido valores predeterminados para dos parmetros, puede buscar los libros y editores de todos los autores cuyo apellido es "Ringer", de la siguiente manera: au_info2 Ringer au_lname au_fname --------------Ringer Anne Ringer Anne Ringer Albert Ringer Albert (4 rows affected) Grupos de procedimientos El punto y coma (;) y el nmero entero opcionales despus del nombre del procedimiento en las instrucciones create procedure y execute permiten agrupar los procedimientos que tienen el mismo nombre para que puedan omitirse juntos mediante un solo comando drop procedure . Los procedimientos utilizados en la misma aplicacin suelen agruparse de este modo. Por ejemplo, podra crear una serie de procedimientos llamados orders;1 , orders;2 , etc.. La siguiente instruccin omitira el grupo completo: drop proc orders Una vez agrupados los procedimientos mediante el anexo de un punto y coma (;) y un nmero a sus nombres, no es posible omitirlos de forma individual. Por ejemplo, no se permite la siguiente instruccin: drop proc orders;2

title --------------------The Gourmet Microwave Is Anger the Enemy? Is Anger the Enemy? Life Without Fear

Pub_name -----------Binnet & Hardley New Age Books New Age Books New Age Books

with recompile en create procedure


En la instruccin create procedure , la clusula opcional with recompile aparece justo antes de las instrucciones SQL. Esto indica a SQL Server que no guarde ningn plan para este procedimiento. Cada vez que se ejecuta el procedimiento se crea un plan nuevo. Si no se usa with recompile , SQL Server almacena el plan de ejecucin que crea. Generalmente, este plan de ejecucin es correcto.

Page 213 of 280

Sin embargo, es posible que un cambio en los datos o un cambio en los valores de parmetro suministrados para las ejecuciones subsiguientes haga que SQL Server proponga un plan de ejecucin distinto del que cre la primera vez que se ejecut el procedimiento. En estas situaciones, SQL Server necesita un plan de ejecucin nuevo. Use with recompile en una instruccin create procedure cuando crea que necesita un plan nuevo. Consulte el Manual de Referencia de SQL Server para obtener ms informacin.

with recompile en execute


En la instruccin execute , la clusula opcional with recompile aparece despus de cualquier parmetro. Esto indica a SQL Server que compile un plan nuevo. El plan nuevo se utiliza para ejecuciones subsiguientes. Use with recompile cuando ejecute un procedimiento si los datos han sufrido un gran cambio o si el parmetro que proporciona es atpico, es decir, si tiene alguna razn para creer que el plan almacenado con el procedimiento podra no ser ptimo para la ejecucin de ste. Note: Si utiliza select * en la instruccin create procedure , el procedimiento, aunque use la opcin with recompile de execute , no toma ninguna columna nueva aadida a la tabla. Es necesario omitir el procedimiento y volver a crearlo. Anidacin de procedimientos dentro de procedimientos La anidacin tiene lugar cuando un procedimiento almacenado o un disparador llama a otro. El nivel de anidacin se incrementa cuando el procedimiento o disparador llamado inicia la ejecucin y disminuye cuando el procedimiento o disparador llamado finaliza la ejecucin. Si se supera el mximo de 16 niveles de anidacin, el procedimiento no se ejecuta correctamente. El nivel de anidacin actual se almacena en la variable global @@nestlevel . Uso de tablas temporales en procedimientos almacenados Es posible crear y utilizar tablas temporales en un procedimiento almacenado, pero la tabla temporal slo existe mientras dura el procedimiento almacenado que la crea. Cuando el procedimiento finaliza, SQL Server omite la tabla temporal de forma automtica. Un solo procedimiento puede:

Crear una tabla temporal Insertar, actualizar o eliminar datos Ejecutar consultas en la tabla temporal Llamar a otros procedimientos que hacen referencia a la tabla temporal

Dado que la tabla temporal tiene que existir para poder crear procedimientos que hagan referencia a ella, a continuacin se indican los pasos que debe seguir: 1. Cree la tabla temporal que precisa con una instruccin create table o una select into . Por ejemplo: create table #tempstores (stor_id char(4), amount money) 2. Cree los procedimientos que accedan a la tabla temporal (pero no el que la genera). create procedure inv_amounts as select stor_id, "Total Due" =sum(amount) from #tempstores group by stor_id 3. Omita la tabla temporal: drop table #tempstores 4. Cree el procedimiento que genera la tabla y llama a los procedimientos creados en el paso 2: create procedure inv_proc as
Page 214 of 280

create table #tempstores (stor_id char(4), amount money) insert #tempstores select stor_id, sum(qty*(100-discount)/100*price) from salesdetail, titles where salesdetail.title_id = titles.title_id group by stor_id, salesdetail.title_id exec inv_amounts Tambin puede crear tablas temporales sin el prefijo #, utilizando create table tempdb..tablename... desde dentro de un procedimiento almacenado. Estas tablas no desaparecen cuando finaliza el procedimiento, de modo que es posible hacer referencia a ellas mediante procedimientos independientes. Siga los pasos descritos anteriormente para crear estas tablas. Ejecucin de procedimientos de forma remota Es posible ejecutar procedimientos en otro SQL Server desde el SQL Server local. Una vez configurados ambos servidores de forma adecuada, puede ejecutar cualquier procedimiento en el SQL Server remoto con slo usar el nombre del servidor como parte del identificador. Por ejemplo, para ejecutar un procedimiento llamado remoteproc en un servidor denominado GATEWAY: exec gateway.remotedb.dbo.remoteproc Consulte la Gua de Administracin del Sistema para obtener informacin sobre cmo configurar los SQL Server local y remoto para la ejecucin remota de procedimientos. Es posible pasar uno o ms valores como parmetros a un procedimiento remoto desde el lote o el procedimiento que contiene la instruccin execute para el procedimiento remoto. Los resultados del SQL Server remoto aparecen en el terminal local. El estado de retorno de los procedimientos, descritos en las secciones siguientes, puede utilizarse para capturar y transmitir mensajes de informacin sobre el estado de ejecucin de los procedimientos. Warning! Las llamadas de procedimientos remotos no se consideran parte de una transaccin. En consecuencia, si ejecuta una llamada de procedimientos remotos como parte de una transaccin y luego revierte la transaccin, los cambios realizados por la llamada en un SQL Server remoto no se revierten. Obtencin de informacin a partir de procedimientos almacenados Los procedimientos almacenados muestran un "estado de retorno" que indica si se han ejecutado correctamente o, en caso contrario, las razones del fallo. Este valor puede almacenarse en una variable cuando se llama a un procedimiento y utilizarse en futuras instrucciones Transact-SQL. Los valores del estado de retorno definidos por SQL Server para fallos se encuentran en la escala de -1 a -99; los usuarios pueden definir sus propios valores de estado de retorno fuera de esta escala. Otra forma en la que los procedimientos almacenados pueden devolver informacin al solicitante es mediante los parmetros de retorno. Los parmetros designados como parmetros de retorno en las instrucciones create procedure y execute informan sobre los valores de parmetro al solicitante. Despus el solicitante puede utilizar instrucciones condicionales para verificar el valor devuelto. El estado de retorno y los parmetros de retorno permiten modularizar los procedimientos almacenados. Un conjunto de instrucciones SQL usadas por varios procedimientos almacenados puede crearse como un solo procedimiento que devuelve su estado de ejecucin o los valores de sus parmetros al procedimiento de llamada. Por ejemplo, muchos de los procedimientos del sistema suministrados por SQL Server ejecutan un procedimiento que verifica que determinados parmetros son identificadores vlidos. Las llamadas de procedimientos remotos, que son procedimientos almacenados ejecutados en un SQL Server remoto, tambin devuelven ambos tipos de informacin. Todos los ejemplos que se muestran ms abajo se podran ejecutar de forma remota si la sintaxis de la instruccin execute incluyese el servidor, la base de datos y los nombres de los propietarios, as como el nombre del procedimiento. Estado de retorno Los procedimientos almacenados pueden devolver un valor entero llamado estado de retorno . Este estado indica que el procedimiento se ha realizado correctamente, o indica la razn del fallo. SQL Server tiene un conjunto definido de valores de
Page 215 of 280

retorno. Los usuarios tambin pueden definir sus propios valores de retorno. A continuacin se muestra un ejemplo de un lote que utiliza el formato de la instruccin execute que devuelve el estado: declare @status int execute @status = pub_info select @status El estado de ejecucin del procedimiento pub_info se almacena en la variable @ status . Este ejemplo solamente imprime el valor con una instruccin select ; ejemplos posteriores utilizan este valor de retorno en clusulas condicionales. Valores de estado de retorno reservados SQL Server reserva el 0 para indicar un retorno correcto y los valores negativos entre -1 y -99 para indicar diferentes razones de fallo. Los nmeros 0 y -1 a -14 estn en uso: Tabla 14-1: Valores de estado de retorno reservados Valor Significado 0 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 Procedimiento ejecutado sin error Falta objeto Error de tipo de datos Se eligi un proceso como vctima de un bloqueo insoluble Error de permiso Error de sintaxis Errores de usuario diversos Error de recursos, como espacio insuficiente Problema interno no fatal Se ha alcanzado el lmite del sistema Inconsistencia interna fatal Inconsistencia interna fatal La tabla o el ndice estn corrutpos La base de datos est corrupta Error de hardware

Los valores entre -15 y -99 estn reservados para su uso futuro por parte de SQL Server. Si se produce ms de un error durante la ejecucin, se devolver el estado que tenga el valor absoluto ms alto. Valores de retorno generados por el usuario El usuario puede generar sus propios valores de retorno en procedimientos almacenados aadiendo un parmetro a la instruccin return . Los nmeros entre 0 y -99 estn reservados para su uso por parte de SQL Server; pueden utilizarse todos los dems nmeros enteros. El siguiente ejemplo devuelve 1 cuando un libro tiene un contrato vlido y 2 en todos los dems casos: create proc checkcontract @titleid tid as if (select contract from titles where title_id = @titleid) = 1 return 1 else return 2 El siguiente procedimiento almacenado llama a checkcontract y utiliza clusulas condicionales para verificar el estado de retorno: create proc get_au_stat @titleid tid as
Page 216 of 280

declare @retvalue int execute @retvalue = checkcontract @titleid if (@retvalue = 1) print "Contract is valid" else print "There is not a valid contract" A continuacin se muestran los resultados de ejecutar get_au_stat con la title_id de un libro con un contrato vlido: get_au_stat "MC2222" Contract is valid Verificacin de roles en procedimientos Si un procedimiento almacenado realiza tareas relacionadas con la administracin del sistema o la seguridad, es posible que desee asegurarse de que slo los usuarios con un rol especfico puedan ejecutarlo (consulte la Gua del Usuario de las Caractersticas de Seguridad para obtener informacin sobre roles). La funcin proc_role permite verificar los roles cuando se ejecuta el procedimiento. proc_role devuelve 1 si el usuario posee el rol especificado. Los nombres de rol son sa_role, sso_role y oper_role . A continuacin se muestra un ejemplo que utiliza proc_role en el procedimiento almacenado test_proc para que la persona solicitante sea el administrador del sistema: create proc test_proc as if (proc_role("sa_role") = 0) begin print "You don't have the right role" return -1 end else print "You have SA role" return 0 Parmetros de retorno Cuando las instrucciones create procedure y execute incluyen la opcin output con un nombre de parmetro, el procedimiento devuelve un valor al solicitante, que puede ser un lote SQL u otro procedimiento almacenado. El valor devuelto puede utilizarse en instrucciones adicionales en el lote o el procedimiento de llamada. Cuando se usan parmetros de retorno en una instruccin execute que forma parte de un lote, los valores de retorno se imprimen con un encabezado antes de que se ejecuten las instrucciones subsiguientes del lote. Este procedimiento almacenado realiza la multiplicacin con dos valores enteros. El tercer valor entero, @ result , se define como un parmetro output : create procedure mathtutor @mult1 int, @mult2 int, @result int output as select @result = @mult1 * @mult2 Para utilizar mathtutor a fin de poner en cifras un problema de multiplicacin, debe declarar la variable @result e incluirla en la instruccin execute . La adicin de la palabra clave output a la instruccin execute muestra el valor de los parmetros de retorno. declare @result int exec mathtutor 5, 6, @result output (return status = 0) Return parameters: ----------30 Si quisiera adivinar la respuesta y ejecutar este procedimiento proporcionando tres valores enteros, no vera los resultados de la multiplicacin. La instruccin select del procedimiento asigna valores, pero no imprime:
Page 217 of 280

mathtutor 5, 6, 32 (return status = 0) El valor del parmetro output debe pasarse como una variable, no como una constante. Este ejemplo declara la variable @ guess para almacenar el valor que debe pasarse a mathtutor para su uso en @ result . SQL Server imprime los parmetros de retorno: declare @guess int select @guess = 32 exec mathtutor 5, 6, @result = @guess output (1 row affected) (return status = 0) Return parameters: @result ----------30 El valor del parmetro de retorno siempre se indica, tanto si ha cambiado su valor como si no. Tenga en cuenta que:

En el ejemplo anterior, el parmetro output @ result debe pasarse como "@ parameter = @ variable ". Si no fuera el ltimo parmetro pasado, los parmetros subsiguientes tendran que pasarse como "@ parameter = value ". @ result no tiene que declararse en el lote de llamada; es el nombre de un parmetro que ha de pasarse a mathtutor . Aunque el valor cambiado de @ result se devuelve al solicitante en la variable asignada en la instruccin execute , en este caso @ guess , se muestra bajo su propio encabezado, es decir, @ result .

Si quiere utilizar el valor inicial de @ guess en clusulas condicionales despus de la instruccin execute , debe almacenarlo en otro nombre de variable durante la llamada al procedimiento. El siguiente ejemplo ilustra los ltimos dos puntos utilizando @ store para mantener el valor de la variable durante la ejecucin del procedimiento almacenado y empleando el "nuevo" valor devuelto de @ guess en clusulas condicionales: declare @guess int declare @store int select @guess = 32 select @store = @guess execute mathtutor 5, 6, @result = @guess output select Your_answer = @store, Right_answer = @guess if @guess = @store print "Right-o" else print "Wrong, wrong, wrong!" (1 row affected) (1 row affected) (return status = 0) Return parameters: @result ----------30 Your_answer Right_answer ----------- -----------32 30 (1 row affected) Wrong, wrong, wrong! A continuacin se muestra un procedimiento almacenado que verifica si las nuevas ventas de libros haran que el porcentaje de derechos de autor de un autor cambiase. El parmetro @ pc est definido como un parmetro output : create proc roy_check @title tid, @newsales int, @pc int output as declare @newtotal int select @newtotal = (select titles.total_sales + @newsales
Page 218 of 280

from titles where title_id = @title) select @pc = royalty from roysched where @newtotal >= roysched.lorange and @newtotal < roysched.hirange and roysched.title_id = @title El siguiente lote SQL llama al procedimiento roy_check , despus de asignar un valor a la variable percent . Los parmetros de retorno se imprimen antes de que se ejecute la siguiente instruccin del lote: declare @percent int select @percent = 10 execute roy_check "BU1032", 1050, @pc = @percent output select Percent = @percent go (1 row affected) (return status = 0) Return parameters: @pc ----------12 Percent ----------12 (1 row affected) El siguiente procedimiento almacenado llama al procedimiento roy_check y utiliza el valor de retorno para percent en una clusula condicional: create proc newsales @title tid, @newsales int as declare @percent int declare @stor_pc int select @percent = (select royalty from roysched, titles where roysched.title_id = @title and total_sales >= roysched.lorange and total_sales < roysched.hirange and roysched.title_id=titles.title_id) select @stor_pc = @percent execute roy_check @title, @newsales, @pc = @percent output if @stor_pc != @percent begin print "Royalty is changed" select Percent = @percent end else print "Royalty is the same" Si ejecuta este procedimiento almacenado con los mismos parmetros utilizados en el lote anterior, ver estos resultados: execute newsales "BU1032", 1050 Royalty is changed Percent ----------12 (1 row affected, return status = 0) En los dos ejemplos anteriores que llaman a roy_check , @ pc es el nombre del parmetro que se pasa a roy_check y @percent es la variable que contiene la salida. Cuando el procedimiento almacenado newsales ejecuta roy_check , el valor devuelto en @percent puede cambiar dependiendo de los otros parmetros que se pasen. Si quiere comparar el valor devuelto de percent con el valor inicial de @ pc , debe almacenar el valor inicial en otra variable. El ejemplo anterior lo guard en stor_pc . Pase de valores en parmetros
Page 219 of 280

Los valores pasados en los parmetros deben tener este formato: @ parameter = @ variable

No pueden pasarse constantes; debe existir un nombre de variable que "reciba" el valor de retorno. Los parmetros pueden ser de cualquier tipo de datos de SQL Server, excepto text e image . Note: Si el procedimiento almacenado requiere varios parmetros, pase el parmetro del valor de retorno en ltimo lugar en la instruccin execute o pase todos los parmetros subsiguientes con el formato "@parameter = value". La palabra clave output La palabra clave output puede abreviarse como out , del mismo modo que execute puede acortarse como exec . Un procedimiento almacenado puede devolver varios valores; cada uno debe definirse como una variable output en el procedimiento almacenado y en las instrucciones de llamada: exec myproc @a = @myvara out, @b = @myvarb out Si especifica output mientras ejecuta un procedimiento y el parmetro no se define utilizando output en el procedimiento almacenado, aparecer un mensaje de error. No es un error llamar a un procedimiento que incluya especificaciones de valor de retorno sin solicitar los valores de retorno con output . Sin embargo, no se obtendrn los valores de retorno. El autor del procedimiento almacenado controla la informacin a la que pueden acceder los usuarios y stos tienen control sobre sus variables. Reglas asociadas a procedimientos almacenados Algunas reglas adicionales para la creacin de procedimientos almacenados son:

Las instrucciones create procedure no pueden combinarse con otras instrucciones en un solo lote. La definicin create procedure propiamente dicha puede incluir cualquier nmero y tipo de instruccin SQL, con la excepcin de use y estas instrucciones create : create view create default create rule create trigger create procedure Se pueden crear otros objetos de base de datos dentro de un procedimiento. Es posible hacer referencia a un objeto creado en el mismo procedimiento, siempre que se cree antes de hacer referencia a l. La instruccin create del objeto debe ocupar la primera posicin en el orden real de las instrucciones del procedimiento. En un procedimiento almacenado, no es posible crear un objeto, omitirlo y despus crear otro con el mismo nombre. SQL Server crea los objetos definidos en un procedimiento almacenado cuando el procedimiento se ejecuta, no cuando se compila. Si ejecuta un procedimiento que llama a otro, el procedimiento llamado puede acceder a los objetos creados por el primer procedimiento. Se puede hacer referencia a tablas temporales dentro de un procedimiento. Si crea una tabla temporal dentro de un procedimiento, la tabla slo existe para ese procedimiento y desaparece al salir de ste. El nmero mximo de parmetros de un procedimiento almacenado es de 255. El nmero mximo de variables locales y globales de un procedimiento slo est limitado por la memoria disponible.

Calificacin de nombres dentro de procedimientos Dentro de un procedimiento almacenado, los nombres de objeto utilizados con determinados comandos deben calificarse con el nombre del propietario del objeto si otros usuarios van a hacer uso del procedimiento almacenado. Estos comandos son: alter table , create table , drop table , truncate table , create index , drop index , update statistic s , dbcc . Los nombres de objeto usados con otras instrucciones, como select o insert , dentro de un procedimiento almacenado no necesitan estar calificados porque los nombres se resuelven cuando se compila el procedimiento. Por ejemplo, el usuario "mary" , que posee la tabla marytab , debera calificar el nombre de su tabla cuando se utilice con uno de estos comandos si quiere que otros usuarios puedan ejecutar el procedimiento donde se emplea la tabla:

Page 220 of 280

create procedure p1 as create index marytab_ind on mary.marytab(col1) El motivo de esta regla es que los nombres de objeto se resuelven cuando se ejecuta el procedimiento. Si marytab no est calificada y el usuario " john" intenta ejecutar el procedimiento, SQL Server busca una tabla llamada marytab propiedad de John. El ejemplo anterior muestra el uso correcto: indica a SQL Server que busque una tabla llamada marytab propiedad de Mary. Omisin de procedimientos almacenados Los procedimientos se quitan con el comando drop procedure , cuya sintaxis es: drop procedure [ owner .] procedure_name [, [ owner .] procedure_name ]... Si un procedimiento almacenado llama a otro procedimiento almacenado que se ha omitido, SQL Server muestra un mensaje de error. Sin embargo, si se define un procedimiento con el mismo nombre para reemplazar al omitido, otros procedimientos que hagan referencia a l podrn llamarlo sin ningn problema. Es posible omitir un grupo de procedimientos, es decir, varios procedimientos con el mismo nombre pero con sufijos number diferentes, mediante una sola instruccin drop procedure . Una vez agrupados los procedimientos, los procedimientos pertenecientes al grupo no podrn omitirse de forma individual. Cambio de nombre de los procedimientos almacenados Se puede cambiar el nombre de un procedimiento almacenado mediante el procedimiento del sistema sp_rename , cuya sintaxis es la siguiente: sp_rename objname , newname

Por ejemplo, para cambiar el nombre de showall a countall : sp_rename showall, countall Lgicamente, el nombre nuevo debe ajustarse a las reglas para identificadores. El usuario slo puede cambiar el nombre de los procedimientos almacenados que sean de su propiedad. El propietario de la base de datos puede cambiar el nombre del procedimiento almacenado de cualquier usuario. El procedimiento almacenado deber estar en la base de datos actual. Cambio de nombre de los objetos referenciados por procedimientos Es necesario omitir y volver a crear un procedimiento si se cambia el nombre de cualquiera de los objetos a los que hace referencia. Un procedimiento que hace referencia a una tabla o una vista cuyos nombres se han cambiado puede parecer que funciona de forma correcta durante un tiempo. De hecho, slo funciona hasta que SQL Server lo recompila. La recompilacin tiene lugar por muchas razones y sin notificarse al usuario. Utilice sp_depends para obtener un informe sobre los objetos a los que hace referencia un procedimiento. Uso de procedimientos almacenados como mecanismos de seguridad Es posible usar los procedimientos almacenados como mecanismos de seguridad a fin de controlar el acceso a la informacin de las tablas y la capacidad para efectuar modificaciones en los datos. Por ejemplo, puede denegar a otros usuarios el permiso para emplear el comando select en una tabla que es suya y crear un procedimiento almacenado que les permita visualizar slo determinadas filas o columnas. Tambin puede utilizar los procedimientos almacenados para limitar las instrucciones update , delete o insert . La persona que posee el procedimiento almacenado debe ser propietario de la tabla o vista usada en el procedimiento. Ni siquiera el administrador del sistema puede generar un procedimiento almacenado para realizar operaciones en las tablas de otro usuario si no ha recibido permiso sobre ellas.

Page 221 of 280

Para obtener informacin sobre cmo conceder y revocar permisos de procedimientos almacenados y otros objetos de base de datos, consulte la Gua del Usuario de las Caractersticas de Seguridad . Procedimientos del sistema Los procedimientos del sistema se suministran para comodidad del usuario como:

Mtodos abreviados para la recuperacin de informacin de las tablas del sistema. Mecanismos para llevar a cabo la administracin de la base de datos y otras tareas que implican la actualizacin de tablas del sistema.

La mayor parte del tiempo, las tablas del sistema slo se actualizan mediante procedimientos del sistema. Un administrador del sistema puede permitir actualizaciones directas en las tablas del sistema cambiando una variable de configuracin y emitiendo el comando reconfigure with override . Consulte la Gua de Administracin del Sistema para obtener informacin detallada. Los nombres de todos los procedimientos del sistema empiezan por "sp_". Se crean mediante el guin installmaster en la base de datos sybsystemprocs durante la instalacin de SQL Server. Los procedimientos del sistema pueden ejecutarse desde cualquier base de datos. Si ejecuta un procedimiento del sistema desde una base de datos distinta de sybsystemprocs , cualquier referencia a las tablas del sistema se correlacionan con la base de datos desde la que se ejecuta el procedimiento. Por ejemplo, si el propietario de la base de datos pubs2 ejecuta sp_adduser desde pubs2 , el usuario nuevo se aade a pubs2 .. sysusers . Cuando el parmetro de un procedimiento del sistema es un nombre de objeto y este nombre de objeto est calificado por un nombre de base de datos o de propietario, el nombre completo debe incluirse entre comillas dobles o simples. Dado que los procedimientos del sistema se encuentran en la base de datos sybsystemprocs , sus permisos tambin se definen aqu. Algunos procedimientos del sistema slo pueden ser ejecutados por los propietarios de las bases de datos. Estos procedimientos garantizan que el usuario que ejecuta el procedimiento es el propietario de la base de datos en la que se ejecutan. Otros procedimientos del sistema pueden ser ejecutados por cualquier usuario al que se ha concedido permiso execute sobre ellos, pero este permiso debe otorgarse en la base de datos sybsystemprocs . Esta situacin tiene dos consecuencias:

Un usuario puede tener permiso para ejecutar un procedimiento del sistema en todas las bases de datos o en ninguna. El propietario de una base de datos de usuario no puede controlar directamente los permisos para procedimientos del sistema dentro de su propia base de datos.

Consulte la Gua de Administracin del Sistema para obtener informacin detallada. Administracin de seguridad Esta categora incluye procedimientos para:

Aadir, omitir e informar sobre los logins a SQL Server Aadir, omitir e informar sobre los usuarios, grupos y alias de una base de datos Cambiar contraseas y bases de datos predeterminadas Cambiar el propietario de una base de datos Aadir, omitir e informar sobre los servidores remotos que pueden acceder a este SQL Server Aadir los nombres de los usuarios de servidores remotos que pueden acceder a este SQL Server

Los procedimientos de esta categora son: sp_addlogin , sp_addalias , sp_addgroup , sp_adduser , sp_changedbowner , sp_changegroup , sp_droplogin , sp_dropalias , sp_dropgroup , sp_dropuser , sp_helpgroup , sp_helprotect , sp_helpuser , sp_password . Servidores remotos Esta categora incluye procedimientos para:

Aadir, omitir e informar sobre los servidores remotos que pueden acceder a este SQL Server
Page 222 of 280

Aadir los nombres de los usuarios de servidores remotos que pueden acceder a este SQL Server

Los procedimientos de esta categora son: sp_addremotelogin , sp_addserver , sp_dropremotelogin , sp_dropserver , sp_helpremotelogin , sp_helpserver , sp_remoteoption , sp_serveroption . Definicin de datos y objetos de base de datos Esta categora incluye procedimientos para:

Vincular y desvincular reglas y valores predeterminados Aadir, omitir e informar sobre claves primarias, externas y comunes Aadir, omitir e informar sobre los tipos de datos definidos por el usuario Cambiar el nombre de objetos de base de datos y tipos de datos definidos por el usuario Volver a optimizar procedimientos almacenados y disparadores Informar sobre objetos de base de datos, tipos de datos definidos por el usuario, dependencias entre objetos de base de datos, bases de datos, ndices y espacio utilizado por tablas e ndices

Los procedimientos de esta categora son: sp_bindefault , sp_bindrule , sp_unbindefault , sp_unbindrule , sp_foreignkey , sp_primarykey , sp_commonkey , sp_dropkey , sp_depends , sp_addtype , sp_droptype , sp_rename , sp_spaceused , sp_help , sp_helpdb , sp_helpindex , sp_helpjoins , sp_helpkey , sp_helptext , sp_indsuspect , sp_recompile . Mensajes definidos por el usuario Esta categora incluye procedimientos para:

Aadir mensajes definidos por el usuario a la tabla sysusermessages de una base de datos del usuario Omitir mensajes definidos por el usuario de sysusermessages Recuperar mensajes de sysusermessages o sysmessages de la base de datos master para su uso en instrucciones print y raiserror

Los procedimientos de esta categora son: sp_addmessage , sp_dropmessage y sp_getmessage . Administracin del sistema Esta categora incluye procedimientos para:

Aadir, omitir e informar sobre dispositivos de bases de datos y de volcado Informar sobre bloqueos, las opciones de base de datos definidas y los usuarios que estn ejecutando procesos Cambiar e informar sobre variables de configuracin Controlar de la actividad del SQL Server

Los procedimientos de esta categora son: sp_addumpdevice , sp_dropdevice , sp_helpdevice , sp_helpsort sp_logdevice , sp_dboption , sp_diskdefault , sp_configure , sp_monitor , sp_lock, sp_who . Encontrar ms informacin sobre los procedimientos del sistema que llevan a cabo estas tareas administrativas en la Gua de Administracin del Sistema . Para obtener informacin completa sobre los procedimientos del sistema, consulte el Manual de Referencia de SQL Server . Obtencin de informacin sobre procedimientos almacenados Varios procedimientos del sistema proporcionan informacin sobre procedimientos almacenados a partir de las tablas del sistema.

sp_help
Se puede obtener un informe sobre un procedimiento almacenado con el procedimiento del sistema sp_help . Por ejemplo, se puede obtener informacin sobre el procedimiento almacenado byroyalty , que forma parte de la base de datos pubs2 , de la siguiente forma:
Page 223 of 280

sp_help byroyalty Name Owner ------------byroyalty dbo

type ---------------stored procedure

Created_on ------------------Feb 9 1987 3:56PM

Data_located_on_segment --------------------------Parameter_name Type Length -------------- ------ -----@percentage int 4 (return status = 0)

When_created -------------------Param_order ----------1

Se puede obtener ayuda sobre un procedimiento del sistema ejecutando sp_help al utilizar la base de datos master .

sp_helptext
Para mostrar el texto de la instruccin create procedure , ejecute el procedimiento del sistema sp_helptext : sp_helptext byroyalty # Lines of Text --------------1 (1 row affected) text --------------------------------------------------create procedure byroyalty @percentage int as select au_id from titleauthor where titleauthor.royaltyper = @percentage (1 row affected, return status = 0) Es posible ver el texto de un procedimiento del sistema ejecutando sp_helptext al utilizar la base de datos sybsystemprocs .

sp_depends
El procedimiento del sistema sp_depends muestra todos los procedimientos almacenados que hacen referencia al objeto especificado por el usuario, o todos los procedimientos de los que depende. Este comando muestra todos los objetos a los que hace referencia el procedimiento almacenado byroyalty creado por el usuario: sp_depends byroyalty Cosas a las que hace referencia el objeto en la base de datos actual. object type updated selected ---------------- ----------- ---------------dbo.titleauthor user table no no (return status = 0) La siguiente instruccin utiliza sp_depends para mostrar todos los objetos que hacen referencia a la tabla titleauthor : sp_depends titleauthor Cosas incluidas en la base de datos actual que hacen referencia al objeto. object -------------dbo.titleview dbo.reptq2 dbo.byroyalty type -----------------view stored procedure stored procedure

(return status = 0) Debe omitir y volver a crear el procedimiento si el nombre de algunos de los objetos a los que hace referencia ha cambiado. Los procedimientos del sistema se explican brevemente en "Procedimientos del sistema". Para obtener informacin completa sobre los procedimientos del sistema, consulte el Manual de Referencia de SQL Server .
Page 224 of 280

Chapter 15

Disparadores: imposicin de la integridad de referencia


Los disparadores pueden usarse para imponer la integridad de referencia de los datos en toda la base de datos. Los disparadores tambin permiten realizar cambios "en cascada" en tablas relacionadas, imponer restricciones de columna ms complejas que las permitidas por las reglas, comparar los resultados de las modificaciones de datos y llevar a cabo una accin resultante. En este captulo se trata lo siguiente:

Introduccin general a los disparadores Creacin y omisin de disparadores Forma en que los disparadores imponen la integridad de referencia de los datos en toda la base de datos Reglas asociadas a los disparadores Obtencin de informacin sobre disparadores Definicin de disparador Creacin de disparadores Omisin de disparadores Uso de disparadores para mantener la integridad de referencia Consideraciones sobre filas mltiples Reversin de disparadores Anidacin de disparadores Reglas asociadas a los disparadores Obtencin de informacin sobre disparadores

Definicin de disparador Un disparador es un tipo especial de procedimiento almacenado que se ejecuta cuando se insertan, eliminan o actualizan datos de una tabla especificada. Los disparadores pueden ayudar a mantener la integridad de referencia de los datos conservando la consistencia entre los datos relacionados lgicamente de distintas tablas. Integridad de referencia significa que los valores de las claves primarias y los valores correspondientes de las claves externas deben coincidir de forma exacta. La principal ventaja de los disparadores es que son automticos : funcionan cualquiera sea el origen de la modificacin de los datos, una introduccin de datos por parte de un empleado o una accin de una aplicacin. Cada disparador es especfico de una o ms operaciones de modificacin de datos, update , insert o delete . El disparador se ejecuta una vez por cada instruccin SQL. Un disparador se "dispara" slo cuando la instruccin de modificacin de datos finaliza y SQL Server verifica la posible violacin de tipos de datos, reglas o restricciones de integridad. El disparador y la instruccin que lo "dispara" se consideran una sola transaccin que puede revertirse desde dentro del disparador. Si se detecta un error grave, se revierte toda la transaccin. Situaciones en las que los disparadores son de mayor utilidad:

Los disparadores pueden realizar cambios "en cascada" a lo largo de las tablas relacionadas de la base de datos. Por ejemplo, un disparador de eliminacin de la columna title_id de la tabla titles puede originar una eliminacin correspondiente de las filas coincidentes de otras tablas, usando title_id como clave nica para localizar las filas de titleauthor , sales y roysched . Los disparadores pueden no permitir, o "revertir", los cambios que violen la integridad de referencia, cancelando la transaccin de modificacin de datos intentada. Este tipo de disparador puede activarse si intenta insertar una clave externa que no coincide con su clave primaria correspondiente. Por ejemplo, podra crear un disparador de insercin en titleauthor que revirtiese cualquier insercin si el nuevo valor titleauthor.title_id no coincidiese con alguno de los valores de titles.title_id . Los disparadores pueden imponer restricciones de mucha mayor complejidad que las definidas con las reglas. Al contrario de lo que ocurre con las reglas, los disparadores pueden hacer referencia a columnas u objetos de base de datos. Por ejemplo, un disparador puede revertir actualizaciones que intenten incrementar el precio de un libro en ms de un 1% del anticipo. Los disparadores pueden llevar a cabo anlisis de hiptesis sencillos. Por ejemplo, un disparador puede comparar el estado de una tabla antes y despus de una modificacin de datos y llevar a cabo acciones basndose en esa comparacin.
Page 225 of 280

En este captulo se resume la sintaxis de los disparadores, se explica cmo usarlos y se proporcionan ejemplos. Es posible que quiera utilizar estos ejemplos como plantillas para otros disparadores. En la seccin final de este captulo se describen las reglas relacionadas con el uso de disparadores y se explican los procedimientos del sistema que proporcionan ayuda con los disparadores. Note: Salvo el disparador llamado deltitle , los disparadores tratados en este captulo no estn incluidos en la base de datos pubs2 entregada con la copia de SQL Server. Para trabajar con los ejemplos mostrados en este captulo, cree cada ejemplo de disparador escribiendo la instruccin create trigger. Cada disparador nuevo para la misma operacin ( insert , update o delete ) de una tabla o columna escribe sobre el disparador anterior sin avisar, y los disparadores antiguos se omiten de forma automtica. Comparacin de disparadores y restricciones de integridad Como alternativa a los disparadores, es posible usar la restriccin de integridad de referencia de la instruccin create table para imponer la integridad de referencia en las tablas de la base de datos. Sin embargo, las restricciones de integridad de referencia se diferencian de los disparadores en que no pueden llevar a cabo las siguientes tareas (al igual que se ha descrito anteriormente):

Efectuar cambios "en cascada" en las tablas relacionadas de la base de datos Imponer restricciones complejas haciendo referencia a otras columnas u objetos de base de datos Realizar anlisis de hiptesis

Adems, las restricciones de integridad de referencia no revierten la transaccin actual como resultado de la imposicin de la integridad de datos. Con los disparadores, la transaccin se puede revertir o continuar segn la forma en que se manipule la integridad de referencia. Para obtener informacin sobre transacciones, consulte el Captulo 17, "Transacciones: mantenimiento de la consistencia y recuperacin de datos". Si la aplicacin requiere una de las tareas anteriores, deber usar disparadores. De lo contrario, las restricciones de integridad de referencia ofrecen un mtodo ms sencillo para imponer la integridad de los datos. Tenga presente que SQL Server verifica las restricciones de integridad de referencia antes que los disparadores, por lo que una instruccin de modificacin de datos que viole la restriccin no dispara el disparador tambin. Para obtener ms informacin sobre restricciones de integridad de referencia, consulte el Captulo 7, "Creacin de bases de datos y tablas". Creacin de disparadores Un disparador es un objeto de base de datos. Cuando se crea un disparador, se especifica la tabla y los comandos de modificacin de datos que deben "disparar", o activar, el disparador. Luego se indica la accin o acciones que debe llevar a cabo el disparador. A continuacin se muestra un ejemplo sencillo. Este disparador imprime un mensaje cada vez que alguien trata de insertar, eliminar o actualizar datos de la tabla titles : create trigger t1 on titles for insert, update, delete as print "Now modify the titleauthor table the same way." Sintaxis de create trigger A continuacin se muestra la sintaxis completa de create trigger : create trigger [ owner .] trigger_name on [ owner .] table_name {for {insert , update , delete} as SQL_statements O bien, usando la clusula if update : create trigger [ owner .] trigger_name on [ owner .] table_name for {insert , update} as [if update ( column_name )
Page 226 of 280

[{and | or} update ( column_name SQL_statements [if update ( column_name ) [{and | or} update ( column_name SQL_statements ]...

)]...] )]...

La clusula create crea el disparador y le asigna un nombre. El nombre del disparador debe cumplir con las reglas para identificadores. La clusula on indica el nombre de la tabla que activa el disparador. Esta tabla se denomina en ocasiones tabla de disparadores. Los disparadores se crean en la base de datos actual, aunque pueden hacer referencia a objetos de otras bases de datos. El nombre de propietario que califica el nombre de disparador debe ser el mismo que el de la tabla. Nadie, excepto el propietario de la tabla, puede crear un disparador en una tabla. Si se indica el propietario de la tabla con el nombre de tabla en la clusula create trigger o la clusula on , tambin debe especificarse en la otra clusula. La clusula for especifica los comandos de modificacin de datos de la tabla de disparadores que activan el disparador. En el ejemplo anterior, la ejecucin de insert , update o delete en titles hace que se imprima el mensaje. Las instrucciones SQL indican las condiciones y acciones del disparador . Las condiciones del disparador especifican criterios adicionales que determinan si el comando insert , delete o update har que se lleven a cabo las acciones del disparador. Las acciones de disparador mltiples de una clusula if deben agruparse con begin y end . Una clusula if update verifica si existe una insercin o actualizacin para una columna en particular. En el caso de las actualizaciones, la clusula if update da como resultado verdadero cuando el nombre de colmna se incluye en la clusula set de una instruccin update , aunque la actualizacin no cambie el valor de la columna. if update no se utiliza con delete . Es posible especificar ms de una columna, y usar ms de una clusula if update en una instruccin create trigger . Puesto que el nombre de tabla se especifica en la clusula on , no debe usar el nombre de tabla delante del nombre de columna con if update . Instrucciones SQL no permitidas en los disparadores Dado que los disparadores se ejecutan como parte de la transaccin, no se permiten las siguientes instrucciones en un disparador:

Todos los comandos create , incluidos create database , create table , create index , create procedure , create default , create rule , create trigger y create view Todos los comandos drop alter table y alter database truncate table grant y revoke update statistics reconfigure load database y load transaction disk init , disk mirror , disk refit , disk reinit , disk remirror , disk unmirror select into

Omisin de disparadores Se puede quitar un disparador omitindolo u omitiendo la tabla de disparadores a la que est asociado. La sintaxis de drop trigger es: drop trigger [ owner .] [, [owner.] trigger_name trigger_name ]...

Cuando se omite una tabla, los disparadores asociados a ella se omiten automticamente. El permiso drop trigger est asignado de forma predeterminada al propietario de la tabla de disparadores y no es transferible. Uso de disparadores para mantener la integridad de referencia
Page 227 of 280

Los disparadores se usan para mantener la integridad de referencia, que garantiza que los datos vitales de la base de datos, como el identificador nico de unos datos determinados, sean precisos y puedan usarse conforme cambia la base de datos. La integridad referencial se coordina mediante el uso de claves primarias y externas. La clave primaria es la columna o combinacin de columnas que identifican de forma exclusiva una fila. Su valor no puede ser NULL, y debe tener un ndice nico. Una tabla con una clave primaria puede combinarse con las claves externas de otras tablas. La tabla de clave primaria puede considerarse como la maestra en una relacin maestro-discpulo . En una base de datos puede haber numerosos grupos maestro-discpulo de este tipo. Use el procedimiento del sistema sp_primarykey para marcar la clave primaria. Esto marca la clave para usarse con sp_helpjoins y la aade a la tabla syskeys . En la base de datos pubs2 , por ejemplo, la columna title_id es la clave primaria de titles . Esta columna identifica de forma exclusiva los libros de titles y se combina con la columna title_id de titleauthor , salesdetail y roysched . La tabla titles es la tabla maestra en relacin con titleauthor , salesdetail y roysched . El diagrama del Chapter 1, "The pubs2 Database," del Suplemento de Referencia de SQL Server muestra estas relaciones. La clave externa es una columna o combinacin de columnas cuyos valores coinciden con la clave primaria. No es necesario que la clave externa sea nica. Con frecuencia esta clave tiene una relacin de muchas-a-una con respecto a la clave primaria. Los valores de las claves externas deben ser copias de los valores de las claves primarias, es decir, los valores de las claves externas slo pueden existir si tambin existen en las claves primarias. Una clave externa puede ser nula; si alguna parte de la clave externa compuesta es nula, la totalidad de la clave externa debe ser nula. Las tablas con claves externas se denominan con frecuencia tablas discpulas o dependientes de la tabla maestra. Use el procedimiento sp_foreignkey para marcar las claves externas de la base de datos. Esto les asigna indicadores que permite utilizarlas con sp_helpjoins y otros procedimientos que hagan referencia a la tabla syskeys . Las columnas title_id de titleauthor , salesdetail y roysched son claves externas; estas tablas son discpulas. Funcionamiento de los disparadores Los disparadores de integridad de referencia mantienen los valores de las claves externas en lnea con los de las claves primarias. Cuando una modificacin de datos afecta a una columna clave, los disparadores comparan los nuevos valores de columna con las claves relacionadas usando tablas de trabajo temporales llamadas tablas de verificacin de disparadores. Cuando se escriben los disparadores, las comparaciones se basan en los datos almacenados temporalmente en las tablas de verificacin de disparadores. Contrastacin de la modificacin de datos respecto a las tablas de verificacin de disparadores En las instrucciones de los disparadores se usan dos tablas especiales: la tabla deleted (eliminada) y la tabla inserted (insertada). Se trata de tablas temporales usadas en la verificacin de disparadores. Emplee estas tablas para comprobar los efectos de algunas modificaciones de datos y definir las condiciones de las acciones del disparador. No es posible alterar directamente los datos de las tablas de verificacin de disparadores, pero se pueden usar las tablas en instrucciones select para detectar los efectos de una instruccin insert , update o delete .

La tabla deleted almacena copias de las filas afectadas por las instrucciones delete y update . Durante la ejecucin de una instruccin delete o update , las filas se quitan de la tabla de disparadores y se transfieren a la tabla deleted . La tabla deleted y la tabla de disparadores no suelen tener filas en comn. La tabla inserted almacena copias de las filas afectadas por las instrucciones insert y update . Durante la ejecucin de insert o update , se aaden filas nuevas a inserted y a la tabla de disparadores al mismo tiempo. Las filas de inserted son copias de las nuevas filas de la tabla de disparadores.

Una actualizacin con update es, en realidad, una eliminacin seguida de una insercin; primero las filas antiguas se copian en la tabla deleted y luego las filas nuevas se copian en la tabla de disparadores y en la tabla inserted . La siguiente ilustracin muestra el estado de las tablas de verificacin de disparadores durante la ejecucin de insert, delete y update. Figure 15-4: Tablas de verificacin de disparadores durante operaciones con insert, delete o update Cuando defina las condiciones de los disparadores, use las tablas de verificacin de disparadores que son adecuadas para la modificacin de datos. Aunque no es un error hacer referencia a eliminated mientras se verifica una instruccin insert ni a inserted mientras se verifica una instruccin delete , estas tablas de verificacin de disparadores no contendrn ninguna fila en estos casos.
Page 228 of 280

Note: Cada disparador se activa una sola vez por consulta. Si las acciones de los disparadores dependen del nmero de filas afectadas por una modificacin de datos, deber usar pruebas, como examinar @@rowcount , para las modificaciones de datos de mltiples filas y llevar a cabo las acciones adecuadas. Los siguientes ejemplos de disparadores albergarn las modificaciones de datos de mltiples filas cuando sea necesario. La variable global @@ rowcount , que almacena el "nmero de filas afectadas" por la ltima operacin de modificacin de datos, comprueba si se ha llevado a cabo una insercin, eliminacin o actualizacin en mltiples filas. Si otra instruccin select precede a la verificacin de @@ rowcount dentro del disparador, deber usar variables locales para almacenar el valor a fin de examinarlo ms adelante. Todas las instrucciones Transact-SQL que no devuelven valores vuelven a definir @@ rowcount en 0. Ejemplo de disparador de insercin Cuando se inserta una nueva fila de clave externa, es conveniente asegurarse de que la clave externa coincide con una clave primaria. El disparador debe verificar si existen combinaciones entre la fila o filas insertadas y las filas de la tabla de clave primaria, y luego revertir las inserciones de claves externas que no coincidan con una de las claves de la tabla de clave primaria. Este ejemplo revierte todos los cambios provocados por la instruccin insert ; en ejemplos posteriores se indica cmo rechazar de forma selectiva algunas modificaciones de datos. Cuando tiene lugar la insercin, se aaden filas nuevas a la tabla de disparadores y a la tabla de verificacin de disparadores inserted . Para verificar si las nuevas claves coinciden con alguna clave primaria, compruebe si existen combinaciones entre inserted y la tabla de clave primaria. El siguiente disparador compara los valores title_id de la tabla inserted con los de la tabla titles . El disparador supone que va a realizar una entrada para la clave externa y que no va a introducir un valor nulo. Si la combinacin falla, la transaccin se revierte. create trigger forinsertrig1 on salesdetail for insert as if (select count(*) from titles, inserted where titles.title_id = inserted.title_id) != @@rowcount /* cancelar la insercin e imprimir un mensaje.*/ begin rollback transaction print "No, a title_id does not exist in titles" end /* En caso contrario, permitirlo. */ else print "Added! All title_id's exist in titles." En este ejemplo, @@ rowcount hace referencia al nmero de filas aadidas a la tabla salesdetail . Tambin es el nmero de filas aadidas a la tabla inserted . La verificacin de si todos los valores title_id aadidos a salesdetail existen en la tabla titles se lleva a cabo combinando titles e inserted . Si el nmero de filas combinadas, que se determina mediante la consulta select count(*) , es diferente de @@ rowcount , una o varias inserciones son incorrectas y toda la transaccin se cancela. Este disparador imprime un mensaje si la insercin se revierte y otro si se acepta. Ejemplo de disparador de eliminacin Cuando se elimina una fila de clave primaria, tambin deben eliminarse las filas de clave externa correspondientes de las tablas dependientes. Esto mantiene la integridad de referencia al garantizar la eliminacin de las filas discpulas cuando se quita la fila maestra. Si esto no se hiciera, podra acabar con una base de datos que tuviera filas discpulas imposibles de recuperar o identificar. Se requiere un disparador que lleve a cabo una eliminacin en cascada. A continuacin se muestra un ejemplo. Cuando se ejecuta una instruccin delete en titles , una o ms filas salen de la tabla titles y se aaden a la eliminida. Un disparador puede comprobar las tablas dependientes ( titleauthor , salesdetail y roysched ) para ver si tienen filas con un valor title_id que coincida con los valores title_id quitados de titles y almacenados ahora en la tabla deleted. Si el disparador encuentra alguna fila de este tipo, la quita. create trigger delcascadetrig on titles for delete as
Page 229 of 280

delete titleauthor from titleauthor, deleted where titleauthor.title_id = deleted.title_id /* Quitar filas de titleauthor que ** coincidan con las filas eliminadas ** (ttulos).*/ delete salesdetail from salesdetail, deleted where salesdetail.title_id = deleted.title_id /* Quitar filas de salesdetail que ** coincidan con las filas eliminadas ** (ttulos).*/ delete roysched from roysched, deleted where roysched.title_id = deleted.title_id /* Quitar filas de roysched que ** coincidan con las filas eliminadas ** (ttulos).*/ En la prctica, es posible que quiera conservar algunas de las filas discpulas. Esto puede ocurrir por razones de mantenimiento de historiales (para verificar cuntas ventas se han realizado en ttulos que ya no se publican cuando estaban activos) o porque haya transacciones incompletas sobre las filas discpulas. Un disparador bien escrito debera tener en cuenta estos factores. Por ejemplo, el disparador deltitle suministrado con la base de datos pubs2 evita la eliminacin de una clave primaria si hay filas discpulas correspondientes a la misma en la tabla salesdetail . Este disparador conserva la capacidad de recuperar filas de salesdetail . create trigger deltitle on titles for delete as if (select count(*) from deleted, salesdetail where salesdetail.title_id = deleted.title_id) > 0 begin rollback transaction print "You can't delete a title with sales." end En este disparador, la fila o filas eliminadas de titles se verifican combinndolas con la tabla salesdetail . Si se encuentra una combinacin, la transaccin se cancela. Ejemplos de disparador de actualizacin Dado que una clave primaria es el identificador nico de su fila y de las filas externas de otras tablas, un intento de actualizar una clave primaria debe realizarse con extremo cuidado. En este caso, desea proteger la integridad de referencia revirtiendo la actualizacin a no ser que se cumplan las condiciones especificadas. Como norma general, es ms adecuado prohibir cualquier cambio de edicin de la clave primaria, por ejemplo, revocando todos los permisos para esa columna. Pero si desea prohibir las actualizaciones slo en determinadas circunstancias, use un disparador. Este disparador evita las actualizaciones de titles.title_id durante el fin de semana. La clusula if update de stopupdatetrig permite centrarse en una columna concreta, titles.title_id . Las modificaciones de los datos de esa columna hacen que el disparador se active. Los cambios de los datos de otras columnas no. Cuando este disparador detecta una actualizacin que viola sus condiciones, cancela la actualizacin e imprime un mensaje. Si desea probar este disparador, sustituya el da actual de la semana por sbado ("Saturday") o domingo ("Sunday"). create trigger stopupdatetrig on titles for update as /* Si se intenta cambiar titles.title_id ** el sbado o domingo, se cancela la actualizacin. */
Page 230 of 280

if update (title_id) and datename(dw, getdate()) in ("Saturday", "Sunday") begin rollback transaction print "We don't allow changes to" print "primary keys on the weekend!" end Tambin puede especificar acciones de disparador mltiples en ms de una columna mediante if update . El siguiente ejemplo modifica stopupdatetrig a fin de incluir acciones de disparador adicionales para las actualizaciones realizadas en titles.price o titles.advance . Adems de evitar las actualizaciones en la clave primaria durante los fines de semana, tambin las evita en el precio o anticipo de un ttulo, a no ser que los ingresos totales de este ttulo sobrepasen la cantidad del anticipo. Es posible usar el mismo nombre de disparador, ya que el disparador modificado sustituye al antiguo al volver a crearlo. create trigger stopupdatetrig on titles for update as if update (title_id) and datename(dw, getdate()) in ("Saturday", "Sunday") begin rollback transaction print "We don't allow changes to" print "primary keys on the weekend!" end if update (price) or update (advance) if (select count(*) from inserted where (inserted.price * inserted.total_sales) < inserted.advance) > 0 begin rollback transaction print "We don't allow changes to price or" print "advance for a title until its total" print "revenue exceeds its latest advance." end Actualizacin de una clave externa Un cambio o actualizacin nicamente en una clave externa constituye con toda probabilidad un error. Una clave externa no es ms que una copia de la clave primaria; nunca deben ser independientes la una de la otra. Si por alguna razn desea permitir actualizaciones en una clave externa, es posible que quiera proteger la integridad creando un disparador que contraste las actualizaciones con la tabla master y las revierta si no coinciden con la clave primaria. En el siguiente ejemplo, el disparador comprueba la existencia de dos fuentes posibles de error: puede ocurrir que title_id no est siquiera en la tabla salesdetail , o que no est en la tabla titles . Este ejemplo usa instrucciones anidadas if...else . La primera instruccin if se cumple cuando el valor de la clusula where de la instruccin update no coincide con ninguno de los valores existentes de salesdetail , es decir, la tabla inserted no contendr ninguna fila y la seleccin devolver un valor nulo. Si esta prueba se supera, la siguiente instruccin if comprueba si la fila o filas nuevas de la tabla inserted se combina con alguna title_id de la tabla titles . Si alguna de las filas no se combina, la transaccin se revierte y se imprime un mensaje de error. Si la combinacin se realiza con xito, se imprime otro mensaje. create trigger forupdatetrig on salesdetail for update as declare @row int /* guardar valor de rowcount */ select @row = @@rowcount if update (title_id) begin if (select distinct inserted.title_id from inserted) is null begin rollback transaction print "No! Old title_id must be in salesdetail"
Page 231 of 280

end else if (select count(*) from titles, inserted where titles.title_id = inserted.title_id) != @row begin rollback transaction print "No! New title_id not in titles" end else print "salesdetail table updated" end Consideraciones sobre filas mltiples Las consideraciones sobre filas mltiples son especialmente importantes en los casos en que la funcin del disparador es recalcular de forma automtica los valores sumarios, es decir, llevar a cabo concordancias continuadas. Los disparadores usados para mantener los valores sumarios deben contener clusulas group by, o subconsultas que realicen agrupaciones implcitas, a fin de crear valores sumarios cuando se inserte, actualice o elimine ms de una fila. Puesto que una clusula group by impone una sobrecarga adicional, los siguientes ejemplos se han escrito para verificar si el valor de @@ rowcount es igual a uno, lo que significa que slo se ha visto afectada una fila de la tabla de disparadores. Si @@ rowcount es igual a uno, las acciones del disparador se llevan a efecto sin la clusula group by . Este disparador de insercin actualiza la columna total_sales de la tabla titles cada vez que se aade una fila nueva a salesdetail . El disparador se activa cada vez que se registra una venta aadiendo una fila a la tabla salesdetail . Actualiza la columna total_sales de la tabla titles de modo que total_sales sea igual a su valor anterior ms el valor aadido a salesdetail.qty . Esto mantiene actualizados los totales para las inserciones de salesdetail.qty . create trigger intrig on salesdetail for insert as /* verificar valor de @@rowcount */ if @@rowcount = 1 update titles set total_sales = total_sales + qty from inserted where titles.title_id = inserted.title_id else /* cuando rowcount sea mayor que 1, ** usar una clusula group by */ update titles set total_sales = total_sales + (select sum(qty) from inserted group by inserted.title_id having titles.title_id = inserted.title_id) El siguiente ejemplo es un disparador de eliminacin que actualiza la columna total_sales de la tabla titles cada vez que se elimina una o ms filas de salesdetail . create trigger deltrig on salesdetail for delete as /* verificar valor de @@rowcount */ if @@rowcount = 1 update titles set total_sales = total_sales - qty from deleted where titles.title_id = deleted.title_id else /* cuando rowcount sea mayor que 1, ** usar una clusula group by */ update titles set total_sales = total_sales - (select sum(qty) from deleted
Page 232 of 280

group by deleted.title_id having titles.title_id = deleted.title_id) Este disparador se activa cada vez que se elimina una fila de la tabla salesdetail . Actualiza la columna total_sales de la tabla titles de modo que total_sales sea igual a su valor anterior menos el valor sustrado de salesdetail.qty . El siguiente disparador de actualizacin actualiza la columna total_sales de la tabla titles cada vez que se actualiza el campo qty de una fila de salesdetail . No olvide que una actualizacin es una insercin seguida de una eliminacin. Este disparador hace referencia a las tablas de verificacin de disparadores inserted y deleted. create trigger updtrig on salesdetail for update as if update (qty) begin /* verificar valor de @@rowcount */ if @@rowcount = 1 update titles set total_sales = total_sales + inserted.qty - deleted.qty from inserted, deleted where titles.title_id = inserted.title_id and inserted.title_id = deleted.title_id else /* cuando rowcount sea mayor que 1, ** usar una clusula group by */ begin update titles set total_sales = total_sales + (select sum(qty) from inserted group by inserted.title_id having titles.title_id = inserted.title_id) update titles set total_sales = total_sales (select sum(qty) from deleted group by deleted.title_id having titles.title_id = deleted.title_id) end end Disparador de insercin condicional Los disparadores examinados hasta aqu han considerado cada instruccin de modificacin de datos como un todo. Si una fila de una insercin de cuatro filas no era aceptable, la insercin en su conjunto se consideraba inaceptable y se reverta la transaccin. Sin embargo, no es necesario revertir todas las modificaciones de datos slo porque algunas de ellas no son aceptables. El uso de una subconsulta correlacionada dentro de un disparador puede obligar al disparador a examinar las filas modificadas de una en una. Consulte el Captulo 5, "Subconsultas: uso de consultas dentro de otras consultas", para obtener ms informacin sobre las subconsultas correlacionadas. Entonces el disparador puede llevar a cabo acciones distintas en filas diferentes. El ejemplo de disparador que se muestra a continuacin supone la existencia de una tabla llamada newsales . Esta es su instruccin create : create table newsales (stor_id char(4) ord_num varchar(20) title_id tid qty smallint discount float

not not not not not

null, null, null, null, null)

Para verificar el disparador condicional, hay que insertar cuatro filas en la tabla newsales , . Dos de las filas de newsales tienen columnas title_id que no coinciden con ninguna de las ya existentes en la tabla titles . Estos son los datos:
Page 233 of 280

newsales stor_id ------7066 7066 7067 7131 ord_num ---------BA27619 BA27619 NB-1.242 Asoap433 title_id --------PS1372 BU7832 PSxxxx PSyyyy qty ---75 100 50 50 discount --------40.000000 40.000000 40.000000 40.000000

Cuando inserta datos de newsales en salesdetail , la instruccin es como sigue: insert salesdetail select * from newsales En caso que se desee examinar cada uno de los registros que se intenta insertar, el disparador conditionalinsert analiza la insercin fila a fila y elimina las filas que no tienen una columna title_id en titles . A continuacin se indica cmo hacerlo: create trigger conditionalinsert on salesdetail for insert as if (select count(*) from titles, inserted where titles.title_id = inserted.title_id) != @@rowcount begin delete salesdetail from salesdetail, inserted where salesdetail.title_id = inserted.title_id and inserted.title_id not in (select title_id from titles) print "Only records with matching title_ids added." end La prueba de disparador es la misma que la del ejemplo intrig , pero la transaccin no se revierte. En lugar de ello, el disparador elimina las filas no deseadas. Esta capacidad de borrar las filas que se acaban de insertar se basa en el orden en que se lleva a cabo el procesamiento cuando los disparadores se activan. Primero se insertan las filas en la tabla y en inserted , y luego se activa el disparador. Reversin de disparadores Es posible revertir los disparadores mediante las instrucciones rollback trigger o rollback transaction (si el disparador se activa como parte de una transaccin). Sin embargo, rollback trigger slo revierte el efecto del disparador y de la instruccin que lo activ. rollback transaction revierte la transaccin en su totalidad. Por ejemplo: begin tran insert into publishers (pub_id) values ('9999') insert into publishers (pub_id) values ('9998') commit tran Si la segunda instruccin insert hace que el disparador de publishers ejecute rollback trigger , slo se ver afectada esa instruccin insert ; la primera instruccin insert no se revierte. Si, en cambio, ese disparador ejecuta rollback transaction , se revierten las dos instrucciones insert como parte de la transaccin. A continuacin se indica la sintaxis de rollback trigger: rollback trigger [with raiserror_statement

La sintaxis de rollback transaction se describe en el Captulo 17, "Transacciones: mantenimiento de la consistencia y recuperacin de datos".

raiserror_statement especifica una instruccin raiserror que imprime un mensaje de error definido por el usuario y establece un
indicador del sistema para registrar que se ha producido una situacin de error. Esto ofrece la posibilidad de presentar un error al cliente cuando se ejecuta rollback trigger , de forma que el estado de transaccin del error refleje la reversin. Por ejemplo:

Page 234 of 280

rollback trigger with raiserror 25002 "title_id does not exist in titles table." Para obtener ms informacin sobre raiserror , consulte el Captulo 13, "Uso de lotes y lenguaje de control de flujo". Cuando se ejecuta rollback trigger , SQL Server aborta el comando en ejecucin y detiene la ejecucin del resto del disparador. Si el disparador que ejecuta rollback trigger est anidado dentro de otros disparadores, SQL Server revierte todo el trabajo realizado en estos disparadores hasta la actualizacin que activ el primer disparador, incluida sta. El siguiente ejemplo de disparador de insercin realiza una tarea similar a la del disparador forinsertrig1 descrito en la . Sin embargo, este disparador utiliza rollback trigger en lugar de rollback transaction para originar un error cuando revierte la insercin pero no la transaccin. create trigger forinsertrig2 on salesdetail for insert as if (select count(*) from titles, inserted where titles.title_id = inserted.title_id) != @@rowcount rollback trigger with raiserror 25003 "Trigger rollback: salesdetail row not added because a title_id does not exist in titles." Cuando los disparadores que incluyen instrucciones rollback transaction se ejecutan desde un lote, dichos disparadores abortan el lote en su totalidad. En el siguiente ejemplo, si la instruccin insert activa un disparador que incluye una instruccin rollback transaction ( como forinsertrig1 ), la instruccin delete no se ejecutar, puesto que el lote se abortar: insert salesdetail values ("7777", "JR123", "PS9999", 75, 40) delete salesdetail where stor_id = "7067" Si los disparadores que incluyen instrucciones rollback transaction se activan desde dentro de una transaccin definida por el usuario , rollback transaction revierte el lote en su totalidad. En el siguiente ejemplo, si la instruccin insert activa un disparador que incluye una instruccin rollback transaction , la instruccin update tambin se revertir: begin tran update stores set payterms = "Net 30" where stor_id = "8042" insert salesdetail values ("7777", "JR123", "PS9999", 75, 40) Consulte el Captulo 17, "Transacciones: mantenimiento de la consistencia y recuperacin de datos", para obtener informacin sobre las transacciones definidas por el usuario. SQL Server ignora una instruccin rollback trigger ejecutada fuera de un disparador y no emite la raiserror asociada con la instruccin. Sin embargo, una instruccin rollback trigger ejecutada fuera de un disparador, pero dentro de una transaccin, genera un error que hace que SQL Server revierta la transaccin y aborte el lote de instrucciones actual. Anidacin de disparadores Los disparadores se pueden anidar a una profundidad de 16 niveles. La anidacin se activa durante la instalacin. El administrador del sistema puede activar y desactivar la anidacin de disparadores con sp_configure . Para inhabilitar la anidacin: sp_configure "allow nested triggers", 0 Si la anidacin de disparadores se habilita, un disparador que modifica una tabla en la que hay otro disparador activa el segundo disparador, que a su vez puede activar un tercer disparador, y as sucesivamente. Si cualquiera de los disparadores de la cadena desencadena un bucle infinito, el nivel de anidacin se sobrepasa y el disparador se aborta. Los disparadores anidados pueden usarse para llevar a cabo funciones de mantenimiento como almacenar una copia de seguridad de las filas afectadas por un disparador anterior. Por ejemplo, puede crear un disparador en titleauthor que guarde una copia de seguridad de las filas de titleauthor borradas por el disparador delcascadetrig . Con el disparador delcascadetrig en efecto, la eliminacin de la title_id "PS2091" de titles
Page 235 of 280

tambin elimina la fila o filas correspondientes de titleauthor . Para guardar los datos, puede crear un disparador delete en titleauthor que guarde los datos eliminados en otra tabla, del_save : create trigger savedel on titleauthor for delete as insert del_save select * from deleted No conviene usar los disparadores en una secuencia dependiente de criterios de ordenacin. Emplee disparadores independientes para efectuar las modificaciones de datos en cascada, como en el ejemplo anterior de delcascadetrig . Note: Cuando se incluyen disparadores en una transaccin, un fallo en cualquier nivel de un conjunto de disparadores anidados (incluido el mensaje de error de que se ha sobrepasado el nivel de anidacin) cancela la totalidad de la transaccin. Todas las modificaciones de datos se revierten. Proporcione sus disparadores con las instrucciones print o raiserror a fin de determinar dnde se ha producido el fallo. La ejecucin de rollback transaction en un disparador en cualquier nivel de anidacin revierte los efectos de todos los disparadores y cancela la transaccin completa. rollback trigger slo afecta a los disparadores anidados y a la instruccin de modificacin de datos que activ el primer disparador. Recurrencia automtica de disparadores De forma predeterminada, un disparador no se llama a s mismo de manera recurrente. Es decir, un disparador de actualizacin no se llama a s mismo en respuesta a una segunda actualizacin de la misma tabla dentro del disparador. Si un disparador de actualizacin de una columna de una tabla tiene como resultado la actualizacin de otra columna, el disparador de actualizacin se activa una sola vez, no repetidamente. Sin embargo, es posible activar la opcin allow self_recursion del comando set a fin de permitir que los disparadores se llamen a s mismos de forma recurrente. La variable de configuracin nested triggers tambin debe habilitarse para que se produzca la recurrencia automtica. El valor self_recursion permanece en efecto slo mientras dura la sesin de cliente actual. Si la opcin se define como parte de un disparador, su efecto queda limitado por el alcance del disparador que la define. Si el disparador que establece self_recursion on devuelve o hace que se active otro disparador, esta opcin vuelve a definirse como off . Una vez que el disparador activa la opcin self_recursion , puede repetirse varias veces si sus propias acciones hacen que se vuelva a activar a s mismo, pero no puede sobrepasar el lmite de 16 niveles de anidacin. Por ejemplo, suponga que la siguiente tabla new_budget existe en la base de datos pubs2 : select * from new_budget unit parent_unit --------------- --------------one_department one_division one_division company_wide company_wide NULL (3 rows affected) Cree un disparador que actualice new_budget de forma recurrente cada vez que se modifique la columna budget , como a continuacin: create trigger budget_change on new_budget for update as if exists (select * from inserted where parent_unit is not null) begin set self_recursion on update new_budget set new_budget.budget = new_budget.budget + inserted.budget - deleted.budget from inserted, deleted, new_budget where new_budget.unit = inserted.parent_unit and new_budget.unit = deleted.parent_unit end
Page 236 of 280

budget ------10 100 1000

Si un usuario actualiza new_budget.budget incrementando el presupuesto de la unidad one_department en 3, SQL Server se comporta como sigue (suponiendo que est habilitada la anidacin de disparadores): 1. 2. 3. 4. Al incrementar one_department de 10 a 13 se activa el disparador budget_change . El disparador actualiza el presupuesto ("budget") del padre de one_department (en este caso, one_division ) de 100 a 103, lo que vuelve a activarlo. El disparador actualiza el padre de one_division (en este caso, company_wide ) de 1000 a 1003, lo que hace que el disparador se active por tercera vez. El disparador intenta actualizar el padre de company_wide , pero, puesto que no existe (NULL), la ltima ejecucin de update nunca llega a producirse y el disparador no se activa, finalizando as la recurrencia automtica. Se puede consultar new_budget para ver los resultados finales que se muestran a continuacin: select * from new_budget unit parent_unit --------------- --------------one_department one_division one_division company_wide company_wide NULL (3 rows affected) Tambin es posible ejecutar un disparador de forma recurrente de otras maneras. Un disparador llama a un procedimiento almacenado que realiza acciones que hace que se active de nuevo (slo se reactiva si est habilitada la anidacin de disparadores). A no ser que existan condiciones dentro del disparador que limiten el nmero de recurrencias, esto provocar un desbordamiento del nivel de anidacin. Por ejemplo, si un disparador de actualizacin llama a un procedimiento almacenado que lleva a cabo una actualizacin, el disparador y el procedimiento almacenado se ejecutan exactamente una vez si nested triggers est desactivada. Si esta opcin est activada y el nmero de actualizaciones no est limitado a menos de 16 por alguna condicin del disparador o el procedimiento, este bucle continuar hasta que sobrepase el valor mximo de 16 niveles de anidacin. Reglas asociadas a los disparadores Aparte de prever los efectos de una modificacin de datos en mltiples filas, las reversiones de los disparadores y la anidacin de disparadores, existen otros factores que deben tenerse en cuenta cuando se escriben disparadores. Disparadores y permisos Un disparador se define en una tabla en particular. Slo el propietario de la tabla tiene los permisos create trigger y drop trigger sobre dicha tabla. Estos permisos no se pueden transferir a otros usuarios. SQL Server acepta definiciones de disparador que intentan llevar a cabo acciones para las que el usuario no tiene permiso. La existencia de un disparador de ese tipo aborta cualquier intento futuro de modificar la tabla de disparadores, puesto que el disparador se ejecuta y falla debido a que los permisos no son correctos. La transaccin se cancelar. Ser necesario rectificar la situacin de los permisos u omitir el disparador. Por ejemplo, Jose es el propietario de salesdetail y crea un disparador en ella. Se supone que el disparador debe actualizar titles.total_sales cuando se actualice salesdetail.qty . Sin embargo, Mary es la propietaria de titles y no ha concedido a Jose el permiso sobre titles . Cuando Jose intenta actualizar salesdetail , SQL Server detecta el disparador y que Jose no tiene permisos sobre titles , y revierte la transaccin de actualizacin. Jose deber obtener de Mary el permiso de actualizacin para titles.total_sales u omitir el disparador de salesdetail . Restricciones de los disparadores A continuacin se describen algunas limitaciones o restricciones impuestas a los disparadores por SQL Server:

budget ------13 103 1003

Una tabla puede tener un mximo de tres disparadores: uno de actualizacin, uno de insercin y uno de eliminacin. Cada disparador puede aplicarse a una sola tabla. Sin embargo, un mismo disparador se puede aplicar a las tres acciones del usuario: update , insert y delete . No se puede crear un disparador en una vista ni en una tabla temporal, aunque los disparadores pueden hacer referencia a las vistas o tablas temporales. Aunque la instruccin truncate table es, en realidad, como una instruccin delete sin la clusula where porque quita todas las filas, no puede "activar" un disparador porque las eliminaciones individuales de fila no se registran.
Page 237 of 280

Los disparadores no se permiten en las tablas del sistema. Aunque no aparece ningn mensaje de error si crea un disparador en una tabla del sistema, el disparador no se utilizar.

Valores nulos implcitos y explcitos if update ( column_name ) es verdadero para una instruccin insert siempre que a la columna se le asigna un valor en la lista de seleccin o en la clusula values . La introduccin de un valor NULL explcito o un valor predeterminado asigna un valor a una columna y, por consiguiente, activa el disparador. Sin embargo, un valor NULL implcito no lo activa. Estos ejemplos clarifican la situacin: create table junk (a int null, b int not null) create trigger junktrig on junk for insert as if update(a) and update(b) print "FIRING" /*"if update" es verdadero para ambas columnas. ** Se activa el disparador.*/ insert junk (a, b) values (1, 2) /*"if update" es verdadero para ambas columnas. ** Se activa el disparador.*/ insert junk values (1, 2) /*NULL explcito: **"if update" es verdadero para ambas columnas. ** Se activa el disparador.*/ insert junk values (NULL, 2) /* ** ** insert Si hay un valor predeterminado para la columna a, "if update" es verdadero para ambas columnas. Se activa el disparador.*/ junk (b) values (2)

/* Si no hay ningn valor predeterminado en la ** columna a, "if update" no es verdadero para ** la columna a. El disparador no se activa.*/ insert junk (b)values (2) Los resultados seran los mismos si slo se usara la clusula: if update(a) Para crear un disparador que no permita la insercin de valores nulos implcitos, puede usar: if update(a) or update(b) De este modo, las instrucciones SQL del disparador pueden verificar si a o b es nulo. Disparadores y rendimiento En trminos de rendimiento, la sobrecarga de disparador es generalmente muy baja. El tiempo invertido en ejecutar un disparador se emplea principalmente para hacer referencia a otras tablas, que pueden estar en memoria o en el dispositivo de base de datos. Las tablas de verificacin de disparadores deleted e inserted siempre estn en la memoria activa. La ubicacin de otras tablas a las que hace referencia el disparador determina la cantidad de tiempo necesaria para realizar la operacin. Comandos set en los disparadores
Page 238 of 280

Es posible utilizar el comando set dentro de un disparador. La opcin set que se ejecuta permanece en efecto durante la ejecucin del disparador y despus recupera su valor anterior. Cambio de nombre y disparadores Si cambia el nombre de un objeto al que hace referencia un disparador, debe omitir el disparador y volver a crearlo de forma que su texto refleje el nombre nuevo del objeto al que hace referencia. Emplee el procedimiento sp_depends para obtener un informe de los objetos a los que hace referencia un disparador. El curso de accin ms seguro es no cambiar el nombre de ninguna tabla o vista a las que haga referencia un disparador. Obtencin de informacin sobre disparadores Como objetos de base de datos que son, los disparadores se enumeran en sysobjects por nombre. La columna type de sysobjects identifica los disparadores con la abreviatura "TR". La siguiente consulta busca los disparadores que existen en una base de datos: select * from sysobjects where type = "TR" La instruccin create trigger correspondiente a cada disparador se almacena en syscomments . Se puede mostrar la definicin de un disparador con el procedimiento del sistema sp_helptext . Los planes de ejecucin de los disparadores se almacenan en sysprocedures . Varios procedimientos del sistema proporcionan informacin de las tablas del sistema sobre los disparadores.

sp_help
Se puede obtener un informe sobre un disparador con el procedimiento del sistema sp_help . Por ejemplo, puede obtener informacin sobre deltitle como a continuacin: sp_help deltitle Name Owner Type ----------- ------- ----------deltitle dbo trigger Data_located_on_segment ----------------------no es aplicable (return status = 0) When_created ----------------Feb 9 1987 3:56PM

sp_helptext
Para mostrar el texto de la instruccin create trigger , ejecute el procedimiento del sistema sp_helptext : sp_helptext deltitle # Lines of Text --------------1 text --------------------------------------------create trigger deltitle on titles for delete as if (select count(*) from deleted, salesdetail where salesdetail.title_id = deleted.title_id) >0 begin rollback transaction print "You can't delete a title with sales." end

sp_depends
Page 239 of 280

El procedimiento del sistema sp_depends muestra todos los disparadores que hacen referencia al objeto o todas las tablas y vistas afectadas por el disparador. Este ejemplo indica cmo utilizar sp_depends para obtener una lista de todos los objetos a los que hace referencia el disparador deltitle : sp_depends deltitle Cosas a las que hace referencia el objeto en la base de datos actual. object ---------------dbo.salesdetail dbo.titles (return status = 0) Esta instruccin muestra todos los objetos que hacen referencia a la tabla salesdetail : sp_depends salesdetail Cosas incluidas en la base de datos actual que hacen referencia al objeto. object --------------------------dbo.deltitle dbo.history_proc dbo.insert_salesdetail_proc dbo.totalsales_trig (return status = 0) Chapter 16 type ---------------disparador procedimiento almacenado procedimiento almacenado disparador type updated ---------- ------user table no user table no selected -------no no

Cursores: acceso a los datos fila por fila


Una instruccin select devuelve cero o ms filas. Si devuelve varias filas, puede manipular cada fila de forma individual mediante cursores. En este captulo se trata lo siguiente:

Introduccin general a los cursores Declaracin y apertura de cursores Obtencin de datos utilizando cursores Actualizacin o eliminacin de datos utilizando cursores Cierre y desasignacin de cursores Un ejemplo del uso de cursores Efecto del bloqueo sobre los cursores Obtencin de informacin sobre cursores Definicin de cursores Declaracin de cursores Apertura de cursores Recuperacin de filas de datos mediante cursores Actualizacin y eliminacin de filas utilizando cursores Cierre y desasignacin de cursores Ejemplo del uso de cursores Uso de cursores en procedimientos almacenados Cursores y bloqueo Obtencin de informacin sobre cursores

Definicin de cursores Un cursor es el nombre simblico asociado a una instruccin select Transact-SQL mediante una instruccin de declaracin. Se compone de las siguientes partes:
Page 240 of 280

Conjunto de resultados del cursor : el conjunto (tabla) de filas que resulta de ejecutar una consulta asociada al cursor. Posicin del cursor : un puntero en una fila dentro del conjunto de resultados del cursor

La posicin del cursor indica la fila actual del cursor. Puede modificar o eliminar la fila de forma explcita utilizando las instrucciones delete o update con una clusula que especifique el cursor. Puede cambiar la posicin actual del cursor mediante una operacin llamada recuperacin . Una recuperacin desplaza hacia abajo la posicin actual del cursor una o ms filas en el conjunto de resultados del cursor. Un cursor se comporta en gran medida como un puntero de archivo hacia una serie de registros de archivos, donde el cursor acta como un puntero hacia los resultados de la consulta. Sin embargo, los cursores slo admiten el movimiento hacia delante (o secuencial) a travs de los resultados de la consulta. Una vez que se han recobrado varias filas, no es posible volver hacia atrs en el conjunto de resultados del cursor para acceder a ellas de nuevo. Este proceso permite examinar los resultados de una consulta fila por fila. Despus de declarar el cursor, ste se encuentra en uno de estos dos estados:

Cerrado : el conjunto de resultados del cursor no existe, por lo que no es posible leer informacin en l. Los cursores se encuentran inicialmente en este estado. Es necesario abrir el cursor de forma explcita para poder utilizarlo. Una vez abierto, puede cerrarlo de forma explcita despus de terminar. SQL Server puede cerrar un cursor de forma implcita por varias razones, explicadas posteriormente en este captulo. Abierto: las filas del conjunto de resultados del cursor se encuentran disponibles para su lectura o actualizacin.

Se puede cerrar un cursor y despus volver a abrirse. La reapertura de un cursor vuelve a crear el conjunto de resultados del cursor y coloca el cursor delante de la primera fila. Esto permite progresar por un conjunto de resultados del cursor tantas veces como sea necesario. El cursor se puede cerrar en cualquier momento, sin necesidad de examinar todo su conjunto de resultados. Todas las operaciones de cursor, como recobrar o actualizar una fila, se llevan a cabo en referencia a la posicin actual del cursor. Actualizar una fila del cursor implica modificar los datos de la fila o eliminar sta por completo. No es posible utilizar los cursores para insertar filas. Todas las actualizaciones realizadas mediante un cursor afectan a las tablas base correspondientes incluidas en el conjunto de resultados del cursor. Modo en que SQL Server procesa los cursores Al acceder a los datos mediante cursores, SQL Server divide el proceso en las siguientes operaciones:

Declaracin del cursorSQL Server crea la estructura del cursor y compila la consulta definida para ste. Almacena el plan de consulta compilado, pero no lo ejecuta. Apertura del cursorSQL Server ejecuta el plan de consulta. Realiza un barrido de las tablas base (en la medida en que sea necesario, como con un select normal) y crea el conjunto de resultados del cursor. Prepara cualquier tabla temporal generada por la consulta y asigna recursos (como memoria) para dar soporte a la estructura del cursor. Tambin coloca el cursor delante de la primera fila de su conjunto de resultados. Recuperacin desde el cursor SQL Server desplaza la posicin del cursor hacia abajo una o ms filas en su conjunto de resultados. Recupera los datos de cada fila del conjunto de resultados y almacena la posicin actual, permitiendo posteriores recuperaciones hasta alcanzar el final del conjunto de resultados. Actualizacin o eliminacin mediante el cursor SQL Server actualiza o elimina los datos del conjunto de resultados del cursor (y las tablas base correspondientes de las que se han derivado los datos) en la posicin en que se encuentre el cursor despus de una recuperacin. Esta operacin es opcional. Cierre del cursorSQL Server cierra el conjunto de resultados del cursor, quita las tablas temporales que quedan y libera los recursos del servidor retenidos para la estructura del cursor. Sin embargo, conserva el plan de consulta del cursor para poder abrirlo de nuevo. Desasignacin del cursorSQL Server vuelca el plan de consultas de la memoria y elimina toda huella de la estructura del cursor. Es preciso volver a declarar el cursor antes de utilizarlo.

Declaracin de cursores Debe declarar un cursor para poder utilizarlo. La declaracin especifica la consulta que, a su vez, define el conjunto de resultados del cursor. Puede definir un cursor como actualizable o de slo lectura de forma explcita mediante las palabras clave for update o for read only . En caso de omitirlas, SQL Server determina si el cursor es actualizable basndose en el tipo de consulta que define su conjunto de resultados. No es posible utilizar las instrucciones update o delete con el conjunto de resultados de un cursor de slo lectura.
Page 241 of 280

Sintaxis de declare cursor La sintaxis de la instruccin declare cursor es: declare cursor_name cursor for select_statement [for {read only | update [of

column_name_list

]}]

La instruccin declare cursor debe preceder a cualquier instruccin open del cursor. No es posible combinar declare cursor con otras instrucciones del mismo lote Transact-SQL, excepto al usar el cursor en un procedimiento almacenado.

select_statement es la consulta que define el conjunto de resultados del cursor para cursor_name . En general, select_statement puede utilizar la sintaxis y semntica completas de una instruccin select Transact-SQL, incluida la palabra
clave holdlock . Sin embargo, no puede contener una clusula compute , for browse o into .

Por ejemplo, la siguiente instruccin declare cursor define un conjunto de resultados para el cursor authors_crsr , que contiene todos los autores que no residen en California: declare authors_crsr cursor for select au_id, au_lname, au_fname from authors where state != 'CA'

select_statement puede contener referencias a nombres de parmetros de Transact-SQL o variables locales. Sin embargo, los

nombres slo pueden hacer referencia a parmetros y variables locales definidas en un procedimiento almacenado que contenga la instruccin declare cursor . Si se utiliza el cursor en un disparador, select_statement tambin puede hacer referencia a las tablas temporales inserted y deleted utilizadas en los disparadores. Para obtener informacin adicional sobre el uso de la instruccin select , consulte el Captulo 2, "Consultas: seleccin de datos de una tabla". Alcance del cursor Un cursor viene definido por su alcance , que determina la regin en que est presente el cursor. Una vez que el alcance del cursor deja de existir, tambin desaparece su nombre. El alcance de los cursores viene definido por las siguientes regiones:

Sesin: esta regin comienza cuando un cliente se conecta a SQL Server y termina al desconectarse. Esta regin es distinta de las regiones definidas por procedimientos almacenados o disparadores. Procedimiento almacenado: esta regin se inicia cuando un procedimiento almacenado comienza su ejecucin y finaliza cuando la termina. Si un procedimiento almacenado llama a otro, SQL Server inicia una regin nueva y la trata como subregin del primer procedimiento. Disparador: esta regin se inicia cuando un disparador comienza su ejecucin y finaliza cuando la completa.

Un cursor debe tener un nombre nico dentro de un alcance dado. Puesto que cada alcance es distinto, un nombre de cursor definido en una regin tambin puede definirse en otra regin o en su propia subregin. No es posible acceder a un cursor definido en una regin desde otra regin. Sin embargo, SQL Server permite el acceso de un cursor a una subregin si no existe ningn otro cursor con el mismo nombre en ella. SQL Server detecta conflictos de nombre dentro de un alcance concreto slo durante el tiempo de ejecucin. Un procedimiento almacenado o un disparador pueden definir dos cursores con el mismo nombre si slo se ejecuta uno. Por ejemplo: create procedure proc1 (@flag int) as if (@flag) declare names_crsr cursor for select au_fname from authors else declare names_crsr cursor for select au_lname from authors return Este procedimiento almacenado funciona porque slo est definido un cursor names_crsr en su alcance. Barridos del cursor y el conjunto de resultados del cursor

Page 242 of 280

Es posible que las filas del conjunto de resultados del cursor no reflejen los valores de las filas de la tabla base real. Por ejemplo, un cursor declarado con una clusula order by requiere generalmente la creacin de una tabla interna para ordenar las filas del conjunto de resultados del cursor. SQL Server no bloquea las filas de la tabla base correspondientes a las filas de la tabla interna, permitiendo que otros clientes actualicen dichas filas de la tabla base. En este caso, las filas devueltas al cliente desde el conjunto de resultados del cursor no estarn sincronizadas con las filas de la tabla base. Un conjunto de resultados del cursor se genera a medida que las filas son devueltas mediante un fetch de dicho cursor. Esto significa que una consulta select del cursor se procesa como una consulta select normal. Este proceso, conocido como barridos de cursor , proporciona un tiempo de retorno ms rpido y elimina la necesidad de leer filas que la aplicacin no precisa. SQL Server requiere que los barridos de cursor utilicen un ndice nico de una tabla, sobre todo para lecturas con un nivel de aislamiento 0. Si la tabla tiene una columna IDENTITY y necesita crear un ndice no nico en ella, utilice la opcin de base de datos identity in nonunique index para incluir automticamente una columna IDENTITY en las claves de ndice de la tabla y hacer que todos los ndices creados en la tabla sean nicos. Esta opcin de base de datos hace que los ndices lgicamente no nicos sean internamente nicos y permite usarlos para procesar cursores actualizables en lecturas con un nivel de aislamiento 0. Sin embargo, todava puede emplear cursores que hagan referencia a tablas sin ndices, si no se actualiza ninguna de estas tablas con otro proceso que haga cambiar la posicin actual de la fila. Por ejemplo: declare storinfo_crsr cursor for select stor_id, stor_name, payterms from stores where state = 'CA' La tabla stores especificada con el cursor anterior no tiene ningn ndice. SQL Server permite la declaracin de cursores en tablas sin ndices nicos, pero cualquier actualizacin o eliminacin que mueva la posicin de las filas en estas tablas cierra todos los cursores de las mismas. Conversin de los cursores en actualizables Se puede actualizar o eliminar una fila devuelta por un cursor si ste es actualizable. Si el cursor es de slo lectura, slo podr leer los datos, pero no actualizarlos ni eliminarlos. De forma predeterminada, SQL Server intenta determinar si un cursor es actualizable antes de designarlo como de slo lectura. Se puede especificar si un cursor es actualizable o no explcitamente utilizando las palabras clave read only o update en la instruccin declare . El siguiente ejemplo define un conjunto de resultados actualizable para el cursor pubs_crsr : declare pubs_crsr cursor for select pub_name, city, state from publishers for update of city, state El ejemplo anterior incluye todas las filas de la tabla publishers , pero slo define explcitamente las columnas city y state para su actualizacin. A menos que planee actualizar o eliminar filas mediante un cursor, debe declarar ste como de slo lectura. Si no especifica read only o update explcitamente, el cursor es actualizable implcitamente cuando la instruccin select no contiene ninguno de los siguientes elementos:

Opcin distinct Clusula group by Funcin agregada Subconsulta Operador union Clusula at isolation read uncommitted

No es posible especificar la clusula for update si la select_statement del cursor contiene una de las estructuras anteriores. SQL Server tambin define un cursor como de slo lectura si se declaran ciertos tipos de cursores que incluyen una clusula order by como parte de su select_statement . Para obtener ms informacin, consulte la seccin sobre cursores en el Manual de Referencia de SQL Server .

Page 243 of 280

Si no especifica una column_name_list con la clusula for update , todas las columnas especificadas en la consulta son actualizables. Como se ha descrito anteriormente para los barridos de cursor, SQL Server intenta utilizar ndices nicos con los cursores actualizables al barrer la tabla base. Para los cursores, SQL Server considera un ndice que contenga una columna IDENTITY como ndice nico, aunque no est declarado como tal. SQL Server permite incluir columnas en la column_name_list que no estn especificadas en la lista de columnas de la select_statement del cursor, pero que formen parte de las tablas indicadas en select_statement . En el siguiente ejemplo, SQL Server utiliza el ndice nico de la columna pub_id de publishers (aunque pub_id no est incluida en la definicin de newpubs_crsr ): declare newpubs_crsr cursor for select pub_name, city, state from publishers for update Si no especifica la clusula for update , SQL Server elige cualquier ndice nico, aunque tambin puede utilizar otros ndices o barridos de tabla si no existe ningn ndice nico para las columnas especificadas. Sin embargo, cuando se especifica for update , SQL Server debe utilizar un ndice nico definido en una o varias columnas para barrer la tabla base. Si no hay ningn ndice nico, devolver un error. Las columnas de la tabla base especificadas en la column_name_list de for update deben incluir slo las que se van a actualizar, y ninguna columna incluida en al menos un ndice nico. Esto permite que SQL Server utilice dicho ndice nico para su barrido de cursor, lo que ayuda a evitar una actualizacin anmala llamada problema Halloween . Este problema se produce cuando un cliente actualiza una columna de una fila del conjunto de resultados del cursor que define el orden en que se devuelven las filas de las tablas base. Por ejemplo, si SQL Server accede a una tabla base utilizando un ndice y el cliente actualiza la clave del ndice, la fila del ndice actualizada puede moverse dentro de ste y ser leda nuevamente por el cursor. Esto es resultado de que un cursor actualizable slo crea de forma lgica un conjunto de resultados del cursor. El conjunto de resultados del cursor se compone realmente de las tablas base de las que se deriva el cursor. Apertura de cursores Despus de declarar el cursor, debe abrir ste para realizar una operacin fetch , update o delete de las filas. La apertura de un cursor hace que SQL Server evale la instruccin select que define el cursor y deje disponible el conjunto de resultados del cursor para su procesamiento. La sintaxis de open es: open cursor_name

Despus de abrir un cursor, ste se coloca delante de la primera fila de su conjunto de resultados. Utilice fetch para acceder a la primera fila. SQL Server no permite abrir un cursor si ste ya est abierto o no se ha definido con la instruccin declare cursor . Puede volver a abrir un cursor cerrado para restablecer su posicin al principio del conjunto de resultados. Recuperacin de filas de datos mediante cursores Despus de declarar y abrir un cursor, puede recobrar filas de su conjunto de resultados con el comando fetch . Este comando devuelve una o ms filas al cliente que est extrayendo los datos de columna de la fila. Si lo desea, puede incluir parmetros de Transact-SQL o variables locales con fetch para almacenar valores de columna. Sintaxis de fetch La sintaxis de la instruccin fetch es: fetch cursor_name [into fetch_target_list ]

Por ejemplo, despus de declarar y abrir el cursor authors_crsr , puede recobrar la primera fila de su conjunto de resultados de la siguiente manera: fetch authors_crsr

Page 244 of 280

au_id ----------341-22-1782

au_lname au_fname ------------------- --------------Smith Meander

Cada fetch posterior recupera otra fila del conjunto de resultados del cursor. Por ejemplo: fetch authors_crsr au_id au_lname au_fname ----------- ------------------- --------------527-72-3246 Greene Morningstar Despus de recobrar todas las filas, el cursor apuntar a la ltima fila del conjunto de resultados. Si ejecuta fetch de nuevo, SQL Server devuelve una advertencia a travs de la variable @@sqlstatus (descrita ms abajo) indicndo que no hay ms datos. La posicin del cursor no se altera. No es posible recobrar una fila que ya se ha recuperado, ni volver atrs en un conjunto de resultados del cursor. Se puede cerrar y reabrir el cursor para generar el conjunto de resultados del cursor nuevamente e iniciar la recuperacin desde el principio. La clusula into especifica que SQL Server introduce datos de columna en las variables indicadas. La fetch_target_list debe componerse de parmetros de Transact-SQL o variables locales declarados anteriormente. Por ejemplo, despus de declarar las variables @name , @city y @state , puede recobrar filas del cursor pubs_crsr como se indica a continuacin: fetch pubs_crsr into @name, @city, @state SQL Server espera una correspondencia recproca entre las variables de la fetch_target_list y las expresiones de la lista de destino especificadas en la select_statement que define el cursor. Los tipos de datos de las variables o parmetros deben ser compatibles con los de las columnas del conjunto de resultados del cursor. Verificacin del estado del cursor SQL Server devuelve un valor de estado despus de cada recuperacin. Puede acceder al valor mediante la variable global @@sqlstatus . La siguiente tabla enumera valores de @@sqlstatus posibles y su significado: Tabla 16-1: Valores de @@sqlstatus Valor Significado 0 1 2 Indica que la instruccin f etch se ha completado correctamente. Indica que la instruccin f etch ha dado como resultado un error. Indica que no hay ms datos en el conjunto de resultados. Esta advertencia puede aparecer si la posicin actual del cursor es la ltima fila del conjunto de resultados y el cliente enva una instruccin f etch a ese cursor.

El siguiente ejemplo determina la @@sqlstatus del cursor authors_crsr abierto: select @@sqlstatus --------0 (1 row affected) Slo una instruccin fetch puede definir la @@sqlstatus . Ninguna otra instruccin tiene efecto sobre esta variable. Verificacin del nmero de filas recobradas SQL Server tambin proporciona la variable global @@rowcount . . @@rowcount permite controlar el nmero de filas del conjunto de resultados del cursor devueltas al cliente hasta la ltima recuperacin. En otras palabras, representa el nmero total de filas vistas por el cursor en un momento dado. Una vez ledas todas las filas de un conjunto de resultados del cursor, @@rowcount representa el nmero total de filas de dicho conjunto de resultados. Cada cursor abierto est asociado a una variable @@rowcount especfica. Esta se omite al cerrar el
Page 245 of 280

cursor. Verificando @@rowcount despus de una operacin de fetch , obtendr el nmero de filas ledas con el cursor especificado en dicha operacin fetch . El siguiente ejemplo determina la @@rowcount del cursor authors_crsr abierto: select @@rowcount --------1 (1 row affected) Obtencin de mltiples filas con cada fetch De forma predeterminada, el comando fetch slo devuelve una fila cada vez. Se puede utilizar la opcin cursor rows del comando set para cambiar el nmero de filas devueltas por fetch . Sin embargo, esta opcin no afecta a una recuperacin que contenga una clusula into . La sintaxis de set es: set cursor rows number for cursor_name

donde number especifica el nmero de filas del cursor. El valor predeterminado es 1 para cada cursor declarado. Se puede definir la opcin cursor rows para un cursor con independencia de que est abierto o cerrado. Por ejemplo, se puede cambiar el nmero de filas recobradas por el cursor authors_crsr de la siguiente manera: set cursor rows 3 for authors_crsr Despus, cada recuperacin de authors_crsr devuelve 3 filas del conjunto de resultados del cursor: fetch authors_crsr au_id au_lname ----------- ------------------648-92-1872 Blotchet-Halls 712-45-1867 del Castillo 722-51-5424 DeFrance

au_fname --------------Reginald Innes Michel

El cursor se coloca en la ltima fila recobrada (el autor Michel DeFrance, en el ejemplo anterior). La recuperacin de varias filas al mismo tiempo es especialmente adecuada para aplicaciones cliente. Si recobra ms de una fila, Open Client o Embedded SQL(TM) coloca las filas enviadas a la aplicacin cliente en la memoria intermedia automticamente. El cliente todava ve un acceso fila por fila, pero cada fetch genera menos llamadas a SQL Server, lo que mejora el rendimiento. Actualizacin y eliminacin de filas utilizando cursores Si el cursor es actualizable, puede utilizar las instrucciones update y delete para actualizar o eliminar filas. SQL Server determina si el cursor es actualizable verificando la select_statement que define el cursor. Tambin puede definir un cursor como actualizable de forma explcita con la clusula for update de la instruccin declare cursor . Consulte "Conversin de los cursores en actualizables" para obtener ms informacin. Eliminacin de filas del conjunto de resultados del cursor Mediante la clusula where current of de la instruccin delete , puede eliminar la fila de la posicin actual del cursor. Al eliminar una fila del conjunto de resultados del cursor, tambin se elimina de la tabla de base de datos subyacente. Slo es posible eliminar una fila cada vez con el cursor. La sintaxis de delete...where current of es: delete [from] [[ where current of database .] cursor_name owner .]{ table_name | view_name }

Page 246 of 280

El table_name o view_name especificado con delete ... where current of debe ser la tabla o vista especificada en la primera clusula from de la instruccin select que define el cursor. Por ejemplo, se puede eliminar la fila a la que apunta actualmente el cursor authors_crsr de la siguiente manera: delete from authors where current of authors_crsr La palabra clave from del ejemplo anterior es opcional. Note: No es posible eliminar una fila de un cursor definido por una instruccin select que contenga una combinacin, aunque el cursor sea actualizable. Despus de eliminar una fila de un cursor, SQL Server coloca el cursor delante de la siguiente fila de su conjunto de resultados. Todava debe utilizar fetch para tener acceso a la fila siguiente. Si elimina la ltima fila del conjunto de resultados del cursor, SQL Server coloca el cursor despus de la ltima fila del conjunto de resultados. Por ejemplo, despus de eliminar la fila actual en el ejemplo anterior (el autor Michel DeFrance), se pueden recobrar los siguientes 3 autores en el conjunto de resultados del cursor (suponiendo que cursor rows todava est definido como 3): fetch authors_crsr au_id au_lname ----------- ------------------807-91-6654 Panteley 899-46-2035 Ringer 998-72-3567 Ringer

au_fname --------------Sylvia Anne Albert

Evidentemente, puede eliminar una fila de la tabla base sin hacer referencia a un cursor. El conjunto de resultados del cursor cambia a medida que se realizan cambios en la tabla base. Actualizacin de filas del conjunto de resultados del cursor Mediante la clusula where current of de la instruccin update , puede actualizar la fila de la posicin actual del cursor. Cualquier actualizacin del conjunto de resultados del cursor tambin afecta a la fila de la tabla base de la que se deriva la fila del cursor. La sintaxis de update...where current of es: update [[ database .] owner .]{ table_name | view_name } set [[[ database .] owner .]{ table_name .| view_name .}] column_name 1 = { expression 1 |NULL|( select_statement )} [, column_name 2 = { expressio n2 |NULL|( select_statement )}]... where current of cursor_name La clusula set especifica el nombre de columna del conjunto de resultados del cursor y asigna el valor nuevo. Cuando se enumeran varios pares del tipo nombre de columna/valor, deben ir separados por comas.

table_name o view_name debe ser la tabla o vista especificada en la primera clusula from de la instruccin select que define

el cursor. Si dicha clusula from hace referencia a ms de una tabla o vista (mediante una combinacin), slo podr especificar la tabla o vista que est actualizando en ese momento. Por ejemplo, puede actualizar la fila a la que apunta el cursor pubs_crsr del siguiente modo: update publishers set city = "Pasadena", state = "CA" where current of pubs_crsr Despus de la actualizacin, la posicin del cursor permanece igual. Se puede continuar actualizando la fila de esa posicin del cursor siempre que otra instruccin Transact-SQL no lo desplace.

Page 247 of 280

SQL Server permite actualizar columnas que no estn especificadas en la lista de columnas de la select_statement , pero forman parte de las tablas indicadas en esta instruccin. Sin embargo, cuando especifica una column_name_list con update , slo es posible actualizar las columnas indicadas en ella. Cierre y desasignacin de cursores Cuando termine con el conjunto de resultados del cursor, puede cerrarlo mediante close . La sintaxis de close es: close cursor_name

El cierre del cursor no cambia su definicin. Se puede volver a abrir con open y SQL Server crear un conjunto de resultados del cursor nuevo utilizando la misma consulta que antes. Por ejemplo: close authors_crsr open authors_crsr Despus, puede recobrar desde authors_crsr , empezando por el principio de su conjunto de resultados. Cualquier condicin asociada a dicho cursor (como el nmero de filas recobradas, definido por set cursor rows ) permanece en vigor. Por ejemplo: fetch authors_crsr au_id au_lname ----------- ------------------341-22-1782 Smith 527-72-3246 Greene 648-92-1872 Blotchet-Halls

au_fname --------------Meander Morningstar Reginald

Si quiere desechar el cursor, debe desasignarlo mediante deallocate . La sintaxis de deallocate es: deallocate cursor cursor_name

La desasignacin de un cursor libera cualquier recurso asociado con l, incluido el nombre del cursor. No puede volver a utilizar un nombre de cursor hasta que lo desasigne. Si desasigna un cursor abierto, SQL Server lo cierra automticamente. La finalizacin de una conexin cliente a un servidor tambin cierra y desasigna cualquier cursor abierto. Ejemplo del uso de cursores El siguiente ejemplo de cursor utiliza esta consulta: select author = au_fname + " " + au_lname, au_id from authors order by au_lname Los resultados de la consulta son: author ------------------------Abraham Bennet Reginald Blotchet-Halls Cheryl Carson Michel DeFrance Ann Dull Marjorie Green Morningstar Greene Burt Gringlesby Sheryl Hunter Livia Karsen Chastity Locksley Stearns MacFeather Heather McBadden Michael O'Leary Sylvia Panteley Anne Ringer Albert Ringer au_id ----------409-56-7008 648-92-1872 238-95-7766 722-51-5454 427-17-2319 213-46-8915 527-72-3246 472-27-2349 846-92-7186 756-30-7391 486-29-1786 724-80-9391 893-72-1158 267-41-2394 807-91-6654 899-46-2035 998-72-3567
Page 248 of 280

Meander Smith Dick Straight Dirk Stringer Johnson White Akiko Yokomoto Innes del Castillo

341-22-1782 274-80-9391 724-08-9931 172-32-1176 672-71-3249 712-45-1867

Los siguientes pasos muestran el modo de utilizar un cursor con la consulta anterior: 1. Declare el cursor. Esta instruccin declare cursor define un cursor utilizando la instruccin select mostrada anteriormente: declare newauthors_crsr cursor for select author = au_fname + " " + au_lname, au_id from authors order by au_lname 2. Una vez declarado el cursor, puede abrirlo: open newauthors_crsr 3. Ahora puede recobrar filas utilizando el cursor: fetch newauthors_crsr author ------------------------Abraham Bennet 4.

au_id ----------409-56-7008

Se pueden recobrar varias filas al mismo tiempo especificando el nmero de filas con el comando set : set cursor rows 5 for newauthors_crsr fetch newauthors_crsr author au_id ----------------------------------Reginald Blotchet-Halls 648-92-1872 Cheryl Carson 238-95-7766 Michel DeFrance 722-51-5454 Ann Dull 427-17-2319 Marjorie Green 213-46-8915 Cada fetch posterior devuelve cinco filas ms: fetch newauthors_crsr author ------------------------Morningstar Greene Burt Gringlesby Sheryl Hunter Livia Karsen Chastity Locksley

au_id ----------527-72-3246 472-27-2349 846-92-7186 756-30-7391 486-29-1786

5.

Una vez que haya terminado con el cursor, puede cerrarlo: close newauthors_crsr El cierre del cursor libera el conjunto de resultados, pero el cursor se mantiene definido. Si lo abre de nuevo, SQL Server vuelve a ejecutar la consulta y coloca el cursor delante de la primera fila de su conjunto de resultados. El cursor todava est definido para devolver cinco filas con cada fetch .

6.

El comando deallocate se utiliza para convertir al cursor en no definido: deallocate cursor newauthors_crsr No puede volver a utilizar el nombre del cursor hasta que se desasigne el mismo.
Page 249 of 280

Uso de cursores en procedimientos almacenados Los cursores son especialmente tiles en procedimientos almacenados. Permiten llevar a cabo la misma tarea utilizando slo una consulta que, de otro modo, requerira varias. Sin embargo, todas las operaciones del cursor deben ejecutarse dentro de un solo procedimiento. Un procedimiento almacenado no puede abrir, recobrar o cerrar un cursor que no est declarado en el procedimiento. El cursor no est definido fuera del alcance del procedimiento almacenado. Por ejemplo, el siguiente procedimiento almacenado au_sales verifica la tabla sales para ver si algn libro de un autor concreto se ha vendido bien: create procedure au_sales (@author_id id) as /*declarar variables locales usadas para recobrar */ declare @title_id tid declare @title varchar(80) declare @ytd_sales int declare @msg varchar(120) /* declarar el cursor para recobrar los libros ** escritos por un autor concreto */ declare author_sales cursor for select ta.title_id, t.title, t.total_sales from titleauthor ta, titles t where ta.title_id = t.title_id and ta.au_id = @author_id open author_sales fetch author_sales into @title_id, @title, @ytd_sales if (@@sqlstatus = 2) begin print "We do not sell books by this author." close author_sales return end /* si el conjunto de resultados del cursor no est ** vaco, procesar cada fila de informacin */ while (@@sqlstatus = 0) begin if (@ytd_sales = NULL) begin select @msg = @title + " had no sales this year." print @msg end else if (@ytd_sales < 500) begin select @msg = @title + " had poor sales this year." print @msg end else if (@ytd_sales < 1000) begin select @msg = @title + " had mediocre sales this year." print @msg end else begin select @msg = @title + " had good sales this year." print @msg end fetch author_sales into @title_id, @title, @ytd_sales end
Page 250 of 280

/* si se genera un error, llamar al manipulador ** designado */ if (@@sqlstatus = 1) exec error_handle close author_sales deallocate cursor author_sales return Para obtener ms informacin sobre los procedimientos almacenados, consulte el Captulo 14, "Uso de procedimientos almacenados". Cursores y bloqueo Los mtodos de bloqueo de cursores son similares a los mtodos de bloqueo actuales de SQL Server. En general, las instrucciones que leen datos (tales como select o readtext ) utilizan bloqueos compartidos en cada pgina de datos para evitar la lectura de datos modificados por una transaccin no consignada. Las instrucciones de actualizacin utilizan bloqueos exclusivos en cada pgina que modifican. Para reducir los bloqueos insolubles y mejorar la simultaneidad, SQL Server sita con frecuencia un bloqueo exclusivo delante de un bloqueo de actualizacin, el cual indica que el cliente piensa cambiar datos de la pgina. Con los cursores actualizables, SQL Server utiliza bloqueos de actualizacin de forma predeterminada al barrer tablas o vistas referenciadas con la clusula for update de declare cursor . Si se incluye for update , pero la lista est vaca, todas las referencias a tablas y vistas de la clusula from de la select_statement reciben bloqueos de actualizacin predeterminadamente. Si no incluye la clusula for update , las tablas y vistas referenciadas reciben bloqueos compartidos. Puede indicar a SQL Server que utilice bloqueos compartidos en lugar de bloqueos de actualizacin aadiendo la palabra clave shared a la clusula from . De forma especfica, aada shared despus de cada nombre de tabla para la que prefiera un bloqueo compartido . Para obtener informacin sobre el bloqueo de SQL Server, consulte la Gua de Administracin del Sistema . Para obtener ms informacin sobre cursores y bloqueos, consulte el Manual de Referencia de SQL Server . Obtencin de informacin sobre cursores SQL Server proporciona el procedimiento del sistema sp_cursorinfo , que muestra informacin sobre el nombre del cursor, su estado actual (como abierto o cerrado) y sus columnas de resultados. El siguiente ejemplo muestra informacin sobre el cursor authors_crsr : sp_cursorinfo 0, authors_crsr El nombre de cursor 'authors_crsr' est declarado en el nivel anidado '0'. El id del cursor es 327681 El cursor se abri con xito 1 veces El cursor se compil con un nivel de aislamiento 1. El cursor no est abierto. El cursor permanecer abierto cuando una transaccin se confirme o se elimine. El nmero de filas devuelto para cada FETCH es 1. El cursor es actualizable. Este cursor devolvi 3 columnas. Las columnas de resultado son: Nombre = 'au_id', Tabla = 'authors', Tipo = ID, Longitud = 11 (actualizable) Nombre = 'au_lname', Tabla = 'authors', Tipo = VARCHAR, Longitud = 40 (acutalizable) Nombre = 'au_fname', Tabla = 'authors', Tipo = VARCHAR, Longitud = 20 (actualizable) Para obtener ms informacin sobre sp_cursorinfo , consulte el Manual de Referencia de SQL Server . Chapter 17

Page 251 of 280

Transacciones: mantenimiento de la consistencia y recuperacin de datos


Las transacciones proporcionan un modo de agrupar instrucciones Transact-SQL a fin de que sean tratadas como una unidad. Se ejecutan todas las instrucciones del grupo, o ninguna. En este captulo se trata lo siguiente:

Introduccin general a las transacciones Uso de instrucciones agrupadas en una transaccin Definicin de modos y niveles de aislamiento de transacciones Funcionamiento de procedimientos almacenados y disparadores con transacciones Funcionamiento de cursores con transacciones Copia de seguridad y recuperacin de transacciones Definicin de transaccin Uso de transacciones Seleccin del modo y nivel de aislamiento de las transacciones Uso de transacciones en procedimientos almacenados y disparadores Uso de cursores en transacciones Copia de seguridad y recuperacin de transacciones

Definicin de transaccin Una transaccin es un mecanismo para garantizar que un conjunto de una o ms instrucciones SQL se trate como una sola unidad de trabajo. SQL Server maneja automticamente todos los comandos de modificacin de datos, incluidas las solicitudes de cambio de un solo paso, como transacciones. De forma predeterminada, cada instruccin insert , update y delete se considera una sola transaccin. Puede agrupar un conjunto de instrucciones SQL en una transaccin definida por el usuario con los comandos begin transaction , commit transaction y rollback transaction . begin transaction marca el comienzo de un bloque de transacciones. Todas las instrucciones posteriores, hasta una rollback transaction o una commit transaction coincidente, se incluyen como parte de la transaccin. Las transacciones permiten a SQL Server garantizar:

La consistencia de los datos: las consultas y solicitudes de cambio simultneas no pueden colisionar entre s y los usuarios nunca ven ni emplean los datos que estn en proceso de cambio. La capacidad de recuperacin de los datos: en caso de un fallo del sistema, la recuperacin de la base de datos es completa y automtica.

Para poder utilizar las transacciones compatibles con las normas SQL, SQL Server proporciona opciones que permiten seleccionar el modo y el nivel de aislamiento de las transacciones. Las aplicaciones que requieren transacciones compatibles con las normas SQL deberan definir dichas opciones al comienzo de cada sesin. Los modos y niveles de aislamiento de las transacciones se describen ms adelante en este captulo. Transacciones y consistencia En un entorno multiusuario, SQL Server debe evitar que las consultas y solicitudes de modificacin de datos simultneas interfieran entre s. Esto es importante porque si los datos procesados por una consulta pudieran ser cambiados por la actualizacin de otro usuario mientras la consulta est en ejecucin, los resultados de la consulta seran ambiguos. SQL Server define automticamente el nivel adecuado de bloqueo para cada transaccin. Puede hacer que los bloqueos compartidos sean ms restrictivos consulta a consulta incluyendo la palabra clave holdlock en una instruccin select . Las transacciones definidas por el usuario permiten a los usuarios indicar a SQL Server que procese cualquier nmero de instrucciones SQL como una sola unidad. Dichas transacciones se explican ms adelante en otra seccin. Transacciones y recuperacin

Page 252 of 280

Una transaccin es una unidad de trabajo y una unidad de recuperacin. El hecho de que SQL Server manipule las solicitudes de cambio de un solo paso como transacciones significa que la base de datos puede recuperarse completamente en caso de fallos. El tiempo de recuperacin de SQL Server se mide en minutos y segundos. Se puede especificar el tiempo de recuperacin mximo aceptable. Los comandos SQL relacionados con la recuperacin y copia de seguridad se explican en "Copia de seguridad y recuperacin de transacciones". Uso de transacciones begin transaction y commit transaction indican a SQL Server que procese cualquier nmero de comandos individuales como una sola unidad. rollback transaction deshace la transaccin, bien hasta su comienzo, bien hasta un punto de resguardo. Puede definir un punto de resguardo dentro de una transaccin con el comando save transaction . Las transacciones definidas por el usuario proporcionan control sobre el manejo de la transaccin. Tambin mejoran el rendimiento, dado que la sobrecarga del sistema se alcanza una vez por transaccin en lugar de una vez para cada comando individual. Note: La agrupacin de un gran nmero de comandos Transact-SQL en una transaccin de larga duracin puede afectar al tiempo de recuperacin. Si SQL Server falla antes de que la transaccin se consigne, la recuperacin llevar ms tiempo, porque SQL Server debe deshacer la transaccin. Cualquier usuario puede definir una transaccin. No se requiere ningn permiso para ninguno de los comandos de la transaccin. Las siguientes secciones contienen temas generales sobre transacciones y comandos de transaccin, con ejemplos. Para obtener ms informacin sobre las transacciones, consulte el Manual de Referencia de SQL Server . Uso de comandos de definicin de datos en transacciones Pueden utilizar determinados comandos del lenguaje de definicin de datos en transacciones definiendo la opcin ddl in tran de sp_dboption como verdadera. Si ddl in tran es verdadera en una base de datos concreta, es posible emitir comandos como create table , grant y alter table dentro de transacciones en esa base de datos. Si ddl in tran es verdadera en la base de datos model , es posible emitir los comandos dentro de transacciones en todas las bases de datos creadas despus de que ddl in tran se definiese como verdadera en model . Warning! La nica situacin en la que est justificado el uso de comandos del lenguaje de definicin de datos dentro de transacciones es en create schema . Los comandos del lenguaje de definicin de datos establecen bloqueos sobre las tablas del sistema, como sysobjects . Si usa comandos del lenguaje de definicin de datos dentro de transacciones, stas debern ser de longitud reducida. En particular, evite utilizar comandos del lenguaje de definicin de datos en tempdb dentro de transacciones, porque, de lo contrario, el sistema puede llegar a detenerse. Siempre debe dejar ddl in tran establecido como falso en tempdb . Para definir ddl in tran como verdadera, escriba: sp_dboption mydb,"ddl in tran", true El primer parmetro especifica el nombre de la base de datos donde debe definir la opcin. Es necesario estar usando la base de datos master para ejecutar sp_dboption . Cualquier usuario puede ejecutar sp_dboption sin parmetros para mostrar los valores de opcin actuales. Sin embargo, para definir opciones, es preciso ser un administrador del sistema o el propietario de la base de datos. Los siguientes comandos se permiten en una transaccin definida por el usuario slo si la opcin ddl in tran de sp_dboption est definida como verdadera: Tabla 17-1: Comandos DDL no permitidos en transacciones create default drop default grant alter table (se permiten clusulas distintas de partition y unpartition ) create index drop index revoke create procedure drop procedure
Page 253 of 280

create rule create schema create table create trigger create view

drop rule drop table drop trigger drop view

Los procedimientos del sistema que cambian la base de datos master o que crean tablas temporales no pueden utilizarse dentro de transacciones definidas por el usuario. Nunca debe utilizar los siguientes comandos dentro de una transaccin definida por el usuario: Tabla 17-2: Comandos DDL no permitidos en transacciones alter database alter table...partition alter table...unpartition create database disk init load transaction select into dump database load database update statistics dump transaction reconfigure truncate table drop database

Es posible verificar el valor actual de ddl in tran con sp_helpdb . Inicio y consignacin de transacciones Los comandos begin transaction y commit transaction pueden incluir cualquier nmero de instrucciones SQL y procedimientos almacenados. Las sintaxis de ambas instrucciones es: begin {transaction | tran} [ transaction_name ] commit {transaction | tran | work} [ transaction_name

transaction_name es el nombre asignado a la transaccin y debe cumplir con las reglas para identificadores.
Las palabras clave transaction , tran y work (en commit transaction ) son sinnimas: puede utilizar una en lugar de las otras. Sin embargo, transaction y tran son extensiones Transact-SQL; slo work es compatible con las normas SQL. A continuacin se muestra un ejemplo bsico: begin tran statement procedure statement commit tran commit transaction no afecta a SQL Server si no hay ninguna transaccin activa. Reversin y guardado de transacciones Si una transaccin debe cancelarse antes de que se consigne, ya sea por un fallo o por un cambio por parte del usuario, todas las instrucciones o procedimientos finalizados debern deshacerse. Puede cancelar o revertir una transaccin con el comando rollback transaction en cualquier momento antes de que se introduzca el comando commit transaction . Si utiliza puntos de resguardo, puede cancelar una transaccin completa o parte de la misma. Sin embargo, no es posible cancelar una transaccin una vez consignada. La sintaxis del comando rollback transaction es: rollback {transaction | tran | work} [ transaction_name | savepoint_name ]

Un punto de resguardo es un marcador que el usuario coloca dentro de una transaccin para indicar el punto hasta donde es posible realizar la reversin. Los puntos de resguardo se insertan incluyendo un comando save transaction dentro de la transaccin. La sintaxis es:
Page 254 of 280

save {transaction | tran}

savepoint_name

El nombre del punto de resguardo debe cumplir con las reglas para identificadores. Si no se proporciona ningn nombre de punto de resguardo ( savepoint_name ) ni ningn nombre de transaccin ( transaction_name ) con el comando rollback transaction , la transaccin se revierte al primer comando begin transaction de un lote. A continuacin se indica cmo utilizar los comandos save transaction y rollback transaction : begin tran transaction_name statement statement procedure save tran savepoint_name statement rollback tran savepoint_name statement statement rollback tran El primer comando rollback transaction revierte la transaccin hasta el punto de resguardo situado dentro de la transaccin. El segundo comando rollback transaction revierte la transaccin hasta su comienzo. Si una transaccin se revierte a un punto de resguardo, debe continuar hasta su finalizacin o cancelarse por completo. Hasta que se emite commit transaction , SQL Server considera todas las instrucciones subsiguientes como parte de la transaccin, a menos que se encuentre con otra instruccin begin transaction . En este punto, SQL Server considera todas las instrucciones subsiguientes como parte de esta nueva transaccin anidada. Las transacciones anidadas se describen en la prxima seccin. rollback transaction o save transaction no afectan a SQL Server y no devuelven ningn mensaje de error si no hay ninguna transaccin activa. Verificacin del estado de las transacciones La variable global @@transtate realiza un seguimiento del estado actual de una transaccin. SQL Server determina qu estado debe devolver realizando un seguimiento de los cambios de transaccin que puedan tener lugar despus de la ejecucin de la instruccin. @@transtate puede contener los siguientes valores: Tabla 17-3: Valores de @@transtate Valor Significado 0 1 2 3 Transaccin en proceso. Hay una transaccin implcita o explcita en efecto; la instruccin anterior se ha ejecutado de forma correcta. Transaccin ejecutada de forma correcta. La transaccin ha finalizado y ha consignado sus cambios. Instruccin abortada. La instruccin anterior se ha abortado; no ha tenido ningn efecto sobre la transaccin. Transaccin abortada. La transaccin se ha abortado y ha revertido los cambios efectuados.

En una transaccin, es posible utilizar @@transtate despus de una instruccin (como insert ) para determinar si se ha ejecutado de forma correcta o se ha abortado y su efecto sobre la transaccin. El siguiente ejemplo verifica @@transtate durante una transaccin (tras una operacin insert correcta) y despus de que la transaccin se consigne: begin transaction insert into publishers (pub_id) values ('9999') (1 row affected) select @@transtate ---------0 (1 row affected) commit transaction select @@transtate
Page 255 of 280

---------1 (1 row affected) El siguiente ejemplo verifica @@transtate despus de una operacin insert no correcta (debido a una violacin de regla) y despus de que la transaccin se revierta: begin transaction insert into publishers (pub_id) values ('7777') Msg 552, Level 16, State 1: Una columna insertada o actualizada entra en conflicto con una regla vinculada a la columna. El comando ha sido abortado. El conflicto se produjo en la base de 'pubs2', tabla 'publishers', regla 'pub_idrule', columna 'pub_id'. select @@transtate ---------2 (1 row affected) rollback transaction select @@transtate ---------3 (1 row affected) Sin embargo, a diferencia de @@error , SQL Server no borra @@transtate despus de cada instruccin. Cambia @@transtate slo como respuesta a una accin llevada a cabo por una transaccin. Transacciones anidadas Es posible anidar transacciones dentro de otras transacciones. Cuando se anidan las instrucciones begin transaction y commit transaction , el par ms exterior es el que inicia y consigna la transaccin. Los pares interiores slo mantienen un seguimiento del nivel de anidacin. SQL Server no consigna la transaccin hasta que se emite la instruccin commit transaction que coincide con la instruccin begin transaction ms exterior. SQL Server proporciona una variable global, @@trancount , que mantiene un seguimiento del nivel de anidacin actual de las transacciones. Una instruccin begin transaction incial implcita o explcita define @@ trancount en 1. Cada begin transaction subsiguiente aumenta @@trancount y commit transaction la reduce. La activacin de un disparador tambin incrementa @@ trancount y la transaccin se inicia con la instruccin que activa el disparador. Las transacciones anidadas no se consignan hasta que @@trancount es igual a 0. Por ejemplo, SQL Server no consigna los siguientes grupos de instrucciones anidados hasta la instruccin commit transaction final: begin tran select @@trancount /* @@trancount = 1 */ begin tran select @@trancount /* @@trancount = 2 */ begin tran select @@trancount /* @@trancount = 3 */ commit tran commit tran commit tran select @@trancount /* @@ trancount = 0 */ Cuando se anida una instruccin rollback transaction sin incluir un nombre de transaccin o punto de resguardo, siempre revierte a la instruccin begin transaction ms exterior y cancela la transaccin.
Page 256 of 280

Ejemplo de una transaccin definida por el usuario Este ejemplo muestra el modo en que se podra especificar una transaccin definida por el usuario: begin transaction royalty_change /* ** ** /* ** ** Un usuario trata de cambiar la divisin de derechos de autor de los dos autores de The Gourmet Microwave. */ Dado que la base de datos sera inconsistente entre las dos actualizaciones, deben agruparse en una transaccin. */

update titleauthor set royaltyper = 65 from titleauthor, titles where royaltyper = 75 and titleauthor.title_id = titles.title_id and title = "The Gourmet Microwave" update titleauthor set royaltyper = 35 from titleauthor, titles where royaltyper = 25 and titleauthor.title_id = titles.title_id and title = "The Gourmet Microwave" save transaction percent_changed /* ** ** ** ** ** Una vez actualizadas las entradas royaltyper de los dos autores, el usuario inserta el punto de resguardo "percent_changed" y luego verifica cmo afectara un aumento del 10% en el precio a las ganancias por derechos de autor de los autores. */

update titles set price = price * 1.1 where title = "The Gourmet Microwave" select (price * royalty * total_sales) * royaltyper from titles, titleauthor, roysched where title = "The Gourmet Microwave" and titles.title_id = titleauthor.title_id and titles.title_id =roysched.title_id rollback transaction percent_changed /* ** ** ** La transaccin se revierte al punto de resguardo con el comando rollback transaction. Sin un punto de resguardo, se revertera al principio de la transaccin. */

commit transaction

Seleccin del modo y nivel de aislamiento de las transacciones SQL Server proporciona dos opciones que pueden definirse para dar soporte a las transacciones compatibles con las normas SQL. Estas opciones definen el modo y el nivel de aislamiento de las transacciones, y deberan definirse al comienzo de cada sesin que requiera transacciones compatibles con normas SQL. SQL Server admite los siguientes modos de transaccin:

El modo predeterminado, llamado no encadenado o modo Transact-SQL, requiere instrucciones begin transaction explcitas emparejadas con instrucciones commit transaction o rollback transaction para completar la transaccin.

Page 257 of 280

El modo compatible con las normas SQL, llamado modo encadenado , inicia una transaccin de forma implcita antes de cualquier instruccin de recuperacin o modificacin de datos. Estas instrucciones incluyen: delete , insert , open , fetch , select y update . Sin embargo, es necesario finalizar la transaccin explcitamente con commit transaction o rollback transaction .

Puede definir los dos modos mediante la opcin chained del comando set . Sin embargo, no debera mezclar estos modos de transaccin en las aplicaciones. El comportamiento de los procedimientos almacenados y los disparadores puede variar segn el modo y es posible que precise una accin especial para ejecutar un procedimiento en un modo que se cre en el otro. SQL Server admite los siguientes niveles de aislamiento para las transacciones:

Nivel 0 - SQL Server garantiza que los datos escritos por una transaccin representen los datos reales. Este nivel evita que otras transacciones escriban sobre los mismos datos antes de que la transaccin se consigne. Los otras transacciones pueden leer los datos no consignados. Nivel 1 - SQL Server garantiza que los datos ledos por una transaccin representen los datos reales, no los datos del proceso de otra transaccin no consignada. Este es el nivel de aislamiento predeterminado soportado por SQL Server. Nivel 3 - SQL Server garantiza que los datos ledos por una transaccin sean vlidos hasta el final de dicha transaccin. SQL Server da soporte a este nivel mediante la palabra clave holdlock de la instruccin select que aplica un bloqueo de lectura en los datos especificados.

Es posible definir el nivel de aislamiento de la sesin mediante la opcin transaction isolation level del comando set . Puede imponer el nivel de aislamiento slo para una consulta en lugar de usar la clusula at isolation de la instruccin select . En las siguientes secciones se describen estas opciones de forma ms detallada. Seleccin de un modo de transaccin Las normas SQL requieren que todas las instrucciones SQL de recuperacin y modificacin de datos tengan lugar dentro de una transaccin. Una transaccin se inicia de forma automtica con la primera instruccin de recuperacin o modificacin de datos despus del inicio de una sesin o despus de que la transaccin anterior se consigne o aborte. Este es el modo de transaccin encadenado. Puede definir este modo para la sesin actual mediante la activacin de la opcin chained de la instruccin set . Por ejemplo: set chained on Sin embargo, no puede ejecutar el comando set chained dentro de una transaccin. Para volver al modo no encadenado de las transacciones, defina la opcin chained como off . El modo predeterminado es no encadenado. En el modo encadenado de las transacciones, SQL Server ejecuta de forma implcita una instruccin begin transaction justo antes de las siguientes instrucciones de recuperacin o modificacin de datos: delete , insert , open , fetch , select y update . Por ejemplo, el siguiente grupo de instrucciones genera diferentes resultados dependiendo del modo que se utilice: insert into publishers values ('9999', null, null, null) begin transaction delete from publishers where pub_id = '9999' rollback transaction En el modo no encadenado, rollback slo afecta a la instruccin delete , por lo que publishers todava contiene la fila insertada. En el modo encadenado, la instruccin insert inicia de forma implcita una transaccin y la reversin afecta a todas las instrucciones hasta el comienzo de dicha transaccin, incluida la instruccin insert . Aunque el modo encadenado inicia de forma implcita las transacciones con instrucciones de recuperacin o modificacin de datos, slo puede anidar transacciones mediante el uso explcito de instrucciones begin transaction . Una vez que comienza la primera transaccin implcitamente, las instrucciones de recuperacin o modificacin de datos posteriores dejan de iniciar transacciones hasta despus de que la primera transaccin se consigne o aborte. Por ejemplo, en la siguiente consulta, la primera instruccin commit transaction consigna todos los cambios en modo encadenado; la segunda instruccin commit no es necesaria: insert into publishers values ('9999', null, null, null) insert into publishers
Page 258 of 280

values ('9997', null, null, null) commit transaction commit transaction Note: En el modo encadenado, una instruccin de recuperacin o modificacin de datos inicia una transaccin independientemente de que se ejecute de forma correcta. Incluso una instruccin select que no acceda a una tabla comienza una transaccin. Puede verificar la variable global @@tranchained para determinar el modo de transaccin actual de SQL Server. select @@tranchained devuelve 0 para el modo no encadenado o 1 para el encadenado. Seleccin de un nivel de aislamiento La norma SQL92 define cuatro niveles de aislamiento para las transacciones. Cada nivel de aislamiento especifica los tipos de acciones que no estn permitidos cuando se ejecutan transacciones concurrentes. Los niveles ms altos incluyen las restricciones impuestas por los niveles ms bajos:

El nivel 0 evita que otras transacciones cambien los datos que ya han sido modificados (mediante insert , delete , update , etc.) por una transaccin no consignada. Las otras transacciones se bloquean para que no modifiquen los datos hasta que la transaccin se haya consignado. No obstante, las otras transacciones todava pueden leer los datos no consignados, lo que da lugar a lecturas sucias . El nivel 1 evita las lecturas sucias. Estas lecturas tienen lugar cuando una transaccin modifica una fila y luego una segunda transaccin lee esa misma fila antes de que la primera transaccin haya podido consignar el cambio. Si la primera transaccin revierte el cambio, la informacin leda por la segunda transaccin se convierte en invlida. El nivel 2 evita las lecturas no repetidas . Estas lecturas tienen lugar cuando una transaccin lee una fila y luego una segunda transaccin modifica dicha fila. Si la segunda transaccin consigna el cambio, las lecturas subsiguientes realizadas por la primera transaccin producen resultados diferentes a los de la primera lectura. El nivel 3 evita las lecturas fantasma . Estas lecturas tienen lugar cuando una transaccin lee un conjunto de filas que cumplen una condicin de bsqueda y luego una segunda transaccin modifica los datos (mediante una instruccin insert , delete , update , etc.). Si la primera transaccin repite la lectura con las mismas condiciones de bsqueda, el conjunto de filas resultante es distinto.

De forma predeterminada, el nivel de aislamiento de transaccin de SQL Server es 1. La norma SQL92 establece que el nivel predeterminado de todas las transacciones sea 3 para evitar las lecturas sucias, no repetidas y fantasma. Para imponer este nivel de aislamiento, Transact-SQL proporciona la opcin transaction isolation level de set . Esta opcin indica a SQL Server que aplique de forma automtica una accin holdlock a todas las opciones select de una transaccin. Por ejemplo: set transaction isolation level 3 Las aplicaciones que emplean transaction isolation level 3 deberan definir este nivel de aislamiento al principio de cada sesin. Sin embargo, el uso de transaction isolation level 3 hace que SQL Server retenga los bloqueos de lectura durante la ejecucin de la transaccin. Si tambin utiliza el modo de transaccin encadenado, ese nivel de aislamiento permanece en efecto para cualquier instruccin de recuperacin o modificacin de datos que inicie una transaccin de forma implcita. En ambos casos, esto puede originar problemas de concurrencia para algunas aplicaciones, ya que es posible que se retengan ms bloqueos durante periodos de tiempo ms largos. Para volver a asignar el nivel de aislamiento predeterminado de SQL Server a la sesin actual: set transaction isolation level 1 Si se define transaction isolation level 0 al principio de cada sesin, las aplicaciones no afectadas por las lecturas sucias pueden presenciar una concurrencia menos problemtica y un nivel de bloqueo insoluble reducido cuando acceden a los mismos datos. Un ejemplo es una aplicacin que halla el saldo promedio momentneo de todas las cuentas de ahorro almacenadas en un tabla. Dado que slo necesita una captacin instantnea del saldo promedio actual, que probablemente cambia con frecuencia en una tabla activa, la aplicacin debera consultar la tabla con un nivel de aislamiento 0. Las aplicaciones que precisen una consistencia de datos, como los ingresos y extracciones de cuentas especficas de la tabla, deberan evitar el nivel 0. Las consultas ejecutadas con el nivel de aislamiento 0 no adquieren ningn bloqueo de lectura durante sus operaciones de barrido, por lo que no impiden a otras transacciones que escriban en los mismos datos, ni viceversa. Sin embargo, aunque defina su nivel de aislamiento en 0, las utilidades (como dbcc ) e instrucciones de modificacin de datos (como update ) todava adquieren bloqueos de lectura para sus tareas de barrido, ya que deben mantener la integridad de la base de datos cerciorndose de que se han ledo los datos correctos antes de modificarlos.

Page 259 of 280

La variable global @@isolation contiene el nivel de aislamiento actual de la sesin de Transact-SQL. Al consultar @@isolation se obtiene el valor del nivel activo (0, 1 o 3). Por ejemplo: select @@isolation -------1 (1 row affected) Para obtener ms informacin sobre los niveles de aislamiento y el bloqueo, consulte la Gua de Mejora de Rendimiento y Afinacin . Cambio del nivel de aislamiento de una consulta Puede cambiar el nivel de aislamiento de una consulta usando la clusula at isolation con las instrucciones select o readtext . Las opciones read uncommitted , read committed y serializable de at isolation representan cada nivel de aislamiento al igual que se indica a continuacin: Opcin de at isolation Nivel de aislamiento read uncommited read committed serializable 0 1 3

Por ejemplo, las dos instrucciones siguientes consultan la misma tabla con los niveles de aislamiento 0 y 3, respectivamente: select * from titles at isolation read uncommitted select * from titles at isolation serializable La clusula at isolation slo es vlida para consultas select y readtext individuales o en la instruccin declare cursor . SQL Server devuelve un error de sintaxis si at isolation se utiliza:

Con una consulta que usa la clusula into Dentro de una subconsulta Con una consulta en la instruccin create view Con una consulta en la instruccin insert Con una consulta que usa la clusula for browse

Si hay un operador union en la consulta, debe especificar la clusula at isolation despus de la ltima instruccin select . La norma SQL92 define read uncommitted , read committed y serializable como opciones para at isolation (y set transaction isolation level ). Una extensin Transact-SQL tambin permite especificar 0, 1 o 3 para at isolation . Para simplificar la explicacin sobre los niveles de aislamiento, los ejemplos de at isolation de este manual no usan esta extensin. Tambin puede imponer el nivel de aislamiento 3 usando la palabra clave holdlock de la instruccin select . Sin embargo, no es posible especificar holdlock , noholdlock ni shared en una consulta que tambin indica at isolation read uncommitted . Si emplea distintas formas de definir un nivel de aislamiento, la palabra clave holdlock tiene prioridad sobre la clusula at isolation (salvo el nivel de aislamiento 0) y esta clusula tiene prioridad sobre el nivel de sesin definido por set transaction isolation level . Cursores y niveles de aislamiento Puede utilizar la clusula at isolation de la instruccin select para cambiar el nivel de aislamiento de un cursor. Por ejemplo: declare commit_crsr cursor for select * from titles at isolation read committed
Page 260 of 280

Esta instruccin hace que el cursor funcione con el nivel de aislamiento 1, sea cual sea el nivel de la transaccin o sesin. Si declara un cursor con el nivel de aislamiento 0 ( read uncommitted ), SQL Server tambin define el cursor como de slo lectura. No es posible especificar la clusula for update con at isolation read uncommitted en una instruccin declare cursor . SQL Server establece el nivel de aislamiento de un cursor al abrirlo, no al declararlo. Una vez abierto el cursor, SQL Server determina su nivel de aislamiento conforme a lo siguiente:

Si el cursor se declara con la clusula at isolation , este nivel de aislamiento reemplaza al nivel de aislamiento de transaccin con el que se abre. Si el cursor no se declara con at isolation , dicho cursor utiliza el nivel de aislamiento con el que se abre. Si cierra el cursor y luego lo vuelve a abrir, el cursor adquiere el nivel de aislamiento actual de la transacccin.

Con respecto al ltimo punto, es necesario resaltar que algunos tipos de cursores (idioma y cliente) declarados en una transaccin con el nivel de aislamiento 1 o 3 no pueden abrirse en una transaccin con el nivel 0. Para obtener ms informacin sobre esta restriccin y los distintos tipos de cursores, consulte el Manual de Referencia de SQL Server. Procedimientos almacenados y niveles de aislamiento Los procedimientos almacenados del sistema de Sybase siempre funcionan con el nivel de aislamiento 1, sea cual sea el nivel de la transaccin o sesin. Los procedimientos almacenados del usuario utilizan el nivel de aislamiento de la transaccin donde se ejecutan. Si el nivel de aislamiento cambia dentro de un procedimiento almacenado, el nivel nuevo slo permanece en efecto durante la ejecucin del procedimiento almacenado. Disparadores y niveles de aislamiento Como los disparadores se activan mediante instrucciones de modificacin de datos (como insert ), todos los disparadores se ejecutan con el nivel de aislamiento de la transaccin o con el 1, el que sea mayor. En consecuencia, si un disparador se activa en una transaccin con el nivel 0, SQL Server define el nivel de aislamiento del disparador en 1 antes de ejecutar su primera instruccin. Uso de transacciones en procedimientos almacenados y disparadores Es posible utilizar transacciones en procedimientos almacenados y disparadores del mismo modo que con los lotes de instrucciones. Si una transaccin de un lote o procedimiento almacenado llama a otro procedimiento almacenado o disparador que contiene una transaccin, la segunda transaccin se anida en la primera. La primera instruccin begin transaction explcita o implcita (que usa el modo encadenado) inicia la transaccin del lote, procedimiento almacenado o disparador. Cada begin transaction subsiguiente aumenta el nivel de anidacin. Cada commit transaction subsiguiente reduce el nivel de anidacin hasta que alcanza el 0. A continuacin, SQL Server consigna la transaccin completa. rollback transaction aborta la transaccin completa hasta la primera instruccin begin transaction , independientemente del nivel de anidacin o el nmero de procedimientos almacenados y disparadores que abarque. En los procedimientos almacenados y disparadores, el nmero de instrucciones begin transaction debe coincidir con el nmero de instrucciones commit transaction . Esto tambin se aplica a los procedimientos almacenados que utilizan el modo encadenado. La primera instruccin que inicia implcitamente una transaccin tambin debe tener una commit transaction coincidente. El siguiente diagrama muestra lo que puede ocurrir cuando se anidan instrucciones de transaccin dentro de procedimiento almacenados: Figure 17-5: Anidacin de instrucciones de transaccin Las instrucciones rollback transaction incluidas en procedimientos almacenados no afectan a las instrucciones subsiguientes del procedimiento o lote que llam originalmente al procedimiento. SQL Server ejecuta las instrucciones subsiguientes del procedimiento almacenado o lote. Sin embargo, las instrucciones rollback transaction en disparadores abortan el lote a fin de que las instrucciones subsiguientes no se ejecuten. Por ejemplo, el siguiente lote llama al procedimiento almacenado myproc que incluye una instruccin rollback transaction : begin tran update titles set ... insert into titles ...
Page 261 of 280

execute myproc delete titles where ... Las instrucciones update e insert se revierten y la transaccin se aborta. SQL Server contina el lote y ejecuta la instruccin delete . Sin embargo, si hay un disparador insert en una tabla que incluye rollback transaction , se aborta todo el lote y delete no se ejecuta. Por ejemplo: begin tran update authors set ... insert into authors ... delete authors where ... El uso de diferentes modos o niveles de aislamiento de transaccin para procedimientos almacenados tiene determinados requisitos, que se describen en la siguiente seccin. Los disparadores no se ven afectados por el modo de transaccin actual, puesto que siempre son llamados como parte de una instruccin de modificacin de datos. Modos y niveles de aislamiento de transaccin en procedimientos almacenados Los procedimientos almacenados escritos para utilizar el modo no encadenado de las transacciones puede ser incompatible con otras transacciones que usan el modo encadenado, y viceversa. Por ejemplo, a continuacin se muestra un procedimiento almacenado vlido que utiliza el modo encadenado: create proc myproc as insert into publishers values ('9999', null, null, null) commit work Un programa que utilice el modo no encadenado de transacciones fallara si llamase a este procedimiento porque commit no tiene el comando correspondiente begin . Es posible encontrar otros problemas:

Las aplicaciones que inician una transaccin que utiliza el modo encadenado pueden crear transacciones increiblemente largas o retener bloqueos de datos durante toda su sesin. Este comportamiento reduce el rendimiento de SQL Server. Las aplicaciones pueden anidar transacciones en momentos imprevistos. Esto puede generar resultados diferentes dependiendo del modo de transaccin.

Como norma general, las aplicaciones que utilizan un modo de transaccin deberan llamar a procedimientos almacenados escritos para usar el mismo modo. Las excepciones a dicha regla son los procedimientos almacenados del sistema SYBASE (que no incluyen a sp_procxmode descrito ms adelante), que pueden ser llamados por sesiones que utilizan cualquier modo de transaccin. Si no hay ninguna transaccin activa al ejecutar un procedimiento almacenado del sistema, SQL Server desactiva el modo encadenado durante la ejecucin del procedimiento. Antes de volver, el programa restablece el parmetro original del modo. SQL Server etiqueta todos los procedimientos con el modo de transaccin ("encadenado" o "no encadenado") de la sesin en la que se crean. Esto ayuda a evitar problemas asociados con transacciones que utilizan un modo que invocan otras transacciones que usan otro modo. Un procedimiento almacenado etiquetado como "encadenado" no es ejecutable en sesiones que utilizan el modo de transaccin no encadenado, y viceversa. Warning! Cuando emplee los modos de transaccin, tenga presente los efectos que cada parmetro puede tener en sus aplicaciones. Definicin de modos de transaccin para procedimientos almacenados Puede utilizar el procedimiento almacenado del sistema sp_procxmode para cambiar el valor de etiqueta asociado a un procedimiento almacenado. SQL Server tambin proporciona una tercera etiqueta, "anymode" ("cualquier etiqueta"), que puede utilizar con sp_procxmode para sealar los procedimientos del sistema que pueden ejecutarse en cualquier modo de transaccin. Por ejemplo: sp_procxmode byroyalty, "anymode" Use sp_procxmode sin valores de parmetro para obtener los modos de transaccin de todos los procedimientos almacenados de la base de datos actual:
Page 262 of 280

sp_procxmode procedure name ------------------------byroyalty discount_proc insert_sales_proc insert_salesdetail_proc storeid_proc storename_proc title_proc titleid_proc

transaction mode -------------------Unchained Unchained Unchained Unchained Unchained Unchained Unchained Unchained

(8 rows affected, return status = 0) Slo se puede utilizar sp_procxmode en el modo de transaccin no encadenado. Para cambiar el modo de transaccin de un procedimiento, es necesario ser un administrador del sistema, el propietario de la base de datos o el propietario del procedimiento. Uso de cursores en transacciones De forma predeterminada, SQL Server no cambia el estado de un cursor (abierto o cerrado) cuando una transaccin finaliza por una consignacin o reversin. Sin embargo, las normas SQL asocian un cursor abierto con su transaccin activa. La consignacin o reversin de esa transaccin cierra automticamente todos los cursores abiertos asociados a ella. Para imponer este comportamiento compatible con las normas SQL, SQL Server proporciona la opcin close on endtran del comando set . Adems, si se activa el modo encadenado, SQL Server inicia una transaccin cuando se abre un cursor y cierra el cursor cuando la transaccin se consigna o revierte. Por ejemplo, la siguiente secuencia de instrucciones genera de forma predeterminada un error: open cursor test commit tran open cursor test Si define las opciones close on endtran o chained , el estado del cursor pasa de abierto a cerrado despus de la consignacin. Esto permite que el cursor se vuelva a abrir. Los bloqueos exclusivos adquiridos por un cursor en una transaccin se retienen hasta el final de dicha transaccin. Esto tambin se aplica a los bloqueos compartidos cuando se usa la palabra clave holdlock , la clusula at isol a tion serializable o la opcin set isol a tion level 3 . Sin embargo, si no define la opcin close on endtran , el cursor permanece abierto despus del final de la transaccin y su bloqueo de pgina actual permanece en efecto. Asimismo, el cursor podra continuar adquiriendo bloqueos conforme recobrara filas adicionales. Copia de seguridad y recuperacin de transacciones Todos los cambios efectuados en la base de datos, independientemente de que sean el resultado de una sola instruccin update o de un conjunto agrupado de instrucciones SQL, se registran de forma automtica en la tabla del sistema syslogs . A esta tabla se le llama diario de transacciones . Algunos comandos que cambian la base de datos no se registran, como truncate table , la copia masiva en una tabla que no tiene ndices, select into , writetext y dump transaction with no_log . El diario de transacciones registra las instrucciones update , insert o delete cada pocos segundos. Cuando comienza una transaccin, se registra un evento begin transaction en el diario. Las instrucciones de modificacin de datos se registran en el diario conforme se reciben. El cambio siempre se registra en el diario antes de que se realice ningn cambio en la base de datos en s. Este tipo de diario, llamado registro de escritura anticipada, garantiza que la base de datos pueda recuperarse completamente en caso de que se produzca un fallo. Los fallos se pueden producir por problemas del hardware o de los medios, problemas del software de sistema, problemas del software de aplicacin, cancelaciones de transacciones dirigidas por el programa o decisiones de usuario de cancelar una transaccin.
Page 263 of 280

En caso de generarse alguno de estos fallos, el diario de transacciones puede reproducirse frente a una copia de la base de datos restaurada a partir de una copia de seguridad realizada con los comandos dump . Para recuperarse de un fallo, las transacciones que estaban en proceso, pero an sin consignar, en el momento del fallo deben deshacerse, puesto que una transaccin parcial no es un cambio exacto. Las transacciones finalizadas deben rehacerse si no hay garanta de que se hayan escrito en el dispositivo de bases de datos. Si hay transacciones activas de larga duracin todava sin consignar en el momento en que SQL Server falla, el proceso para deshacer los cambios puede necesitar tanto tiempo como el invertido en ejecutar la transaccin. Estos casos incluyen transacciones que no contienen commit transaction ni rollback transaction para que coincidan con begin transaction . Esto evita que SQL Server escriba ningn cambio y aumenta el tiempo de recuperacin. El volcado dinmico de SQL Server permite realizar copias de seguridad de la base de datos y del diario de transacciones mientras la base de datos contina en uso. Realice copias de seguridad frecuentes del diario de transacciones de la base de datos. Cuanto ms a menudo realice copias de seguridad de los datos, menor ser la cantidad de trabajo que pierda en caso de un fallo del sistema. El propietario de cada base de datos o los usuarios con una autorizacin OPER son responsables de la copia de seguridad de la base de datos y de su diario de transacciones con los comandos dump , aunque el permiso para ejecutarlos puede transferirse a otros usuarios. Sin embargo, el permiso para utilizar los comandos load corresponde predeterminadamente al propietario de la base de datos y no puede transferirse. Una vez emitidos los comandos load adecuados, SQL Server administra todos los aspectos del proceso de recuperacin. SQL Server tambin controla de forma automtica el intervalo del punto de verificacin, que es el punto en el que todas las pginas de datos que se han cambiado tienen garanta de haberse escrito en el dispositivo de bases de datos. Los usuarios pueden forzar un punto de verificacin si es necesario con el comando checkpoint . Para obtener ms informacin, consulte el Manual de Referencia de SQL Server y la Gua de Administracin del Sistema.

Glosario
acciones de disparador Accin para la que se especifica un disparador. actualizacin Adicin, eliminacin o modificacin de datos utilizando las instrucciones insert , delete , truncate table o update . administrador del sistema Usuario autorizado para manejar la administracin del sistema SQL Server, incluida la creacin de cuentas de usuario, asignacin de permisos y creacin de bases de datos. alcance del cursor Regin en la que se reconoce el cursor. El nombre de cursor existe slo mientras exista su alcance. El alcance es de uno de los tres tipos siguientes: Sesin - la regin se inicia cuando el cliente se conecta a SQL Server y finaliza cuando se desconecta. Esta regin no incluye cualquier regin definida por procedimientos almacenados o disparadores. Procedimiento almacenado - la regin se inicia cuando un procedimiento almacenado comienza la ejecucin y finaliza cuando la completa. Disparador- la regin se inicia cuando un disparador comienza la ejecucin y finaliza cuando la completa. Los nombres de cursor deben ser nicos dentro de su alcance. Por ejemplo, un procedimiento almacenado no puede declarar dos cursores con el mismo nombre. alias
Page 264 of 280

Permite que un usuario de SQL Server sea reconocido como otro usuario en una base de datos. Utilice sp_addalias para crear un alias. argumento Valor suministrado para una funcin o procedimiento, necesario para evaluar la funcin. autocombinacin Combinacin utilizada para comparar valores dentro de una columna de una tabla. Puesto que esta operacin relaciona una combinacin de una tabla consigo misma, es preciso asignar dos nombres temporales a la tabla, o nombres de correlacin , que se utilizan para calificar los nombres de columna en el resto de la consulta. barridos del cursor Proceso de generacin de un conjunto de resultados del cursor. base de datos Conjunto de tablas de datos relacionados y otros objetos de base de datos organizados y presentados para un fin especfico. base de datos master Controla las bases de datos de usuarios y el funcionamiento general de SQL Server. Conocida como master , realiza el seguimiento de las cuentas de usuario, procesos permanentes y mensajes de error del sistema. base de datos predeterminada Base de datos a la que un usuario se conecta al hacer el login. bases de datos del sistema Bases de datos de un SQL Server instalado recientemente: master , que controla las bases de datos de usuarios y las operaciones de SQL Server; tempdb , utilizada para tablas temporales; model , utilizada como un modelo para crear nuevas bases de datos de usuario; y sybsystemprocs , que almacena los procedimientos del sistema. bloque de instrucciones Consiste de una serie de instrucciones Transact-SQL incluidas entre las palabras clave begin y end , de forma que se interpretan como una unidad. bloqueo Proceso de restriccin de acceso a recursos en un entorno multiusuario para mantener la seguridad e impedir que se produzcan problemas de acceso. SQL Server aplica bloqueos a tablas o pginas de forma automtica. bloqueo activo Solicitud de un bloqueo exclusivo que se deniega repetidamente debido a la interferencia de una serie de bloqueos compartidos simultneos. SQL Server detecta la situacin despus de cuatro rechazos y no admite ms bloqueos compartidos. bloqueo compartido bloqueo creado por operaciones de no actualizacin ("lectura"). Otros usuarios pueden leer los datos simultneamente, pero ninguna transaccin puede adquirir un bloqueo exclusivo sobre los datos hasta que se hayan liberado todos los bloqueos compartidos. bloqueo de demanda

Page 265 of 280

Impide que se definan ms bloqueos compartidos en un recurso de datos (tabla o pgina de datos). Cualquier nueva solicitud de bloqueo compartido tiene que esperar a que termine la solicitud de bloqueo de demanda. bloqueo insoluble Situacin que se produce cuando dos usuarios, cada uno de los cuales mantiene un bloqueo sobre una parte de los datos, intenta adquirir un bloqueo sobre la otra parte de los datos. SQL Server detecta los bloqueos insolubles y destruye el proceso de uno de los usuarios. bloqueo intent Indica la intencin de adquirir un bloqueo compartido o exclusivo sobre una pgina de datos. bloqueos de actualizacin Bloqueos que garantizan que slo una operacin pueda modificar datos en una pgina. Otras transacciones pueden leer los datos mediante bloqueos compartidos. SQL Server aplica bloqueos de actualizacin cuando se inicia una operacin update o delete . bloqueos exclusivos Bloqueos que impiden que cualquier otra transaccin adquiera un bloqueo hasta que se libere el bloqueo original al final de una transaccin. Siempre se aplican a operaciones de actualizacin ( insert , update , delete ). cadena hexadecimal Cadena binaria con codificacin hexadecimal que comienza con el prefijo 0x y que puede incluir los dgitos de 0 a 9 y las letras maysculas y minsculas de la A a la F. La interpretacin de cadenas de caracteres hexadecimales es especfica de la plataforma. Para algunos sistemas, el primer byte despus del prefijo es el ms significativo; para otros, es el ltimo byte. Por ejemplo, la cadena de caracteres 0x0100 se interpreta como 1 en algunos sistemas, y como 256, en otros. calificado El nombre de un objeto de base de datos puede ser calificado, o ir precedido del nombre de base de datos y del propietario del objeto. campo Valor de datos que describe una caracterstica de una entidad. Tambin denominado columna . carcter comodn Carcter especial utilizado con la palabra clave de Transact-SQL like que puede representar un carcter (el carcter de subrayado, _) o un nmero cualquiera de caracteres (signo de porcentaje, %) que coincidan con un modelo de referencia. clusula predeterminada Especifica el valor predeterminado para una columna en la instruccin create table . clusulas Conjunto de palabras claves y parmetros que adaptan un comando Transact-SQL para satisfacer una necesidad determinada. Este trmino tambin se denomina frase de palabras clave . clave Campo utilizado para identificar un registro, a menudo empleado como el campo de ndice para una tabla. clave externa
Page 266 of 280

Columna clave de una tabla que depende lgicamente de una columna de clave primaria de otra tabla. Tambin es una columna (o combinacin de columnas) cuyos valores deben coincidir con una clave primaria en alguna otra tabla. clave primaria Columna o columnas cuyos valores identifican de forma exclusiva una fila de una tabla. columna Equivalente lgico de un campo. Una columna contiene un elemento de datos individual dentro de una fila o registro. columna IDENTITY Columna con valores generados por el sistema que identifican cada columna de una tabla de forma exclusiva. Las columnas IDENTITY almacenan nmeros nicos, como nmeros de facturas o nmeros de empleados, que SQL Server genera automticamente. El valor de la columna IDENTITY identifica cada fila de una tabla de forma exclusiva. comando Instruccin que especifica una operacin para que la computadora la realice. Cada comando o instruccin SQL comienza con una palabra clave, como insert , que asigna nombre a la operacin bsica realizada. Muchos comandos SQL tienen una o ms frases de palabras clave o clusulas , que adaptan el comando para satisfacer una necesidad determinada. combinacin Operacin bsica de un sistema relacional que enlaza las filas de dos o ms tablas comparando los valores de columnas especificadas. combinacin desigual Combinacin realizada en trminos de desigualdad. combinacin externa Combinacin que devuelve filas coincidentes y no coincidentes. Los operadores *= y =* se emplean para solicitar la devolucin de todas las filas de la primera y segunda tabla, independientemente de si existe o no alguna coincidencia en la columna de combinacin. combinacin natural Combinacin en la que los valores de las columnas combinadas se comparan en trminos de igualdad, y todas las columnas de las tablas se incluyen en los resultados, a menos que slo se incluya una columna de cada par de columnas combinadas. combinacin theta Combinaciones que utilizan los operadores de comparacin como condicin de combinacin. Los operadores de comparacin incluyen: igual (=), no igual (!=), mayor que (>), menor que (<), mayor o igual a (>=) y menor o igual a (<=). concatenacin Combinacin de expresiones para crear expresiones mayores. Las expresiones pueden incluir cualquier combinacin de cadenas de caracteres o binarias, o de nombres de columna. condiciones de disparador Condiciones que provocan la activacin de un disparador. conjunto de resultados del cursor Conjunto de filas resultantes de la ejecucin de la instruccin select asociada con el cursor.
Page 267 of 280

consulta 1. Solicitud para la recuperacin de datos con una instruccin select . 2. Cualquier instruccin SQL que manipula datos. consulta externa Nombre alternativo de la consulta principal de una instruccin que contiene una subconsulta. consulta interna Tambin denominada subconsulta. consultas anidadas Instrucciones select que contienen una o ms subconsultas. conversiones implcitas Conversiones de tipos de datos realizadas automticamente por SQL Server para comparar tipos de datos. creador de indicadores FIPS Para definir el creador de indicadores FIPS (Federal Information Processing Standards), es preciso que se indiquen todas las mejoras realizadas al lenguaje SQL sin normalizar. FIPS reconoce SQL89 como norma base. cursor Nombre simblico asociado con una instruccin select Transact-SQL mediante una instruccin de declaracin. Los cursores se componen de dos partes: el conjunto de resultados del cursor y la posicin del cursor . cursor cliente Cursor declarado mediante llamadas Open Client o Embedded SQL. Open Client hace un seguimiento de las filas devueltas por SQL Server y las pone en memoria intermedia para la aplicacin. Las actualizaciones y eliminaciones del conjunto de resultados de los cursores cliente slo pueden realizarse mediante llamadas Open Client. cursor de ejecucin Subconjunto de cursores de Open Client, cuyo conjunto de resultados se define mediante un procedimiento almacenado que tiene una sola instruccin select . El procedimiento almacenado puede utilizar parmetros. Los valores de los parmetros se envan mediante llamadas Open Client. cursor de idioma Cursor declarado en SQL sin utilizar Open Client. Al igual que con los cursores de SQL Server, Open Client ignora completamente los cursores, y los resultados se devuelven al cliente con el mismo formato que una operacin select normal. cursor del servidor Cursor declarado dentro de un procedimiento almacenado. El cliente que ejecuta el procedimiento almacenado no percibe la presencia de estos cursores. Los resultados de un fetch recibidos por el cliente aparecen exactamente del mismo modo que los resultados de una operacin select normal. datos discpulos Datos que dependen de otra tabla lgicamente. Por ejemplo, en la base de datos pubs2 , la tabla salesdetail es una tabla discpula. Cada pedido de la tabla sales puede tener un gran nmero de entradas correspondientes en salesdetail . Cada elemento de salesdetail carece de significado sin una entrada correspondiente en la tabla sales .
Page 268 of 280

definicin de datos Proceso de definicin de bases de datos y de creacin de objetos de base de datos, como tablas, ndices, reglas, valores predeterminados, procedimientos, disparadores y vistas. dependiente Los datos dependen lgicamente de otros datos cuando los datos maestros de una tabla deben mantenerse sincronizados con los datos discpulos de otra tabla, a fin de proteger la consistencia lgica de la base de datos. diario de transacciones Tabla del sistema ( syslogs ) en la que se registran todos los cambios realizados en la base de datos. diccionario de datos Tablas del sistema que contienen descripciones de los objetos de base de datos y de su estructura. disparador Forma especial de un procedimiento almacenado que se activa cuando un usuario ejecuta un comando de modificacin como insert , delete o update en una tabla o columna especificada. Los disparadores se utilizan frecuentemente para imponer la integridad de referencia. eliminacin en cascada Operacin de eliminacin que afecta a los datos relacionados en otras tablas. equicombinacin Combinacin basada en la igualdad. errores fatales Errores cuyo nivel de gravedad es 19 y superior. Un error fatal termina la sesin de trabajo del usuario y exige volver a hacer a el login. escala Nmero mximo de dgitos que un tipo de datos numeric o decimal puede almacenar a la derecha de la coma decimal. La escala debe ser inferior o igual a la precisin. espacio del nombre de cursor Regin en la que se reconoce el cursor. Es una de los tres tipos siguientes: sesin - La regin se inicia cuando el cliente se conecta a SQL Server y finaliza cuando se desconecta. Esta regin no incluye cualquier regin definida por procedimientos almacenados o disparadores. procedimiento almacenado - La regin se inicia cuando un procedimiento almacenado comienza la ejecucin y finaliza cuando la completa. disparador- La regin se inicia cuando un disparador comienza la ejecucin y finaliza cuando la completa. Los nombres de cursor deben ser nicos dentro de una regin de alcance determinado. Por ejemplo, un procedimiento almacenado no puede declarar dos cursores con el mismo nombre. esquema

Page 269 of 280

Consiste de una serie de objetos asociados con un nombre de esquema particular y con un identificador de autorizacin de esquema. Los objetos son tablas, vistas, dominios, restricciones, axiomas, privilegios, etc.. Un esquema se crea con la instruccin create schema . estabilidad del cursor Nivel de bloqueo o aislamiento en el que SQL Server tiene un bloqueo compartido sobre pginas de la tabla base que contienen una fila del cursor actual. La pgina permanece bloqueada hasta que el cursor deja de posicionarse en la pgina (como resultado de operaciones de recobro). Si la tabla base tiene un ndice, las pginas de ndice correspondientes tambin tienen bloqueos compartidos. estado de retorno Valor que indica que el procedimiento se complet correctamente, o la razn del fallo. expresin Combinacin de una o ms constantes, literales, funciones, identificadores de columna o variables separadas por operadores que devuelven un valor nico. Una expresin puede ser aritmtica, relacional, lgica (booleana) o una cadena de caracteres. expresin aritmtica Expresin que slo contiene operandos numricos y devuelve un valor numrico nico. En Transact-SQL, los operandos pueden ser de cualquier tipo de datos numrico de SQL Server. Pueden ser funciones, variables, parmetros u otras expresiones aritmticas. Es sinnimo de expresin numrica . expresin booleana Expresin que realiza una evaluacin TRUE (1) o FALSE (0). Las expresiones booleanas se emplean con frecuencia en instrucciones de control de flujo, como las condiciones if o while . expresin constante Expresin que devuelve el mismo valor cada vez que sta se utiliza. En las instrucciones de sintaxis Transact-SQL, constant_expression no incluye variables ni identificadores de columna. expresin de caracteres Expresin que devuelve un valor de tipo de caracteres nico. Puede incluir literales, operadores de concatenacin, funciones e identificadores de columna. expresin lgica Expresin que realiza una evaluacin TRUE (1), FALSE (0) o UNKNOWN (NULL). Las expresiones lgicas se utilizan con frecuencia en instrucciones de control de flujo, como las condiciones if o while . expresin numrica Expresin que slo contiene valores numricos y que devuelve un valor numrico nico. En Transact-SQL, los operandos pueden ser de cualquier tipo de datos numrico de SQL Server. Pueden ser funciones, variables, parmetros u otras expresiones aritmticas. Este trmino es sinnimo de expresin aritmtica . expresin relacional Tipo de expresin booleana o lgica con el formato:

arith_expression

relational_operator

arith_expression

En Transact-SQL, una expresin relacional puede devolver TRUE, FALSE o UNKNOWN. Los resultados pueden evaluarse como UNKNOWN si una o ambas expresiones se evalan como NULL.
Page 270 of 280

fecha base 1 de enero de 1900; la fecha suministrada por SQL Server cuando un usuario no especifica un valor para una columna de fecha. fila Conjunto de columnas relacionadas que describe una entidad especfica. Tambin llamada registro . fragmento Cuando se asigna slo parte del espacio de un dispositivo con create o alter database , dicha parte se denomina fragmento. frases de palabras clave Conjunto de palabras clave y de parmetros que adaptan un comando Transact-SQL para satisfacer una necesidad determinada. Tambin denominadas clusulas . funcin agregada Funcin que acta sobre un conjunto de celdas para generar una respuesta nica o conjunto de respuestas, una para cada subconjunto de celdas. Las funciones agregadas disponibles en Transact-SQL son: promedio ( avg ), mximo ( max ), mnimo ( min ), total ( sum ) y conteo del nmero de elementos ( count ). funcin agregada de fila Funciones ( sum , avg , min , max y count ) que generan una nueva fila de datos resumidos cuando se utilizan con compute en una instruccin select . funcin agregada escalar Funcin agregada que genera un valor nico de una instruccin select sin una clusula group by . Esto es verdadero tanto si la funcin agregada est operando en todas las filas de una tabla, como si lo hace en un subconjunto de filas definido por una clusula where . Vase tambin funcin agregada vectorial. funcin agregada vectorial Valor resultante del uso de una funcin agregada con una clusula group by . Vase tambin funcin agregada escalar . funcin de cadena de caracteres Funcin que opera sobre cadenas de caracteres o de datos binarios. substring y charindex son funciones de cadena de caracteres de Transact-SQL. funcin de conversin de tipos de datos Funcin que se utiliza para convertir expresiones de un tipo de datos en otro tipo de datos, siempre que estas conversiones no se realicen automticamente por SQL Server. funcin de fecha Funcin que muestra informacin de fechas y horas, o manipula los valores de fecha y hora. Las funciones de fecha incluyen getdate , datename , datepart , datediff y dateadd . funcin del sistema Funcin que devuelve informacin especial de la base de datos, en particular, de las tablas del sistema. funciones Vase funciones incorporadas .
Page 271 of 280

funciones incorporadas Amplia variedad de funciones que toman uno o ms parmetros y devuelven resultados. Las funciones incorporadas incluyen funciones matemticas, del sistema, de cadena de caracteres, de texto, de fecha y de conversin de tipos. ID de usuario del servidor Nmero de ID por el que SQL Server conoce al usuario. identificador Cadena de caracteres utilizada para identificar un objeto de base de datos, como un nombre de tabla o de columna. identificadores delimitados Nombres de objeto incluidos entre comillas dobles que evitan determinadas restricciones sobre los nombres de objeto. ndice agrupado Indice en el que el orden fsico es igual que el orden lgico (indexado). El nivel de hoja de un ndice agrupado representa las propias pginas de datos. ndice no agrupado Indice que almacena valores clave y punteros a datos. El nivel de hoja apunta a pginas de datos, en lugar de contener los propios datos. ndices compuestos Indices que utilizan ms de una columna. Emplee ndices compuestos cuando sea conveniente realizar bsquedas en dos o ms columnas como unidad, debido a su relacin lgica. ndices nicos Indices que no permiten que dos filas de las columnas especificadas tengan el mismo valor. SQL Server busca valores duplicados cuando se crea el ndice (si ya existen datos) y cada vez que se aaden datos. informe de cortes de control Informe o visualizacin de datos que corta los datos en grupos y genera informacin resumida para cada corte. Los cortes controlan la generacin de datos resumidos. instruccin Comienza con una palabra clave que nombra la operacin o comando bsico que va a realizarse. instrucciones select anidadas Vase consultas anidadas . int Valor entero de 32 bits con signo. integridad de datos Correccin e integridad de los datos dentro de una base de datos. integridad de referencia
Page 272 of 280

Reglas que gobiernan la consistencia de datos, especficamente las relaciones entre las claves primarias y las claves externas de distintas tablas. SQL Server resuelve la integridad de referencia con disparadores definidos por el usuario. invitado Si existe un usuario llamado "guest" (invitado) en la tabla sysusers de una base de datos, cualquier usuario con un login de SQL Server vlido puede utilizar dicha base de datos, con privilegios limitados. jerarqua de tipos de datos Jerarqua que determina el resultado de los clculos utilizando valores de distintos tipos de datos. lectura no repetida Se produce cuando una transaccin lee una fila y, a continuacin, una segunda transaccin modifica dicha fila. Si la segunda transaccin consigna el cambio, las lecturas posteriores realizadas por la primera transaccin devuelven resultados diferentes al de la lectura original. lectura sucia Se produce cuando una transaccin modifica una fila y, a continuacin, una segunda transaccin lee la fila antes de que la primera transaccin consigne el cambio. Si la primera transaccin revierte el cambio, la informacin leda por la segunda transaccin deja de ser vlida. lecturas fantasma Se producen cuando una transaccin lee un conjunto de filas que cumplen una condicin de bsqueda y, a continuacin, una segunda transaccin modifica los datos (mediante insert , delete , update , etc.). Si la primera transaccin repite la lectura con las mismas condiciones de bsqueda, obtiene un conjunto de filas distinto. lenguaje de control de flujo Estructuras de programacin de Transact-SQL (como if , else , while, o el rtulo goto ) que controlan el flujo de ejecucin de las instrucciones Transact-SQL. lista de seleccin Columnas especificadas en la clusula principal de una instruccin select . Para que una vista dependiente contine siendo vlida, la lista seleccionada debe mantenerse en todas las vistas subyacentes. login Nombre que emplea el usuario para conectarse a SQL Server. Un login es vlido si SQL Server tiene una entrada para dicho usuario en la tabla del sistema syslogins . lote Una o ms instrucciones Transact-SQL terminadas con una marca de final de lote, que enva los lotes a SQL Server para su procesamiento. mensaje de error Mensaje que SQL Server emite, generalmente al terminal del usuario, cuando detecta una situacin de error. modificacin de datos Adicin, eliminacin o modificacin de la informacin de la base de datos con los comandos insert , delete y update . modo de transaccin encadenado
Page 273 of 280

Determina si SQL Server inicia o no automticamente una nueva transaccin en la siguiente instruccin de recuperacin o de modificacin de datos. Si set chained se define como on fuera de una transaccin, la siguiente instruccin de recuperacin o de modificacin de datos inicia una nueva transaccin. Este modo cumple con las normas SQL: garantiza que cada instruccin de recuperacin y de modificacin de datos se realiza dentro de una transaccin. El modo de transaccin encadenado puede ser incompatible con programas Transact-SQL existentes. El valor predeterminado es off . Las aplicaciones que requieren el cumplimiento de las normas SQL (como el precompilador Embedded SQL) deben definir automticamente la opcin chained como on al principio de cada sesin. mdulo Operador aritmtico representado por un signo de porcentaje (%), que proporciona el resto entero despus de una operacin de divisin entre dos enteros. Por ejemplo, 21 % 9 = 3 porque 21 dividido entre 9 es igual a 2 con un resto de 3. nivel de aislamiento Especifica las clases de acciones no permitidas durante la ejecucin de las transacciones actuales; tambin denominado "nivel de bloqueo." La norma SQL define cuatro niveles de aislamiento para transacciones SQL. El nivel 0 impide que otras transacciones modifiquen datos ya modificados por una transaccin no consignada. El nivel 1 impide las lecturas sucias . El nivel 2 (no admitido por SQL Server) tambin impide las lecturas no repetidas . El nivel 3 impide ambos tipos de lecturas, as como las lecturas fantasma ; es equivalente a realizar todas las consultas con holdlock . El usuario controla el nivel de aislamiento con la opcin transaction isolation level de set o con la clusula at isolation de select o readtext . El nivel predeterminado es 1. nivel de bloqueo Vase nivel de aislamiento . nivel de hoja Nivel de un ndice en el que todos los valores clave aparecen en orden. Para ndices agrupados de SQL Server, el nivel de hoja y el nivel de datos es el mismo. Para ndices no agrupados, el ltimo nivel de ndice por encima del nivel de datos es el nivel de hoja, ya que los valores clave para todas las filas de datos aparecen en el orden clasificado. nombres de correlacin Distinguen los diferentes roles que una tabla determinada realiza en una consulta, en especial una consulta correlacionada o autocombinacin . Asigne nombres de correlacin en la clusula from y especifique el nombre de correlacin despus del nombre de tabla: select au1.au_fname, au2.au_fname from authors au1, authors au2 where au1.zip = au2.zip nmero de estado de error Nmero adjunto a un mensaje de error de SQL Server que permite identificar de forma exclusiva la lnea del cdigo de SQL Server donde se produjo el error. nmero de mensaje Nmero que identifica de forma exclusiva un mensaje de error. nmero de nivel de gravedad Gravedad de una condicin de error: los errores con un nivel de gravedad 19 y superior son errores fatales. objeto de base de datos Uno de los componentes de una base de datos: tabla, vista, ndice, procedimiento, disparador, columna, valor predeterminado o regla.

Page 274 of 280

objetos Vase objetos de base de datos . operador relacional Operador que compara dos operandos y devuelve un valor verdadero, como "5 <7" (TRUE), "ABC" = "ABCD" (FALSE) o "@value > NULL" (UNKNOWN). operadores Smbolos que actan sobre dos valores para producir un tercero. Vanse los operadores de comparacin, lgicos o aritmticos. operadores aritmticos La adicin (+), sustraccin (-), divisin (/) y multiplicacin (*) pueden utilizarse con columnas numricas. El mdulo (%) slo puede utilizarse con las columnas int , smallint y tinyint . operadores de comparacin Se utilizan para comparar un valor con otro en una consulta. Los operadores de comparacin son: igual a (=), mayor que (>), menor que (<), mayor o igual a (>=), menor o igual a (<=), no igual a (!=), no mayor que (!>) y no menor que (!<). operadores lgicos Son los operadores and , or y not . Los tres pueden utilizarse en clusulas where . El operador and combina dos o ms condiciones y devuelve resultados cuando todas las condiciones son verdaderas; or conecta dos o ms condiciones y devuelve resultados cuando alguna de las condiciones es verdadera. palabra clave Palabra o expresin reservada para uso exclusivo de Transact-SQL. Tambin conocida como palabra reservada . parmetros Argumento para un procedimiento almacenado. parte de fecha Parte de una fecha, como da, mes o ao, reconocidas por las funciones de fecha de Transact-SQL. partes de asignacin de disco Grupos de unidades de asignacin a partir de los cuales SQL Server crea un nuevo archivo de base de datos. El tamao mnimo de un parte de asignacin de disco es una unidad de asignacin , o 256 pginas de 2KB. permiso Autorizacin para realizar determinadas acciones en objetos de base de datos especficos o para ejecutar ciertos comandos. permisos de comando Permisos que afectan a los comandos. Vase tambin permisos de objeto . permisos de objeto Permisos que regulan el uso de determinados comandos (comandos de modificacin de datos, adems de select , truncate table y exec ute) para especificar tablas, vistas o columnas. Vase tambin permisos de comando .

Page 275 of 280

posicin del cursor Indica la fila actual del cursor. Es posible hacer referencia a dicha fila explcitamente utilizando instrucciones diseadas para admitir cursores, como delete o update . Cambie la posicin actual del cursor mediante fetch , que desplaza la posicin actual del cursor una o ms filas hacia abajo en el conjunto de resultados del cursor. precisin Nmero mximo de dgitos decimales que los tipos de datos numeric y decimal pueden almacenar. La precisin incluye todos los dgitos, tanto los que se encuentran a la derecha, como a la izquierda de la coma decimal. precisin de visualizacin Nmero de dgitos binarios significativos que ofrece el formato de visualizacin predeterminado para los valores real y float . Internamente, los valores real y float se almacenan con una precisin inferior o igual a la de los tipos de datos especficos de la plataforma a partir de los cuales son creados. Por razones de visualizacin, la precisin de los valores real de Sybase es de 9 dgitos, y la de los valores float de Sybase, de 17. privilegio Autorizacin para realizar determinadas acciones en objetos de base de datos especficos o para ejecutar comandos concretos. Es sinnimo de permiso . problema Halloween Anomala asociada con actualizaciones del cursor por la que una fila aparece dos veces en el conjunto de resultados. Esto ocurre cuando el cliente actualiza la clave del ndice y la fila de ndice actualizada se desplaza hacia abajo en el conjunto de resultados. procedimiento almacenado Consiste de una serie de instrucciones SQL y de instrucciones de control de flujo opcionales almacenadas bajo un nombre. Los procedimiento almacenados suministrados por SQL Server se denominan procedimientos del sistema . procedimientos del sistema Procedimientos almacenados suministrados por SQL Server para la administracin del sistema. Estos procedimientos se desempean como atajos para recuperar informacin de tablas del sistema, o como mecanismos para efectuar la administracin de bases de datos y otras tareas que involucran la actualizacin de tablas del sistema. producto cartesiano Todas las combinaciones de filas posibles de cada una de las tablas especificadas en una combinacin. El nmero de filas del producto cartesiano es igual al nmero de filas de la primera tabla por el nmero de filas de la segunda tabla. Despus de calcular el producto cartesiano, se eliminarn las filas que no satisfagan las condiciones de combinacin. Propietario de la base de datos Usuario que crea una base de datos. Un propietario de la base de datos tiene control sobre todos los objetos de base de datos de dicha base de datos. El nombre de login del propietario de la base de datos es ''dbo''. proteccin dependiente de contexto Proteccin que proporciona determinados permisos o privilegios dependiendo de la identidad del usuario. Este tipo de proteccin se proporciona utilizando vistas y la funcin incorporada user_id . proyeccin Una de las operaciones de consulta bsicas de un sistema relacional. Una proyeccin es un subconjunto de las columnas de una tabla.
Page 276 of 280

punto de resguardo Marcador que el usuario coloca dentro de una transaccin definida por el usuario . El usuario puede utilizar posteriormente el comando rollback transaction con el nombre del punto de resguardo para cancelar cualquier comando anterior al punto de resguardo, o commit transaction para completar realmente los comandos. punto de verificacin Punto en el cual se garantiza que todas las pginas de datos modificadas se han escrito en el dispositivo de bases de datos. recobro Desplaza la posicin actual del cursor hacia abajo en el conjunto de resultados del cursor. Tambin denominado recobro del cursor. recuperacin de datos Solicitud de datos de la base de datos y recepcin de los resultados. Tambin denominada consulta . regla Especificacin que controla los datos que pueden introducirse en una columna determinada, o en una columna de un tipo particular de datos definido por el usuario. reglas de normalizacin Reglas estndar de diseo de base de datos en un sistema de administracin de bases de datos relacionales. relacin maestro-discpulo Relacin entre conjuntos de datos en la que un conjunto de datos depende lgicamente del otro. Por ejemplo, en la base de datos pubs2 , la tabla sales y la tabla salesdetail tienen una relacin maestro-discpulo. Vase datos discpulos y tabla maestra . resolucin de vista En consultas que utilizan una vista, es el proceso de verificacin de la validez de objetos de base de datos en la consulta y de combinacin de la consulta y de la definicin almacenada de la vista. restriccin Subconjunto de las filas de una tabla. Tambin denominada seleccin , es una de las operaciones de consulta bsicas de un sistema relacional. restriccin a nivel de columna Limita los valores de una columna especificada. Site restricciones a nivel de columna despus del nombre de columna y del tipo de datos en la instruccin create table , antes de la coma de separacin. restriccin a nivel de tabla Limita los valores de ms de una columna de una tabla. Introduzca restricciones a nivel de tabla como clusulas independientes separadas por comas en la instruccin create . Declare las restricciones que operan en ms de una columna como restricciones a nivel de tabla. restriccin de clave primaria Restriccin exclusiva que no admite valores nulos para las columnas que componen la clave. Slo puede haber una restriccin de clave primaria por tabla. La restriccin de clave primaria crea un ndice nico en las columnas especificadas para imponer la integridad de estos datos.
Page 277 of 280

restriccin de integridad de referencia Las restricciones de integridad de referencia requieren que los datos insertados en la tabla "de referencia" que define la restriccin tengan valores coincidentes en la tabla "a la que se hace referencia". No es posible eliminar filas ni actualizar valores de columna de una tabla a la que se hace referencia que sean coincidentes con los valores de una tabla de referencia. Asimismo, no es posible omitir la tabla a la que se hace referencia hasta que se omita la tabla de referencia o se quite la restriccin de integridad de referencia. restriccin de verificacin Una restriccin de verificacin ( check ) limita los valores que el usuario puede insertar en una columna de una tabla. Una restriccin check especifica una condicin de bsqueda search_condition que cualquier valor debe superar antes de insertarse en la tabla. restriccin exclusiva (unique) Restriccin que precisa que todos los valores no nulos de las columnas especificadas sean nicos. No est permitido que dos filas de una tabla tengan el mismo valor en la columna especificada. La restriccin exclusiva crea un ndice nico en las columnas especificadas para imponer la integridad de estos datos. restricciones de integridad Constituyen un modelo para describir la integridad de base de datos en la instruccin create table . La integridad de base de datos est formada por dos componentes complementarios: validez , que garantiza que toda la informacin falsa queda excluida de la base de datos, e integridad , que garantiza que toda la informacin verdadera se incluye en la base de datos. roles Proporcionan responsabilidades individuales para los usuarios que realizan tareas de administracin y de seguridad del sistema en SQL Server. Los roles de administrador del sistema, oficial de seguridad del sistema y operador pueden concederse a cuentas de login individuales del servidor seleccin Subconjunto de filas de una tabla. Tambin denominada restriccin, es una de las operaciones de consulta bsicas de un sistema relacional. sistema operativo Grupo de programas que traduce comandos del usuario a la computadora y permite realizar tareas, como crear archivos, ejecutar programas e imprimir documentos. subconsulta Instruccin select anidada dentro de otra instruccin select , insert , update o delete , o dentro de otra subconsulta. subconsulta correlacionada Es una subconsulta que no puede evaluarse independientemente, sino que sus resultados dependen de la consulta externa. Tambin se denomina subconsulta de repeticin, ya que se ejecuta una vez para cada fila seleccionada por la consulta externa. Vase tambin consultas anidadas . tabla Consiste en una serie de filas (registros) que tienen columnas asociadas (campos). Es el equivalente lgico de un archivo de base de datos. tabla de disparador Tabla a la que se adjunta un disparador.
Page 278 of 280

tabla del sistema Una de las tablas del diccionario de datos. Las tablas del sistema realizan un seguimiento de la informacin general de SQL Server y de cada base de datos de usuario. La base de datos Master contiene algunas tablas del sistema que no estn en las bases de datos de usuarios. tabla maestra Tabla que contiene datos de los que dependen los datos de otra tabla de forma lgica. Por ejemplo, en la base de datos pubs2 , la tabla sales es una tabla maestra. La tabla salesdetail contiene informacin discpula que depende de los datos maestros de sales . Normalmente, la tabla discpula dispone de una clave externa que se combina con la clave primaria de la tabla maestra. tablas base Tablas permanentes en las que se basa una vista. Tambin llamadas tablas "subyacentes". tablas de verificacin de disparadores Cuando una modificacin de datos afecta a una columna clave, los disparadores comparan los nuevos valores de columna con las claves relacionadas utilizando tablas de trabajo temporales llamadas tablas de verificacin de disparadores. terminador de comandos Marca de final de lote que enva el lote a SQL Server para su procesamiento. tipo de datos Especifica el tipo de informacin que contendr cada columna y cmo se almacenarn los datos. Los tipos de datos incluyen char , int , money , etc.. Los usuarios pueden crear sus propios tipos de datos en base a los tipos de datos del sistema SQL Server. tipo de datos definido por el usuario Definicin del tipo de datos que puede contener una columna, creada por el usuario. Estos tipos de datos se definen en funcin de los tipos existentes de datos del sistema. Es posible vincular reglas y valores predeterminados a los tipos de datos definidos por el usuario (pero no a los tipos de datos del sistema). tipos de datos compatibles Tipos que SQL Server convierte automticamente para realizar una comparacin implcita o explcita. transaccin Mecanismo para garantizar que un conjunto de acciones se interprete como una sola unidad de trabajo. Vase tambin transaccin definida por el usuario . transaccin definida por el usuario Vase transaccin . transaccin revertida Instruccin Transact-SQL que se emplea con una transaccin definida por el usuario (antes de que se haya recibido un transaccin commit ) que cancela la transaccin y deshace cualquier cambio realizado en la base de datos. unidad de asignacin Unidad lgica de 1/2 megabyte. El comando disk init inicializa un nuevo dispositivo de base de datos para SQL Server y lo divide en partes de 1/2 megabyte llamadas unidades de asignacin.
Page 279 of 280

valor clave Cualquier valor indexado. valor nulo Se utiliza cuando no se asigna explcitamente ningn valor. NULL no es equivalente a cero, ni a espacio en blanco. Un valor de NULL no se considera superior, inferior ni equivalente a ningn otro valor, incluso otro valor de NULL. valor predeterminado Opcin elegida por el sistema cuando no se especifica ninguna otra opcin. variable Entidad asignada a un valor. SQL Server tiene dos tipos de variables, llamadas variables locales y variables globales . variable global Variables definidas por el sistema que SQL Server actualiza de forma permanente. Por ejemplo, @@error contiene el nmero del ltimo error generado por el sistema. variables locales Variables definidas por el usuario con una instruccin declare . vista Forma alternativa de consultar los datos de una o ms tablas. Normalmente, se crea como un subconjunto de columnas de una o ms tablas. volcado dinmico Volcado que se realiza cuando la base de datos est activa.

http://manuals.sybase.com/onlinebooks/groupasarc/svs11001/tsqlsp/@Generic__BookTocView/45905;hf=0;pt=45905;lang=es
Page 280 of 280

Você também pode gostar