Sie sind auf Seite 1von 222

La palabra clave all en la clusula group by es una mejora de Transact-SQL para SQ L.

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 generado s por la clusula group by , aunque algunos de los grupos no tengan filas que cump lan con las condiciones de bsqueda. Sin all , una instruccin select que incluya gr oup 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,5 00.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,0 00.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 $10 00, pero inferiores a $10000. Dado que no hay ningn libro de cocina con un antici po dentro de dicho margen, los resultados no muestran ningn grupo para el tipo mo d_cook . La segunda instruccin genera grupos para todos los tipos, incluidos cocina modern a y "UNDECIDED", aunque el grupo de cocina moderna no incluya ninguna fila que c umpla 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 Transac t-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 ---------- --------- 0736 3 0877 3 1389 3 (3 rows affected) 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 corres pondientes 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 pa ra los vectoriales. where restringe las columnas incluidas en los valores sumari os agregados, pero no tiene efecto sobre las filas que aparecen en los resultado s 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, s obre todo si se trata de consultas a tablas grandes o con combinaciones de varia s tablas. #endregion #region 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 l as de having lo hacen a menudo. Las clusulas having pueden hacer referencia a cua lquiera 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 tra d_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 (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 e n precio, la instruccin es: select pub_id, sum(advance), avg(price) from titles group by pub_id having s um(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 sec uencia en que cada clusula afecta a las filas de la tabla es importante en la det erminacin 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 d e la expresin group by . Las funciones agregadas especificadas en la lista de seleccin calculan valores su marios 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 3

75 5023 PS2091 1845 5023 PS3333 3437 5023 PS7 777 2206 6380 PS7777 500 7067 PS3333 3 45 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. E l agregado sum calcula el nmero total de libros vendidos para cada grupo y, a con tinuacin, la clusula having excluye de los resultados finales los grupo cuyos tota les no sobrepasan los 200 libros. Todos los ejemplos anteriores de having satisfacen las normas SQL, que especific an que las columnas de una expresin having deben tener un solo valor y encontrars e en la lista de seleccin o la clusula group by . Sin embargo, las extensiones Tra nsact-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 10 000, 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 mod_cook 11 .49 popular_comp 21.48 trad_cook 15.96 (4 rows affected) 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 "exte ndida" 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.4 8 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 r esultados finales, aunque el nmero de filas mostradas para cada tipo depende de l as ventas totales ( total_sales ) de cada ttulo. La consulta indica que 3 ttulos d e business , 1 de mod_cook , 2 de popular_comp , 1 de psychology y 2 de trad_coo k han tenido ventas totales superiores a 4000. Como se indic anteriormente, la forma en que SQL Server manipula las columnas ext endidas puede hacer creer que la consulta est ignorando la clusula where en los re sultados finales. Para que las condiciones de where tengan efecto sobre los resu ltados de la columna extendida, es necesario repetir las condiciones en la clusul a having . Por ejemplo: select type, advance, avg(price) from titles where advance > 5000 group by type having advance > 5000 type advance ------------- --------- -------- business 10,1 25.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_co ok 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 ac tuar independientemente una de la otra. having acta como where porque afecta a la

s filas de un solo grupo en lugar de varios grupos, salvo que la clusula having t odava 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 prom edio de todos los ttulos, despus de que la clusula where excluya los ttulos con anti cipo superior a $4000 del clculo del precio promedio: select title_id, advance, price from titles where advance < 4000 having pric e > 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.9 9 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 selec cin. 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 calcu le un valor para toda la tabla. La clusula having excluye filas del grupo de resu ltados, 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 gro up by , consulte el Manual de Referencia de SQL Server. #endregion #region Ordenacin de resultados de consultas: la clusula order by La clusula order by permite la ordenacin de resultados de consultas por una o ms co lumnas. 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 mo d_cook MC3021 0877 psychology PS1372 0877 trad_cook TC3218 0877 trad_cook TC4203 0877 trad_cook TC7777 1389 business BU1032 1389 business BU1111 1389 busi ness BU7832 1389 popular_comp PC1035 1389 popular_comp PC8888 1389 popular_comp PC9999 (18 rows affected) Si se indica ms de una columna en la clusula order by , las ordenaciones quedan an idadas. La siguiente instruccin ordena las filas de la tabla titles primero por e ditor en orden descendente, despus por tipo (ascendente) dentro de cada editor y, finalmente, por nmero de ttulo (tambin ascendente, puesto que no se ha especificad o 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 p sychology 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 lug ar 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 an terior. 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 aparezc an en la lista de seleccin, pero Transact-SQL no tiene esta restriccin. Los result ados 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 e n la lista order by . Los efectos de una clusula order by en datos con maysculas y minsculas mezcladas de penden del criterio de ordenacin instalado en SQL Server. Las opciones bsicas son binario, orden de diccionario y sin distincin de maysculas y minsculas. El procedim iento del sistema sp_helpsort muestra el criterio de ordenacin del servidor. Cons ulte order by en el Manual de Referencia de SQL Server para obtener informacin co mpleta 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 prome dio, la instruccin es: select type, avg(price) from titles group by type order by avg(price) type ---------- ------------ UNDECIDED NULL mod_cook 1 1.49 psychology 13.50 business 13.73 trad_cook 15. 96 popular_comp 21.48 (6 rows affected) #endregion #region Cmo resumir grupos de datos: la clusula compute La clusula compute es una extensin Transact-SQL de SQL. Utilcela con agregados de f ila para generar informes que totalicen valores siempre que cambie el valor de u na 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") especific adas en la clusula compute . Estos valores sumarios aparecen como filas adicionales en los resultados de cons ultas, a diferencia de los resultados agregados de una clusula group by , que apa recen como columnas nuevas. Una clusula compute permite ver las filas detalladas y resumidas con una instrucc in select . Es posible calcular valores sumarios para subgrupos y calcular ms de u n agregado de fila para el mismo grupo. Esta es la sintaxis general de compute :

compute row_aggregate ( column_name ) [, row_aggregate ( column_na me )]... [by column_name [, column_name ]...] Los agregados de fila que pueden utilizarse con compute son sum , avg , min , ma x y count . sum y avg slo se emplean con columnas numricas. A diferencia de la clus ula order by , no es posible usar el nmero de posicin de una columna de la lista d e 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 grou p by y agregados. La segunda utiliza compute y agregados de fila. Observe las di ferencias: select type, sum(price), sum(advance) from titles group by type type ------------ ---------------- UNDECIDED NULL NUL L 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 sum sum -------------------54.92 2 5,125.00 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 -------------------------------- popular_comp NULL NULL popular_comp 20.00 8,000.00 popular_comp 22.95 7,000.00 sum sum -------------------42.95 15,000.00 type price advance -------------------------------- psychology 7.00 6,000.00 psychology 7.99 4,000.00 psychology 10.95 2,275.00 psychol ogy 19.99 2,000.00 psychology 21.59 7,00 0.00 sum sum -------------------67.52 21,275.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 (24 rows affected) 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 Resultado

sum Total de los valores de la expresin avg Promedio de los valores de la expresin max Valor mximo de la expresin min Valor mnimo de la expresin count 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 u na 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 in struccin. 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 en el mismo orden de izquierda a derecha, empezar con la misma expresin y no omitir ninguna expresin. Por ejempl o, 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 row_aggregate ( column_name ) by a, b, c compute row_aggregate ( column_name ) by a, b compute row_aggregate ( column_name ) by a La clusula compute no puede ser ninguna de las siguientes: compute row_aggregate ( column_name ) by b, c compute row_aggregate ( column_name ) by a, c compute row_aggregate ( column_name ) by c Debe utilizar un nombre de columna o una expresin en la clusula order by ; no es p osible 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 us a 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 s ubgrupos y aplica el agregado de fila especificado en cada nivel de agrupacin. Po r 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" type, pub_id, price compute sum(price) by type, pub_id order by

type 36 10.95

pub_id price ----------- ------- ------------- psychology 07 7.00 psychology 0736 7.99 psychology 0736 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 u na clusula compute . A continuacin se muestra una consulta similar a la anterior q ue 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) b y type type pub_id price ----------- ------- -------------- psychology 0 736 7.00 psychology 0736 7.99 psychology 0736 10.95 psychology 0736 19.99 sum ------------45.93 type pub_ id price ---------- ------- -------------- psychology 0877 21.5 9 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 consu lta halla la suma de los precios y los anticipos para cada tipo de libro de coci na: 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 deb en 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 t ype, pub_id compute sum(price), max(pub_id) by type type pub_id price ----------- ------- -------------- mod_cook 087 7 2.99 mod_cook 0877 19.99 sum -------------22.98 max ----0877 type pub_id price ----------- ------- -------------- trad_cook 0877 11.95 trad_c ook 0877 14.99 trad_cook 0877 20.95 sum -------------47.8 9 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 lo s tipos de libros por encima de $20: select type, price, advance from titles where price > $20 compute sum(pri ce), 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 con sulta. La siguiente consulta halla la suma de los precios y los anticipos por ti po, y despus calcula el total general de los precios y los anticipos para todos l os 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(advanc e) type price advance ----------- --------------------------- mod_ cook 2.99 15,000.00 mod_cook 19.99 0.00 sum sum ---------------------------22.98 15,000.0 0 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 sum sum ================= ============ 70.87 34,000.00 (8 rows affected)

#endregion #region Combinacin de consultas: el operador union El operador union de Transact-SQL permite manipular los resultados de dos o ms co nsultas mediante la combinacin de los resultados de cada consulta en un solo conj unto de resultados. La sintaxis es la siguiente: query1 [union [all] e] donde query1 es: queryN ] ... [order by clause] [compute claus

select select_list [into clause ] [from ] [group by clause ] [having clause ] y queryN es:

clause ] [where

clause

select select_list [from clause ] [where clause ] [group by se ] [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 b

clau

char(4) int abc 1 def 2 ghi 3 jkl 4 mno 5

Observe que, de forma predeterminada, el operador union quita filas duplicadas d el conjunto de resultados. Si utiliza la opcin all , se incluyen todas la filas e n los resultados; las duplicadas no se quitan. Observe tambin que las columnas de l conjunto de resultados tienen los mismos nombres que las columnas de T1 . En u na instruccin Transact-SQL puede aparecer cualquier nmero de operadores union . Po r ejemplo: x union y union z De forma predeterminada, SQL Server evala una instruccin con operadores union de i zquierda a derecha. Es posible usar parntesis para especificar el orden de la eva luacin. Por ejemplo, las expresiones: x y: ( x 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 e liminan. 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 inst rucciones union : Todas las listas de seleccin de la instruccin union deben tener el mismo nmero de e xpresiones (como los nombres de columnas, expresiones aritmticas y funciones agre gadas). La siguiente instruccin no es vlida porque la primera lista de seleccin tie ne una longitud superior a la segunda: select stor_id, date, ord_num from stores union select stor_id, ord_num fro m stores_east Las columnas correspondientes de todas las tablas, o cualquier subconjunto de co lumnas utilizadas en las consultas individuales, deben ser del mismo tipo de dat os, o una conversin de datos implcita debe ser posible entre los dos tipos de dato s, o se debe facilitar una conversin explcita. Por ejemplo, no es posible establec er una unin ( union) entre una columna de tipo de datos char y otra de tipo de da tos int , a menos que se facilite una conversin explcita. Sin embargo, es posible union all ( y union z )

realizar una unin entre una columna de tipo de datos money y otra de tipo de dato s 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 uni on 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 est as tablas:La 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 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 correspond ientes no son compatibles. Cuando se combinan distintos tipos de datos (pero com patibles), 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 c onsulta individual de la instruccin union . Por lo tanto, si quiere definir un nu evo encabezado de columna para el conjunto de resultados, debe hacerlo en la pri mera consulta. Adems, si quiere hacer referencia a una columna del conjunto de re sultados utilizando un nombre nuevo, por ejemplo, en una instruccin order by , de be hacerlo de este modo en la primera instruccin select . La siguiente consulta e s 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 cre e una tabla para el conjunto de resultados finales. Por ejemplo, la siguiente in struccin 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 sel ect 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 cualqui er otro lugar, se muestra un mensaje de error. Las clusulas order by y compute slo se permiten al final de la instruccin union par a definir el orden de los resultados finales o para calcular valores sumarios. N o pueden utilizarse dentro de las consultas individuales que conforman la instru ccin 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 ej emplo: 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 operad or union . #endregion #endregion #region COMBINACIONES: RECUPERACIN DE DATOS DE VARIAS TABLAS #region Definicin de combinacin La combinacin de dos o ms tablas es un proceso que compara los datos de campos esp ecificados y usa los resultados de la comparacin para crear una tabla nueva a par tir de las filas que cumplen los requisitos de calificacin. Una instruccin de comb inacin especifica una columna de cada tabla, compara los valores de dichas column as fila a fila y combina las filas calificadas en filas nuevas. La comparacin es generalmente de igualdad (valores totalmente coincidentes), pero pueden especifi carse otros tipos de combinaciones. Si una combinacin ha de tener resultados sign ificativos, las columnas que van a compararse deben tener valores similares, es decir, valores que puedan compararse porque sus tipos de datos son iguales o sim ilares. 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 n aturales, 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 ubicado s 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 Benn et Algodata Infosystems (2 rows affected) Dado que la consulta se realiza a partir de informacin contenida en dos tablas di stintas, publishers y authors , se precisa una combinacin para recuperar la infor macin solicitada. Las combinaciones y el modelo relacional La operacin de combinacin es el sello del modelo relacional de administracin de bas es de datos. Ms que ninguna otra funcin, la combinacin distingue los sistemas de ad ministracin de bases de datos relacionales de otros tipos de DBMS. En los sistemas de administracin de bases de datos estructurados, a menudo conoci dos como sistemas de redes y jerrquicos, las relaciones entre los valores de dato s estn predefinidas. Una vez que se ha configurado una base de datos, es difcil re alizar 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 u na base de datos y pasan a ser explcitas cuando los datos se manipulan, es decir, cuando la base de datos se consulta , no cuando se crea. El usuario puede reali zar cualquier pregunta que se le ocurra sobre los datos almacenados en la base d e 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 enti dades, se necesita la operacin de combinacin. Las relaciones entre los datos almac enados en tablas diferentes se descubren al combinar las tablas. Un corolario de esta regla es que la operacin de combinacin proporciona una flexib ilidad ilimitada al aadir nuevos tipos de datos a la base de datos. Siempre se pu ede 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 un a tabla o tablas existentes, puede vincularse a las tablas existentes mediante u na combinacin. #endregion #region 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 e jemplo anterior especificaba las columnas que contenan los nombres de autores y e ditores. 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 perten ecen. Pero la columna city utilizada para la comparacin de combinacin s tena que cal ificarse, ya que las tablas publishers y authors tambin contienen columnas con es e nombre . Aunque en este ejemplo ninguna de las columnas city aparece en los re sultados, SQL Server necesita el nombre de la tabla a fin de realizar la compara cin. Al igual s de las iatura " rs en la que en la instruccin select , se puede especificar que todas las columna tablas usadas en la consulta se incluyan en los resultados con la abrev * ". Por ejemplo, para incluir todas las columnas de publishers y autho 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 58 9 Darwin Ln. Berkeley CA 94705 1 1389 Algodata Infosystems Berkeley CA 409-56-7008 Bennet Abraham 415 658-9932 223 Bateman St Berkel ey 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 nece sariamente columnas de las dos tablas de la combinacin. Por ejemplo, para encontr ar los nombres de los autores que viven en la misma ciudad de uno de los editore s, no es necesario que la consulta incluya columnas de la tabla publishers :

select au_lname, au_fname from authors, publishers where authors.city = pub lishers.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 debe n 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 cualquie r orden. El orden de las tablas afecta a los resultados mostrados slo cuando se u tiliza select * para especificar la lista de seleccin. Es posible especificar ms de dos tablas o vistas en la clusula from . Como mximo, u na 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", lo s 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 conve niente. Las vistas pueden combinarse exactamente del mismo modo que las tablas y utiliza rse dondequiera se usen tablas. En el Chapter 9 se explican las vistas; este capt ulo 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 pro porciona los nombres de las columnas que van a combinarse, calificados por nombr es 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 imp revistos. Sin una clusula where , cualquiera de las consultas de combinacin explic adas 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 equico mbinaciones . Ms adelante en este captulo encontrar una definicin ms precisa de equic ombinacin, 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 c ombinaciones theta . Otro conjunto de operadores de combinacin se utiliza para co mbinaciones externas , tambin explicadas en detalle ms adelante en este captulo. Lo s 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 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 m enudo 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 de cir, tipos que SQL Server pueda convertir de forma automtica. Por ejemplo, SQL Se rver convierte automticamente cualquiera de las columnas de tipo numrico ( int, sm allint, tinyint, decimal o float ) y cualquiera de las columnas de tipo de carac teres y de fecha ( char, varchar, nchar, nvarchar y datetime ). Para obtener inf ormacin 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 t ipos de datos"del Manual de Referencia de SQL Server. Note: No pueden combinarse tablas a partir de columnas text o image . Sin embarg o, 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 ad ems 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. #endregion #region Procesamiento de combinaciones Conocer el modo en que se procesan las combinaciones ayuda a entenderlas y a des cubrir 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 proces amiento de combinaciones en trminos conceptuales. El procedimiento real de SQL Se rver es ms sofisticado. En trminos conceptuales, el primer paso del procesamiento de una combinacin es for mar el producto cartesiano de las tablas, es decir, todas las combinaciones posi bles de las filas de cada una de las tablas. El nmero de filas de un producto car tesiano 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 autor es multiplicados por 3 editores). Se puede ver un producto cartesiano con cualqu ier 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 c ombinar cada uno de los 23 autores con cada uno de los 3 editores, y devolver 69 f ilas. Este producto cartesiano no contiene ninguna informacin particularmente til. De he cho, 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 e specifica las columnas que deben compararse y en base a qu compararlas. Tambin pue den 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 clus ula 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 combina das 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 conti enen dos columnas idnticas. Puesto que generalmente no tiene ningn sentido repetir 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 nom bres y editores de todos los libros cuyos anticipos pagados son superiores a $75 00, 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 Stre ss! 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 necesariam ente la de igualdad. Es posible utilizar cualquiera de los dems operadores de com paracin: 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 e n estados que correspondan al estado de New Age Books , Massachusetts, en orden alfabtico. select pub_name, publishers.state, au_lname, au_fname, authors.state fro m publishers, authors where authors.state > publishers.state and pub_name = "New Age Books" pub_name state au_lname au_fname state ------------------ -------------- --------------- New Age Books MA Gree ne Morningstar TN New Age Books MA Blotchet-Halls Reginald OR New Age Books MA del Castillo Innes MI New Ag e Books MA Panteley Sylvia MD New Age Books MA Ringer Anne UT New Age Books MA Ringer Alb ert UT (6 rows affected) El siguiente ejemplo utiliza una combinacin ">=" y otra "<" para buscar el royalt y correcto de la tabla roysched , basndose en las ventas totales del libro. 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_sale s < 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 4 095 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 Oakla nd, 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 t emporal 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 p ara calificar los nombres de columna del resto de la consulta. La instruccin de a utocombinacin 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 Strai ght Dick Straight Dick Straight Dirk Stringer Di ck Straight Livia Karsen Dirk Stringer Dick Straight Dirk Stringer Dirk Stringer Dirk Stringe r Livia Karsen Stearns MacFeather Stearns MacFeather Livi a 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 mi smos y eliminar las filas que son idnticas, pero con el orden de los autores inve rtido, 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 a u1.au_id < au2.au_id au_fname au_lname au_fname au_lname --------- ----------- -------- --------- Dick Straight Dirk Stringer Dick St raight Livia Karsen Dirk Stringer Livia Karsen (3 rows affected) Ahora est claro que Dick Straight, Dirk Stringer y Livia Karsen tienen el mismo cd igo postal. La combinacin de desigualdad La combinacin de desigualdad es particularmente til para restringir filas devuelta s por una autocombinacin. Por ejemplo, una combinacin de desigualdad y una autocom binacin se utiliza para hallar las categoras donde haya dos o ms libros baratos (me nos 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 != colu mn_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 mi smo cdigo title_id , pero con nmeros de au_id diferentes, es decir, libros que tie nen ms de un autor. select distinct t1.au_id, t1.title_id from titleauthor t1, titleauthor t2 w here 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 BU10 32 409-56-7008 BU1032 267-41-2394 BU1111 724-80-9391 BU1111 722-51-5454 MC3021 899-46-2035 MC3021 427-172319 PC8888 846-92-7186 PC8888 724-80-9391 PS1372 756-30-7391 PS1372 899-46-2035 PS2091 998-72-3567 PS209 1 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 res trictiva 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 auto res cuyos apellidos empiecen con "A", "B" o "C". Una consulta de combinacin de de sigualdad podra ser: select distinct au_lname, authors.city from publishers, authors ame like "[ABC]%" and publishers.city != authors.city Pero los resultados no responden a la pregunta formulada. where au_ln

au_lname city --------------------------Bennet Berkeley Carson Berkeley Blotchet-Ha lls Corvallis (3 rows affected) El sistema interpreta esta versin de la instruccin SQL con el siguiente significad o: "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 tod as las combinaciones seleccionables antes de evaluar otras condiciones) hace que la consulta devuelva resultados no deseados. En estos casos, es necesario utili zar una subconsulta para obtener los resultados deseados. Una subconsulta puede eliminar primero las filas no seleccionables y despus realizar las restantes rest ricciones. A continuacin se muestra la instruccin correcta: select distinct au_lname, city from authors and city not in (select city from publishers .city) Ahora los resultados son los deseados: where au_lname like "[ABC]%" where authors.city = publishers

au_lname city ------------Blotchet-Halls Corvallis (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 re sulta til la combinacin de ms de dos tablas. Para buscar los ttulos de todos los lib ros de un tipo concreto y los nombres de sus autores, la consulta es: select au_lname, au_fname, title from authors, titles, titleauthor where au thors.au_id = titleauthor.au_id and titles.title_id = titleauthor.title_id a nd 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) Observe que una de las tablas de la clusula from , titleauthor , no contribuye ni nguna columna a los resultados. Ni tampoco ninguna de las columnas que se combin an, au_id y title_id , aparecen en los resultados. No obstante, esta combinacin e s posible nicamente mediante el uso de titleauthor como tabla intermedia. Tambin pueden combinarse ms de dos pares de columnas en la misma instruccin. Por ej emplo, 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, r oysched where titles.title_id = roysched.title_id and total_sales >= loran ge and total_sales < hirange title_id total_sales lorange hirange royalty ------------------ ------ ------- ------- BU1032 4095 0 5000 10 BU1 111 3876 0 4000 10 BU2075 18722 14001 50000 24 BU7832 4095 0 5000 10 MC2222 2032 2001 4000 12 MC3021 2224 12001 5000 0 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 PS 7777 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 fil as no coincidentes en los resultados de una combinacin. En tales ocasiones, la co mbinacin externa es la operacin de eleccin. Transact-SQL es una de las pocas versio nes 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 edito r 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 m isma 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 NUL L Cheryl Carson Algodata Infosystems Michael O'Leary NULL Dick Straight NULL Meander Smith NULL Abraham Bennet Algodata Infosystems Ann Dull NULL Burt Gringlesby NULL Chastity Locksley NULL Morningstar Greene NULL Reginald Blotche-Halls N ULL Akiko Yokomoto NULL Innes del Castillo NULL Michel DeFrance NULL Dirk Stringer NULL Stearn s MacFeather NULL Livia Karsen NULL Sylvia Panteley NULL Sheryl Hunter NULL Heather McBad den NULL Anne Ringer NULL Albert Ringer NULL (23 rows affected) El operador de comparacin "*=" distingue la combinacin externa de una ordinaria. E sta combinacin externa "izquierda" indica a SQL Server que incluya todas las fila s de la tabla authors en los resultados, exista o no una coincidencia en la colu mna 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 con tienen 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 d e "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 t abla, independientemente de si existen datos coincidentes en la primera tabla. La sustitucin de este operador en la consulta de combinacin externa anterior da es te 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 & Hardl ey Cheryl Carson Algodata Infosystems Abraham Bennet Al godata 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 real mente deseados y utilizar la combinacin externa para mostrar las filas que no ent raron en el corte. Primero observe la equicombinacin y luego comprela con la combi nacin 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 qt y > 500 and salesdetail.title_id = titles.title_id stor_id title -------------------------------------------------- 5023 Sushi, Anyone? 5023 Is Anger the Enemy? 5023 The Gourmet M icrowave 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 E motional Security: A New Algorithm 5023 The Busy Executive's Database Gu ide 5023 Fifty Years in Buckingham Palace Kitchens 5023 Prolonged Data Deprivation: Four Case Studies 5023 Cooking with Computers: Surrepti tious Balance Sheets 7067 Fifty Years in Buckingham Palace Kitchens ( 14 rows affected) Para mostrar, adems, los ttulos que no vendieron ms de 500 copias en cualquier libr era, puede utilizar una consulta de combinacin externa:

select distinct salesdetail.stor_id, title from titles, salesdetail where q ty > 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 Fi fty Years in Buckingham Palace Kitchens 7067 Fifty Years in Buckingham P alace Kitchens 5023 Prolonged Data Deprivation: Four Case Studies 502 3 Cooking with Computers: Surreptitious Balance Sheets NULL Comput er Phobic and Non-Phobic Individuals: Behavior Variations NU LL Onions, Leeks, and Garlic: Cooking Secrets of the Medite rranean (18 rows affected) Restricciones de las combinaciones externas En Transact-SQL, una tabla no puede participar en una clusula de combinacin extern a 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, s alesdetail 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 combina cin externa y una calificacin en una columna de la tabla interna de la combinacin e xterna, los resultados pueden ser distintos de los esperados. La calificacin de l a 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, aparec e un valor nulo en las columnas de la tabla interna de dichas filas. #endregion #region Efecto de los valores nulos sobre las combinaciones Si las columnas de las tablas combinadas contienen valores nulos, stos nunca pued en coincidir. Adems, el resultado de una combinacin de NULL con cualquier otro val or, es NULL. Dado que los valores nulos representan valores desconocidos o inapl icables, Transact-SQL no tiene ningn motivo para creer que un valor desconocido c oincide con otro. 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 f ormar parte de la combinacin. Una combinacin externa izquierda muestra el valor NU LL en la primera tabla. Tabla 1: a NULL Tabla 2: c b three --------4 -----join4 -----1 one

d --------4 four Combinacin externa izquierda:

NULL

two

select * from t1, t2 where a *= c a b c d ----------- ------ ---------------1 one NULL NULL NULL three NULL NULL 4 join4 4 four Observe que los resultados no facilitan la distincin entre un valor NULL en los d atos y uno NULL que representa un fallo de la combinacin. Cuando hay valores nulo s en los datos que van a combinarse, generalmente es preferible omitirlos de los resultados mediante el uso de una combinacin regular. #endregion #region Determinacin de las columnas de tabla que deben combinarse El procedimiento del sistema sp_helpjoins muestra las columnas de dos tablas o v istas 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 comprue ba si se defini alguna clave comn en las dos tablas con sp_commonkey . Si no encue ntra ninguna clave comn, el procedimiento aplica criterios menos restrictivos par a proponer cualquier clave que pueda combinarse de forma razonable; busca las cl aves con los mismos tipos de datos de usuario y, si falla, busca las columnas co n el mismo nombre y tipo de datos. Para obtener informacin completa sobre los procedimientos del sistema, consulte e l Manual de Referencia de SQL Server . #endregion #endregion #region SUBCONSULTAS: USO DE CONSULTAS DENTRO DE OTRAS CONSULTAS #region 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 r esultado 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 exter na, o bien a una tabla distinta. En Transact-SQL, una subconsulta puede usarse p rcticamente en cualquier lugar donde se permita una expresin, siempre que la subco nsulta 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 ins truccin 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 int ernas , pueden formularse alternativamente como combinaciones. Otras preguntas sl o pueden formularse con subconsultas. Algunos prefieren las subconsultas a las f ormulaciones alternativas porque son ms fciles de entender. Otros usuarios de SQL evitan las consultas siempre que sea posible. Usted puede elegir la formulacin qu e 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 Str aight 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 pre cio 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 Gastronomi c 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 = (select price from titles where title = "Straight Talk About Computers") title price ------------------------------------------ The Busy Executive's Database Guide 19.99 S traight 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 instru ccin select de la consulta tiene una sintaxis select algo restringida, como puede verse en este ejemplo. Las subconsultas pueden anidarse dentro de la clusula where o having de una instr uccin externa select , insert , update o delete , dentro de otra subconsulta, o e n una lista de seleccin. En Transact-SQL, una subconsulta puede aparecer prcticamente en cualquier lugar d onde 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 pued e 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 d ebe 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 e xterna, est implcitamente calificada por el nombre de tabla publishers de la clusul a from , de la consulta externa. La referencia a pub_id en la lista de seleccin d e la subconsulta est calificada por la clusula from de la subconsulta, es decir, p or la tabla titles : select pub_name from publishers where pub_id in (select pub_id f rom titles where type = "business") 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 im plcitas: select pub_name from publishers where publishers.pub_id in (select tit les.pub_id from titles where type = "business") Nunca es incorrecto indicar explcitamente el nombre de una tabla, y siempre es po sible ignorar las suposiciones implcitas relativas a los nombres de las tablas ca lificando dichos nombres de forma explcita. Subconsultas con nombres de correlacin Como se explic en el Captulo 4, "Combinaciones: recuperacin de datos de varias tabl as", los nombres de correlacin de tabla en las autocombinaciones son necesarios p orque la tabla autocombinada aparece en dos roles distintos. Los nombres de corr elacin tambin pueden emplearse en consultas anidadas que hacen referencia a la mis ma tabla en una consulta interna y en otra externa. Por ejemplo, los autores que viven en la misma ciudad que Livia Karsen pueden en contrarse 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 = "Liv ia" 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 s ubconsulta no tiene el mismo significado que la referencia a authors en la consu lta externa. Sin la correlacin explcita, la subconsulta tiene este aspecto: select au_lname, au_fname, city from authors where city in (select cit y from authors where au_fname = "Livia" and au_lname = "Karsen ") La consulta anterior, y otras instrucciones en las que la subconsulta y la consu lta externa hacen referencia a la misma tabla, puede definirse de forma alternat iva como una autocombinacin: select au1.au_lname, au1.au_fname, au1.city from authors au1, authors au2 w here au1.city = au2.city and au2.au_lname = "Karsen" and au2.au_fname = "Liv ia" Es posible que los resultados de una subconsulta redefinida como una combinacin n o aparezcan en el mismo orden, y la combinacin puede necesitar la palabra clave d

istinct para eliminar los duplicados. Niveles mltiples de anidacin Una subconsulta puede incluir otra subconsulta o varias. En una instruccin es pos ible anidar hasta 16 subconsultas. Un ejemplo de problema que puede resolverse usando una instruccin con mltiples niv eles de consultas anidadas es "buscar los nombres de los autores que hayan parti cipado 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 She ryl 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 PC1 035, PC8888 y PC9999. Esta consulta tambin puede expresarse como una combinacin: select au_lname, au_fname from authors, titles, titleauthor where authors.a u_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 c omo en instrucciones select . Note: La ejecucin de estos ejemplos de consulta cambiar la base de datos pubs2 . P ara obtener una copia limpia de la base de datos de muestra, es necesario solici tarla 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 where type = "business") Una instruccin delete equivalente que usa una combinacin es: from titles

delete salesdetail from salesdetail, titles where salesdetail.title_id = ti tles.title_id and type = "business" Subconsultas en instrucciones condicionales Las subconsultas tambin pueden utilizarse en instrucciones condicionales. La subc onsulta anterior que elimin todos los registros de ventas de libros de negocios p odra 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 ofrece n algunos ejemplos que ilustran el modo en que puede utilizarse esta mejora de T ransact-SQL. La siguiente instruccin busca los ttulos y tipos de libros escritos por autores re sidentes 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") a nd 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 Comp uters: Surreptitious Balance Sheets business Straight Talk About Com puters business But Is It User Friendly? popular_comp Sec rets 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 co pias, muestra sus precios y el precio del libro ms caro: select title, price, (select max(price) from titles) from titles where total_sales > 5000 title price --------------------------------------- ------ You Can Combat Computer Stress! 2.99 22.95 The Gourme t Microwave 2.99 22.95 But Is It User Friendly? 2 2.95 22.95 Fifty Years in Buckingham Palace Kitchens 11.95 22.95 #endregion #region Tipos de subconsultas Existen dos tipos bsicos de subconsultas: Las subconsultas introducidas con un operador de comparacin sin modificar y que d eben devolver un solo valor se conocen como subconsultas de expresin . Las subconsultas que operan en listas introducidas con in o con un operador de c omparacin 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 corr elacionadas. Una subconsulta no correlacionada puede evaluarse como una consulta independient e. En trminos conceptuales, los resultados de la subconsulta se usan en la instru ccin principal, o consulta externa. Esta no es la forma real en que SQL Server pr ocesa las instrucciones con subconsultas. Las subconsultas no correlacionadas pu eden definirse alternativamente como combinaciones y SQL Server las procesa como combinaciones. Una subconsulta correlacionada no puede evaluarse como una consulta independient

e, pero puede hacer referencia a las columnas de la tabla especificada en la lis ta 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. #endregion #region 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 dec ir, 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 compar acin sin modificar, el usuario est suficientemente familiarizado con sus datos y c on la naturaleza del problema para tener la certeza de que la subconsulta va a d evolver un valor. Por ejemplo, supongamos que cada editor est ubicado en una sola ciudad. Para busc ar 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 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 so lo 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 t itles) title --------------------------------------------------- The Busy Executive 's Database Guide Cooking with Computers: Surreptitious Balance Sheets Straight Talk About Computers Silicon Valley Gastronomic Treats But Is It Us er Friendly? Secrets of Silicon Valley Computer Phobic and Non-Phobic Indivi duals: Behavior Variations Is Anger the Enemy? Life Without Fear Pro longed 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 n o 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 t itles group by type having type = "trad_cook") Uso de distinct con subconsultas de expresin Las subconsultas introducidas con operadores de comparacin sin modificar, a menud o incluyen la palabra clave distinct para devolver un solo valor. Por ejemplo, sin distinct , la siguiente subconsulta no se ejecutara de forma cor recta porque devolvera ms de un valor: select pub_name from publishers ub_id from titles #endregion #region 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 puede n incluir una clusula group by o having , tienen este formato general: [Comienzo de instruccin o subconsulta select , insert , update , delete ] where expression comparison_operator [any | all] ( subquery ) [Final de instruccin o subconsulta select , insert , update , delete ] Las subconsultas introducidas con in o not in tienen este formato general:[Comie nzo 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 exi stencia cuyo formato general es el siguiente: [Comienzo de instruccin o subconsul ta 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 un a subconsulta. Tomando el operador de comparacin > como ejemplo: >all significa mayor que todos los valores o mayor que el valor mximo. Por ejempl o, >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 n ingn valor, toda la consulta fracasa. where pub_id = (select distinct p where pub_id = publishers.pub_id)

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 formul arse la pregunta "Qu libros tuvieron un anticipo superior al de cualquier libro ed itado por New Age Books?". Esta pregunta puede parafrasearse para que su "traduccin" en SQL sea ms clara: "Qu l ibros 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 fro m publishers, titles where titles.pub_id = publishers.pub_id and pub _name = "New Age Books") title ---------------------------------------- The Gourmet Microwave (1 row affected) Para cada ttulo, la consulta externa obtiene los ttulos y anticipos de la tabla ti tles 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 s i 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 introduc e la subconsulta debe ser mayor que todos los valores devueltos por la subconsul ta. 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 Frie ndly? 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 N ULL, la consulta devuelve 0 filas. Esto se debe a que NULL significa "valor desc onocido", 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 li bro 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 , c on precio nulo. =all significa igual a todos los valores El operador =all significa igual a todos los valores. Para que una fila cumpla c on la condicin especificada en la consulta externa, el valor de la columna que in troduce la subconsulta debe ser igual a todos los valores de la lista devuelta p or la subconsulta. Por ejemplo, la siguiente consulta busca los autores que viven en la misma ciuda d examinando el cdigo postal: select au_fname, au_lname, city from authors where city = all ity from authors where postalcode like "946%") (select c

> any significa mayor que algn valor >any significa que, para que una fila cumpla la condicin especificada en la consu lta 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 subconsu lta. 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 Ag e Books. select title from titles where advance > any (select advance fro m 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 C ombat Computer Stress! Emotional Security: A New Algorithm The Busy Executive' s Database Guide Fifty Years in Buckingham Palace Kitchens Cooking with Comput ers: Surreptitious Balance Sheets Computer Phobic and Non-Phobic Individua ls: 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 un a lista de importes de los anticipos pagados por New Age Books. La consulta exte rna examina todos los valores de la lista y determina si el ttulo en cuestin ha re cibido un anticipo superior a cualquiera de dichos valores. En otras palabras, e l ejemplo busca los ttulos con anticipos iguales o superiores al valor mnimo pagad o 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, pue de 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 ciud ad donde no hay ningn editor. En tal caso, podra probarse con esta consulta: 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 viv en 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 edit ores y luego, para cada ciudad, la consulta externa busca los autores que no viv en 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 Smi th Meander White Johnson Greene Morningstar G reen Marjorie Straight Dick Stringer Dirk MacFeath er 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 Ca rson y Abraham Bennet, que viven en Berkeley, donde est la sede de Algodata Infos ystems. 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 editor es que publicaron libros de negocios: select pub_name from publishers where pub_id in (select pub_id f rom titles where type = "business") pub_name ---------------------------------------- New Age Books Algodata Infosystems (2 rows affected) Esta instruccin se evala en dos pasos. En primer lugar, la consulta interna devuel ve 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 publ ishers . 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 utiliz ar otros tipos de expresiones, como las combinaciones de constantes y nombres de columna. Las consultas anteriores, al igual que muchas otras subconsultas, pueden formula rse 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 pu blicaron libros de negocios. Todas son correctas y generan los mismos resultados , pero quizs sea necesario usar la palabra clave distinct para eliminar los dupli cados. Sin embargo, una ventaja del uso de una consulta de combinacin, para este problem a y otros similares, en lugar de una subconsulta, es que la consulta de combinac in 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 com binacin:

select pub_name, title from publishers, titles where publishers.pub_id = ti tles.pub_id and type = "business" pub_name title -------------------- --------------------------------------- Algodata Infosystems The Busy Executive's Database Guide Algo data Infosystems Cooking with Computers: Surreptitious Balance Sheets New Age Books You Can Combat Computer Stress! Algoda ta Infosystems Straight Talk About Computers (4 rows affected) El siguiente es otro ejemplo de instruccin que puede formularse con una subconsul ta o con una consulta de combinacin. La versin de la consulta es: "buscar los nomb res 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 ins truccin es: select au_lname, au_fname from authors where state = "CA" and au_id in (select au_id from titleauthor where royaltyper < 30 and au _ord = 2) au_lname au_fname ------------------------ ------------ Mac Feather 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 lo s 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 pue de expresarse frecuentemente como una combinacin. Uso Las ven t = de subconsultas con not in subconsultas introducidas por la frase de palabras clave not in tambin devuel una lista con 0 y valores superiores. not in significa "no = a y no = b y no c".

Esta consulta busca los nombres de los editores que no han editado libros de neg ocios, 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 sus tituye a in . S in embargo, esta instruccin no puede convertirse en una combinacin . La combinacin anloga "no igual" tiene un significado diferente: busca los nombre s de los editores que publicaron algn libro que no sea de negocios. Las dificulta des para interpretar el significado de las combinaciones no basadas en la iguald ad 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 fil a de la consulta externa. Si el valor de esta consulta no se encuentra en el con junto 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 lor coincidente, pero contiene uno NULL, Esto se debe a que NULL significa "valor valor que se est buscando se encuentra La consulta externa omite la fila.

la consulta interna no contiene ningn va not in devuelve UNKNOWN (desconocido). desconocido" y es imposible saber si el en un conjunto con un valor desconocido.

Por ejemplo, si se usa la base de datos pubs2 : select pub_name from publishers 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. Bin net & Handley y Algodata Infosystems no aparecen en los resultados de la consult a 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 compr ueba 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 p ublican libros de negocios: select pub_name from publishers where exists (select * from titl es 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 cad a editor. Este valor, hace que la subconsulta devuelva al menos una fila?. En otr as palabras, hace que la prueba de existencia de como resultado TRUE?. En los resultados de la consulta anterior, el segundo nombre de editor es Algoda ta Infosystems, cuyo nmero de identificacin es 1389. Hay alguna fila en la tabla ti tles en la que pub_id sea 1389 y type sea "business"?. En caso afirmativo, "Algo data Infosystems" debera ser uno de los valores seleccionados. El mismo proceso s e 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 otr as 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 compro bando la existencia o inexistencia de filas que cumplen las condiciones especifi cadas 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 estn dar. La palabra clave exists es muy importante, porque a menudo no hay ninguna formul acin 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 o tra forma, todas las consultas que utilizan in o un operador de comparacin modifi cado por any o all pueden expresarse con exists . A continuacin se muestran algun os 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 edito r: select au_lname, au_fname from authors where city =any (select city from publishers) select au_lname, au_fname from authors where exists (select * fr om 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 edit or 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 pub lishers where city like "B%") title --------------------------------------------------- The Busy Executive' s Database Guide Cooking with Computers: Surreptitious Balance Sheets Y ou Can Combat Computer Stress! Straight Talk About Computers But Is I t User Friendly? Secrets of Silicon Valley Net Etiquette Is Anger the Enemy? Life Without Fear Prolonged Data Deprivation: Four Case Studies Emotio nal 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 whe re 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 n egocios, 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 r ow affected) 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 ope raciones de la teora de conjuntos: interseccin y diferencia. La interseccin de dos conjuntos contiene todos los elementos pertenecientes a los dos conjuntos origin ales. La diferencia contiene los elementos pertenecientes slo al primero de los d os conjuntos. La interseccin de authors y publishers en la columna city es el conjunto de ciuda des en las que hay un autor y un editor: select distinct city from authors where exists (select * from publ ishers where authors.city = publishers.city) city -------------------- Berkeley (1 row affected) La diferencia entre authors y publishers en la columna city es el conjunto de ci

udades 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 O akland Lawrence San Jose Ann Arbor Corvallis Nashville Palo Alto Rockville Vacaville Menlo Park W alnut Creek San Francisco Salt Lake City (15 rows aff ected) #endregion #region 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 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 Marjori e Panteley Sylvia Locksley Chastit y del Castillo Innes Blotchet-Hall Reginal d (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 author s . au_id , pero este valor es una variable: cambia a medida que SQL Server exam ina las distintas filas de la tabla authors . Este es el modo en que se evala la consulta anterior: Transact-SQL tiene en cuent a todas las filas de la tabla authors para su inclusin en los resultados utilizan do el valor de cada fila para la consulta interna. Por ejemplo, supongamos que T ransact-SQL examina primero la fila de Cheryl Carson. A continuacin, authors.au_i d 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 l os resultados. Si se realiza el mismo procedimiento con la fila de Abraham Benne t, 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 publ icados por ms de un editor: e select distinct t1.type from titles t2 from titles t1 where t1.type in where t1.pub_id != t2.pub_id) (select t2.typ

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: 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 l ike "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 -V-7 4 title_id qty ------------------ ---------PS3333 90 91-A-7 PS2106 30 55 PS2106 31 AX-532-FED-452-2Z7 PS7777 125 BA7122 PS7777 200 NB-3.142 PS2091 200 NB-3.142 PS7777 250 NB-3.142 PS3333 345 ZD-123-DFG -752-9G8 PS3333 750 91-A-7 PS7777 180 356921 PS3333 200 (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 se leccin en la consulta externa. Por cada valor posible de s1 , Transact-SQL evala l a subconsulta e incluye el registro considerado en los resultados, si la cantida d 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 lo s libros de su mismo tipo, esta sera la consulta: select t1.type, t1.title from titles t1 where t1.price > (select avg(t 2.price) from titles t2 where t1.type = t2.type) type title ---------------------------------------------- busin ess The Busy Executive's Database Guide business Straight Talk About C omputers mod_cook Silicon Valley Gastronomic Treats popular_comp But Is It User Friendly? psychology Computer Phobic and Non-Phobic I ndividuals: 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 fil a 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, porqu e las filas para las que se calcula el promedio del precio estn restringidas por la clusula where de la subconsulta. Subconsultas correlacionadas en una clusula having Las subconsultas de predicado cuantificado pueden ser subconsultas correlacionad as. Este ejemplo de una subconsulta correlacionada en la clusula having de una consul ta externa busca los tipos de libros cuyo mximo anticipo es ms del doble del prome dio de un grupo dado: select t1.type from titles t1 group by t1.type having max(t1.advance) >=a ny (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 cons ulta externa, es decir, una vez para cada tipo de libro. #endregion #endregion #region USO Y CREACIN DE TIPOS DE DATOS #region Qu son los tipos de datos Transact-SQL? SQL Server suministra algunos tipos de datos del sistema y dos tipos de datos de finidos por el usuario: timestamp y sysname . Es posible utilizar el procedimien to del sistema sp_addtype para crear tipos de datos definidos por el usuarios en base a los tipos de datos del sistema. Para determinar los tipos de datos definidos para las columnas de tablas existen tes, use el procedimiento del sistema sp_help . #endregion #region Tipos de datos suministrados por el sistema NUMRICOS EXACTOS: ENTEROS int (-2.147.483.648) a (2.147.483.647) b) smallint (-32.768) a (32.767) nteger de vb) tinyint 0 a 255 (equiv al tipo byte de vb)

(equiv al tipo long de v (equiv al tipo i

NUMRICOS EXACTOS: DECIMALES -->no-->numeric (p, s) --> slo los tipos numeric con una escala de 0 pueden utili zarse para la columna IDENTITY. decimal (p, s) NUMRICOS APROXIMADOS float (precision) double real MONETARIOS smallmoney money FECHA/HORA smalldatetime datetime 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

#region chapa La informacin de fecha y hora debe incluirse entre comillas simples o dobles. Pue de introducirse en maysculas o en minsculas, y puede contener espacios entre las p artes de los datos. SQL Server reconoce una amplia variedad de formatos de entra da 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 d e fechas. Tambin es posible realizar algunos clculos aritmticos con valores datetim e mediante las funciones de fecha incorporadas. #endregion CARACTERES char(n) y varchar(n) (hasta 8000 caracteres). char(n) se rellena con blancos has

ta la longitud especificada Nota: nchar(n) y nvarchar(n) igual que los anteriores pero para almacenar UNICOD E text (2.147.483.647) no unicode Para aadir datos sin guardar grandes bloques de texto en el diario de transaccion es, utilice writetext . SQL Server trunca las entradas segn la longitud de columna especificada sin indic ar ningn mensaje de advertencia o error, a menos que se defina string_rtruncation on . 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". #region chapa? -?->character -?->character varying, char varying -?->national character, national char -?->nchar varying, national char varying, national character varying longitud de entrada real n * @@ncharsize @@ncharsize * nmero de caracteres nchar(n) Datos de longitud fija en juegos de caracteres multibyte n * @@ncharsize nvarchar(n) Datos de longitud variable en juegos de caracteres multibyte Nmero real de caracteres * @@ncharsize 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 ha sta la longitud de columna. Para el tipo de datos char , el tamao de almacenamien to es n bytes; para el tipo de datos nchar , es n veces la longitud de caractere s nacionales promedio ( @@ncharsize ). Al crear una columna char o nchar que per mite 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 bl anco posteriores; el tamao de almacenamiento es la longitud real de los datos. Pa ra columnas varchar , es el nmero de caracteres; para columnas nvarchar , es el nm ero de caracteres por la longitud de caracteres promedio. Los datos de caractere s de longitud variable necesitan menos espacio que los de longitud fija, pero el acceso a ellos es algo ms lento. #endregion BINARIOS binary(n) varbinary(n) image #region chapa? Tipos de datos binarios Los tipos de datos binarios almacenan datos binarios en bruto, como imgenes, en u na notacin semejante a la hexadecimal. Los datos binarios comienzan con los carac teres "0x" e incluyen cualquier combinacin de dgitos, as como las letras A-F mayscul as 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 . Co nsulte el Captulo 10, "Uso de funciones incorporadas en consultas". Utilice los tipos de datos binary(n) y varbinary(n) para almacenar datos de hast a 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 varbi nary , pero el acceso a stas ltimas ser algo ms rpido. Utilice el tipo binario de longitud variable varbinary(n) , para datos cuya long itud 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 po steriores se truncan. Al crear una columna binary que admite valores nulos, SQL Server la convierte au tomticamente 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 rea lizar operaciones con ellas mediante las funciones de cadena incorporadas. Debid o a que el formato exacto donde se introduce un valor determinado depende del ha rdware que est utilizndose , los clculos en los que se utilizan datos binarios pued en 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.64 7 bytes de datos en listas enlazadas de pginas de datos, aparte de otros datos pa ra 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. Para ahorrar espacio de almacenamiento, defina las columnas image como NULL. Par a aadir datos image sin guardar grandes bloques de texto en el diario de transacc iones, utilice writetext . Consulte el Manual de Referencia de SQL Server para o btener informacin detallada. #endregion BIT bit 0 o 1 #region chapa 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. 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 desplaz amiento exclusiva para las columnas bit. #endregion #region 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 Ope n Client(TM) DB-Library(TM). Cada vez que se inserta o actualiza una fila con una columna timestamp , la colu mna timestamp se actualiza automticamente. Una tabla slo puede tener una columna d el 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 uti lizarse para definir otros tipos de datos definidos por el usuario. Es preciso i ntroducirlo como "timestamp", con todas las letras en minsculas. #endregion #region Tipo de datos sysname sysname es un tipo de datos definido por el usuario incluido en la cinta de inst alacin 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 emba rgo, 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 par a crear columnas. Para obtener ms informacin acerca de los tipos de datos definido s por el usuario, consulte "Creacin de tipos de datos definidos por el usuario". #endregion #endregion #region 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 otra s conversiones con las funciones convert , inttohex y hextoint . Sin embargo, no es posible realizar otras conversiones, ni explcita ni automticamente, debido a i ncompatibilidades 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 n ecesario 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 ( datatype , Por ejemplo: expression , [ style ])

select title, total_sales from titles where convert (char(20), total_sales) like "2%" 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 visu alizacin de fecha. Consulte el Captulo 10 para obtener informacin detallada sobre las funciones conve rt , inttohex y hextoint . #endregion #region Aritmtica de modo mixto y jerarqua de tipos de datos Al realizar operaciones aritmticas con valores de distintos tipos de datos, SQL S erver debe determinar el tipo de datos y, en algunos casos, la longitud y precis in del resultado.

Cada tipo de datos del sistema tiene una jerarqua de tipos de datos , que se alma cena en la tabla del sistema systypes . Los tipos de datos definidos por el usua rio 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 c onsulta 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 varb inary 21 timestamp 21 bi nary 22 text 23 image 24 (28 rows affected) La jerarqua de tipos de datos determina el resultado de los clculos en que se util izan 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 t abla 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 de l 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 resul tados del tipo money , emplee literales o variables money : select moneycol * $2.5 from mytable 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 valor es 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 co mo se indica a continuacin: Tabla 6-8: Precisin y escala despus de realizar operaciones aritmtica Operacin Precisin Escala n1 + n2 mx(s1, s2) + mx(p1 -s1, p2 - s2) + 1 mx(s1, s2)

n1 - n2 mx(s1, s2) + mx(p1 -s1, p2 - s2) + 1 mx(s1, s2) n1 * n2 s1 + s2 + (p1 - s1) + (p2 - s2) + 1 s1 + s2 n1 / n2 mx(s1 + p2 + 1, 6) + p1 - s1 + p2 mx(s1 + p2 -s2 + 1, 6)

#endregion #region 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 dato s 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. E sto 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 cualqui er 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 posib le vincularles reglas y valores predeterminados para utilizarlos en varias tabla s. 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 crendos e, el tipo de datos suministrado por SQL Server a partir del que est crendose, y u na especificacin NULL, NOT NULL o IDENTITY opcional. Se puede crear un tipo de datos definido por el usuario utilizando cualquier tip o de datos del sistema menos t imestamp . Los tipos de datos definidos por el us uario tienen la misma jerarqua de tipos de datos que los tipos de datos del siste ma en que estn basados. Pero, a diferencia de los tipos de datos suministrados po r SQL Server, los nombres de los tipos de datos definidos por el usuario disting uen entre maysculas y minsculas. Sintaxis de sp_addtype : sp_addtype datatypename , phystype [, "identity" | nulltype ] tid se ha definido de la siguiente forma: [(length) | (precision [, scale])]

sp_addtype tid, "char(6)", "not null" Es preciso incluir un parmetro entre comillas simples o dobles, si contiene un es pacio en blanco o algn signo de puntuacin, o si es una palabra clave distinta de n ull (por ejemplo, identity o sp_helpgroup ). En este ejemplo, es necesario inclu ir char(6 ) entre comillas debido al parntesis, as como NOT NULL, debido al espaci o en blanco. No es preciso incluir tid entre comillas.

Especificacin de la longitud, precisin y escala Al crear un tipo de datos definido por el usuario basado en determinados tipos d e 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, S QL Server utiliza la longitud predeterminada de un carcter. Para el tipo de datos float , puede suministrarse un valor de precisin entre parnt esis. 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 prec isin y de escala entre parntesis, separados por una coma. Si no se suministran, SQ L Server utiliza la precisin y escala predeterminadas de 18 y 0. No es posible cambiar la especificacin de longitud, precisin o escala al incluir e l 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 val ores nulos. Es posible crear un tipo de datos definido por el usuario con un tip o nulo "null", "NULL", "nonull", "NONULL", " not null " o " NOT NULL". Por defin icin, 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 va lores predeterminados con el tipo de datos. Con el procedimiento del sistema sp_ help , se puede imprimir un informe que enumere las reglas, valores predetermina dos e informacin adicional asociados con el tipo de datos. Las reglas y los valores predeterminados se describen en el Captulo 12. Para obte ner 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. #endregion #region Obtencin de informacin sobre tipos de datos Utilice el procedimiento del sistema sp_help para mostrar informacin sobre las pr opiedades de un tipo de datos del sistema o de uno definido por el usuario. El i nforme indica el tipo base a partir del que se ha creado el tipo de datos, si ad mite o no valores nulos, los nombres o cualquier regla o valor predeterminado vi nculados al tipo de datos, y si dispone de la propiedad IDENTITY.

En los ejemplos siguientes, se muestra informacin sobre el tipo de datos del sist ema 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 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) #endregion #endregion #region CREACIN DE BASES DE DATOS Y TABLAS #region Definicin de base de datos y de tabla Una base de datos almacena informacin (datos) en un conjunto de objetos de base d e datos, tales como tablas, relacionados entre s. Una tabla es un conjunto de fil as que tienen columnas asociadas con elementos de datos individuales. La organiz acin 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 tabla s, incluyendo las restricciones de integridad. 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 e numerados en sysobjects . Las columnas y tipos de datos se explican en este captu lo; 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 lo s valores de los datos que los usuarios pueden insertar, eliminar o actualizar e n 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 tab la publishers . No se debe insertar libros en titles que no tengan un editor vlid o, ya que esto viola la integridad de los datos de pubs2 . Transact-SQL proporciona varios mecanismos para imponer la integridad en una bas e de datos, como reglas, valores predeterminados, ndices y disparadores, que perm iten mantener los siguientes tipos de integridad de datos: Requisito: esta integridad requiere que una columna de tabla contenga un valor vl ido en cada fila; no permite valores nulos. La instruccin create table permite re stringir los valores nulos de una columna. Verificacin o validez: esta integridad limita o restringe los valores de datos in sertados 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 co n 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 colum na de la misma tabla. Para imponer esta integridad, pueden utilizarse disparador es. La consistencia de los valores de datos de la base de datos es otra integridad d e 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 p arte de la instruccin create table para imponer la integridad de datos segn las no rmas SQL. Estas restricciones de integridad se describen ms adelante en este captu lo. Permisos dentro de bases de datos La posibilidad de crear y omitir bases de datos y objetos de base de datos depen de 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. E stos 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 s ysusers . El guin que crea pubs2 concede una gran variedad de permisos al " invit ado " . El mecanismo " invitado " significa que cualquiera que tenga un login en SQL Ser ver, es decir, que aparezca en master.. syslogins , tendr acceso a pubs2 y permis o para crear y omitir objetos como tablas, ndices, valores predeterminados, regla s, procedimientos, etc.. El nombre de usuario " invitado " tambin permite utiliza

r algunos procedimientos almacenados, crear tipos de datos definidos por el usua rio, consultar la base de datos y modificar sus datos. Para utilizar la base de datos pubs2 , emita el comando use . SQL Server verific a si su nombre de usuario aparece en pubs2.. sysusers . Si no aparece, ser admiti do como invitado sin ms trmite. Si su nombre aparece en pubs2.. sysusers , ser admi tido, pero sus permisos pueden ser diferentes de los de " invitado " . Todos los ejemplos de este captulo suponen que usted es un " invitado " . #endregion #region Uso y creacin de bases de datos 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 sist ema : La base de datos master controla las bases de datos del usuario y el funcionamie nto de SQL Server como un todo. La base de datos sybsystemprocs contiene los procedimientos almacenados del sist ema. La base de datos temporal, tempdb , almacena los objetos temporales, incluidas l as 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 muestr a, pubs2 , y la base de datos de sintaxis, sybsyntax , mediante isql y los guion es SQL incluidos en el directorio scripts . La base de datos pubs2 sirve como ba se para la mayora de los ejemplos de la documentacin de SQL Server. La base de dat os sybsyntax almacena toda la informacin de sintaxis de los comandos y procedimie ntos a los que se tiene acceso mediante sp_syntax . Las bases de datos pubs2 y sybsyntax son bases de datos del usuario. Todos sus atos - el motivo para usar un sistema de administracin de bases de datos - se acenan en bases de datos del usuario. SQL Server administra cada base de datos ediante las tablas del sistema. Las tablas del diccionario de datos de la base e datos master y de otras bases de datos se consideran tablas del sistema. d alm m d

Seleccin de una base de datos: use La mayor parte del tiempo, usted utilizar una base de datos que ya existe. La sin taxis 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 si es un usuario conocido en saje de error. El propietario a base de datos ejecutando el a la base de datos pubs2 mediante dicho comando slo pubs2 . De lo contrario, SQL Server muestra un men de la base de datos decide quin tiene acceso a dich procedimiento del sistema sp_adduser.

La mayora de los usuarios podrn ver las tablas del sistema de la base de datos mas ter como invitados, segn se explic anteriormente. Los usuarios que no son reconoci dos por nombre en la base de datos master pueden tener acceso a la misma como us

uarios " 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 cualq uier base de datos de usuario con el procedimiento del sistema sp_adduser . Los administradores del sistema se convierten automticamente en los propietarios de l as base de datos que usan. Para obtener ms informacin, consulte la Gua de Administr acin del Sistema o el Manual del Referencia de SQL Server . Es probable que se conecte automticamente a la base de datos master cuando haga e l login a SQL Server, de manera que deber ejecutar el comando use para tener acce so a otra base de datos. Tanto usted como el administrador del sistema pueden ca mbiar la base de datos a la que se conectan inicialmente mediante el procedimien to 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 c reate 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 ad ministrador del sistema crea todas las bases de datos. El autor de la base de da tos es su propietario. Si otro usuario crea la base de datos, puede transferirle los derechos de propiedad mediante el procedimiento del sistema sp_changedbowne r . El propietario de la base de datos es responsable de proporcionar acceso a la ba se 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 respons able de mantener copias de seguridad peridicas de la base de datos y de volver a cargarla en caso de un fallo del sistema. El propietario de la base de datos sie mpre puede hacerse pasar por cualquier otro usuario de la base de datos, consigu iendo temporalmente los permisos de tales usuarios, mediante el comando setuser . Dado que cada base de datos tiene asignada una cantidad importante de espacio, a unque 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 est a 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 regla s para identificadores proporcionadas en el Captulo 1. SQL Server puede administr ar 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 sy susages de la base de datos master . Esta es la sintaxis completa del comando create database :

create database database_name [on {default | database_device } [= si ze ] [, database_device [= size ]]...] [log on database_devic e [= 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 Adminis tracin del Sistema . Note: En los ejemplos anteriores y en los de la siguiente seccin, no se muestra l a clusula log on por razones de simplicidad. Sin embargo, cuando cree bases de da tos de produccin, siempre debe hacerlo con la clusula log on . Consulte la siguien te seccin. La clusula on La clusula opcional on permite especificar la posicin donde debe almacenarse la ba se de datos y la cantidad de espacio en megabytes que se le debe asignar. Si uti liza la palabra clave default , la base de datos se asignar a un dispositivo de b ases de datos del banco de dispositivos de bases de datos indicado en la tabla s ysdevices de la base de datos master . Emplee el procedimiento del sistema sp_he lpdevice para ver los dispositivos de la lista predeterminada. Note: Un administrador del sistema puede tener ciertas asignaciones de almacenam iento basadas en estadsticas de rendimiento y otras consideraciones. Antes de cre ar 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 diferent es 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 : 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 de l 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 22 3 MB. La clusula log on A menos que est creando bases de datos pequeas y no esenciales, siempre deber utili zar 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 , ahorran do as tiempo y cintas. Permite establecer un tamao fijo para el diario, dejando as espacio libre para otr as actividades de la base de datos. Hay otras razones para situar el diario en un dispositivo fsico distinto del de l as 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 proce dimiento del sistema sp_extendsegment . Consulte el Manual de Referencia de SQL Server o la Gua de Administracin de Sistema SQL Server para obtener informacin adic ional. El tamao del dispositivo requerido para el diario de transacciones vara segn la can tidad 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 q ue slo puede utilizarse para cargar un volcado de base de datos. Use esta opcin pa ra efectuar la recuperacin tras un fallo de medios, o para el traslado de una bas e de datos de una mquina a otra. Consulte la Gua de Administracin del Sistema para obtener informacin detallada. #endregion #region Omisin de bases de datos La supresin de una base de datos se lleva a cabo con el comando drop database . d rop database elimina la base de datos y su contenido de SQL Server, libera el es pacio de almacenamiento que se le haba asignado, y elimina las referencias a la m isma 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 e jemplo: drop database newpubs, newdb Una base de datos daada no puede suprimirse con drop database . Utilice el comand o dbcc dbrepair . #endregion #region 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 existen tes siempre se conservan. Si el espacio asignado a una base de datos es demasiad o reducido, el propietario de la base de datos puede aumentarlo con el comando a lter database . El permiso alter database corresponde predeterminadamente al pro pietario 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 e spacio. Esta instruccin aade 2 MB a newpubs en el dispositivo de bases de datos pr

edeterminado: alter database newpubs La sintaxis completa de alter database permite ampliar una base de datos en un nm ero especificado de megabytes (un mnimo de 1 MB) e indicar dnde debe aadirse el esp acio de almacenamiento: alter database database_name [on {default | database_device } [= si ze ] [, database_device [= size ]]...] [log on { default | data base_device } [ = size ] [ , database_device [= size ]]...] [with override] [for load] 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 data base 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 d e datos pubsdata , y en 3 MB en el dispositivo de bases de datos newdata , escri ba: 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 segmen tos existentes pueden ampliarse en el espacio aadido. El nmero mximo de segmentos p ara 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 correlaciona n 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 automticament e la correlacin de los segmentos system y default . Para obtener informacin sobre with override , consulte la Gua de Administracin del Sistema. #endregion #region 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 d e 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 i ntentar 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 e l siguiente: create table table_name ( column_name datatype ) 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 deli mitados. En caso contrario, deben ajustarse a las reglas para identificadores de l Captulo 1, "Introduccin". Los nombres de columna deben ser nicos dentro de una ta bla determinada, pero es posible utilizar el mismo nombre de columna en diferent es tablas de la misma base de datos. Debe haber un tipo de datos para cada columna. La palabra "char" despus del nombr e 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 expli can 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 algu nos 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 nom bres de tablas deben ser nicos para cada usuario. Se pueden crear tablas temporales precediendo el nombre de la tabla en una instr uccin 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 nom bres 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 . L as 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 calific ar sus nombres. Tambin puede usar los objetos creados por el propietario de la ba se de datos sin calificar sus nombres, siempre que tenga los permisos adecuados. Estas reglas se aplican a todos los usuarios, incluidos el administrador del si stema y el propietario de la base de datos. Si bien los nombres de tablas deben ser nicos para cada usuario, diferentes usuar ios pueden crear tablas con el mismo nombre. Por ejemplo, un usuario llamado "jo nah" 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 ].] table_name ( column_name datatyp e [default { constant_expression | user | null}] {[{identity | nu ll | not null}] | [[constraint constraint_name ] {{unique | pri mary key} [clustered | nonclustered] [with {fillfactor | ma x_rows_per_page} = x] [on segment_name ] | references [[ database .] owner .] ref_table [( ref_column )] | check ( search_condition )}]}... | [constraint constraint_name ] {{unique | primary key} [cl ustered | nonclustered] ( column_name [{, column_name }...]) [with {fillfactor | max_rows_per_page} = x] [on segment_name ] | foreign key ( column_name [{, column_name }...]) referenc es [[ database .] owner .] ref_table [( ref_column [{, r ef_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 proporci ona el nombre y el tipo de datos de la columna, especifica el modo en que cada c olumna manipula los valores nulos, e indica qu columna, si hubiera alguna, tiene la propiedad IDENTITY. create table tambin puede definir restricciones de integri dad a nivel de columna y a nivel de tabla. Cada definicin de tabla puede tener mlt iples 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 c har(12), pub_id char(4) null, price money null, advance money null, roya lty int null, total_sales int null, notes varchar(200) null, pubdate dateti me contract bit not null) En las secciones siguientes se describen varios componentes distintos de definic in de tabla: tipos de datos suministrados por el sistema, tipos de datos definido s 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 segm ento, solicite una lista de los segmentos que pueden utilizarse al administrador del sistema o propietario de la base de datos. Algunos segmentos pueden estar a signados a tablas o ndices especficos por razones de rendimiento, o por otras cons ideraciones. 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 s e 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 p alabra 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 introdu cir 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 c aracteres y no como el valor NULL. Si omite null o not null en la instruccin create table , SQL Server utiliza el mo do nulo definido para la base de datos (de forma predeterminada, NOT NULL). Para

compatibilidad con las normas SQL, utilice el procedimiento del sistema sp_dbop tion 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 un a entrada. Si no existe ninguna entrada para una columna NOT NULL, aparecer un me nsaje de error. Los valores predeterminados, es decir, los valores suministrados de forma automti ca cuando no se realiza ninguna entrada, pueden usarse con columnas NULL y NOT N ULL. Un valor predeterminado se considera una entrada. Sin embargo, no es posibl e designar un valor predeterminado NULL para una columna NOT NULL. Los valores n ulos pueden especificarse como valores predeterminados mediante la restriccin def ault de la instruccin create table , o mediante la instruccin create default . La restriccin default se describe ms adelante en este captulo; create default se descr ibe en el Captulo 12. Definir las columnas como NULL proporciona un marcador de lugar para los datos q ue todava se desconocen. Por ejemplo, en la tabla titles , las columnas price , a dvance , royalty y total_sales estn definidas para permitir valores NULL. Sin embargo, title_id y title no estn definidas para permitir valores NULL, ya qu e 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 simplement e 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 informa cin 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 almace nan nmeros secuenciales (como los nmeros de factura, de empleado o de registro) ge nerados de forma automtica por SQL Server. El valor de la columna IDENTITY identi fica 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 IDE NTITY no permiten valores nulos). Las columnas IDENTITY deben tener un tipo de d atos 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 a uto 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 colum nas IDENTITY. El tipo de datos definido por el usuario debe tener un tipo numeri c 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 conti nuacin se muestra un ejemplo de un tipo de datos definido por el usuario con la p ropiedad 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 l a 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 permit e valores nulos. Referencia a columnas IDENTITY con syb_identity Una vez definida la columna IDENTITY, no es necesario recordar el nombre de colu mna real. Se puede utilizar la palabra clave syb_identity, calificada por el nom bre de la tabla donde sea necesario, en operaciones de seleccin, actualizacin y el iminacin 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 q ue 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 t amao mximo de la tabla, depende del valor del parmetro de configuracin identity burn ing 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 e l 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 temporal es 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 o mita con drop table . Tablas a las que slo puede accederse durante la sesin actual de SQL Server. Las ta blas temporales no compartibles deben comenzar con un smbolo de nmero (#). Para cr ear una tabla temporal no compartible, especifique slo el nombre de la tabla en l a instruccin create table . Por ejemplo: create table #my_temptbl SQL Server garantiza que el nombre de la tabla temporal sea nico en la sesin actua l. El programa trunca los nombres de tabla temporal largos a 13 caracteres (incl uido el smbolo de nmero) y rellena los nombres cortos a 13 caracteres mediante car acteres 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 u tiliza 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 explc ita.

A continuacin se muestra una instruccin que crea una tabla temporal no compartible : create table #myjobs (task char(30), start datetime, stop datetime, not es 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. L a tabla y sus datos desaparecern al final de la sesin de trabajo actual. Las tablas temporales no son recuperables. Es posible asociar reglas, valores predeterminados e ndices a las tablas temporal es, 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 usu ario permanentemente, ejecute sp_addtype en model y despus reinicie SQL Server pa ra 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 d e 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 sob re ella. Si se usa pubs2 y hay otra base de datos llamada newpubs , se puede crear una ta bla 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 pred eterminados, procedimientos almacenados o disparadores) en una base de datos dis tinta de la actual. #endregion #region Definicin de restricciones de integridad para tablas Transact-SQL proporciona dos mtodos para mantener la integridad de los datos de u na 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. La s restricciones de integridad ofrecen la ventaja de definir los controles de int egridad en un paso durante el proceso de creacin de la tabla (segn definen las nor mas SQL) y de simplificar el proceso para crear dichos controles. Sin embargo, l as restricciones de integridad estn ms limitadas en alcance y son menos extensas q ue los valores predeterminados, reglas, ndices y disparadores. Por ejemplo, los disparadores proporcionan una manipulacin ms compleja de la integ

ridad de referencia que los declarados en create table . Asimismo, las restricci ones de referencia definidas por create table son especficas de dicha tabla. A di ferencia de las reglas o valores predeterminados, las restricciones no pueden vi ncularse a otras tablas y slo pueden omitirse o cambiarse mediante alter table . Las restricciones no pueden contener subconsultas ni funciones agregadas, ni siq uiera en la misma tabla. Los dos mtodos no son excluyentes entre s. Es posible utilizar restricciones de re ferencia junto con valores predeterminados, reglas, ndices y disparadores. Esto p roporciona 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 creat e 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 primar y key requiere que no haya valores nulos en ninguna fila de la columna. La integridad de referencia ( references ) exige que los datos insertados en col umnas especficas ya tengan datos coincidentes en la tabla y columnas especificada s. 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 nu los en una columna (las palabras clave null o not null ) y proporcionando valore s predeterminados para columnas (la clusula default ). Consulte la seccin ''Uso de valores nulos'', para obtener ms informacin sobre las palabras clave null y not n ull . Se pueden crear mensajes de error vinculados a restricciones. Genere mensajes co n sp_addmessage y vinclelos a las restricciones con sp_bindmsg. Para obtener ms in formacin, consulte sp_addmessage y sp_bindmsg en el Manual de Referencia de SQL S erver . Para obtener ms informacin sobre restricciones definidas para una tabla, utilice e l 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. L a 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 c omo restricciones a nivel de tabla. Por ejemplo, la siguiente instruccin create t able 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), c onstraint 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 un a columna como restricciones a nivel de columna. Por ejemplo, si la restriccin ch eck anterior slo utiliza una columna ( pub_id) , se puede poner la restriccin en e

sa 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 acom paa 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 es pecificar 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 instr uccin create table . Cuando un usuario no introduce ningn valor de columna, SQL Se rver 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 pr edeterminado 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 referenc ia 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 pred eterminado. Para utilizar este valor predeterminado, el tipo de datos de la colu mna debe ser char(30) o varchar(30) . null : indica que SQL Server debe insertar el valor nulo como valor predetermina do. No se puede definir este valor predeterminado en columnas que no permitan va lores nulos (utilizando la palabra clave not null ). Por ejemplo, esta instruccin create table define dos valores predeterminados de c olumna: create table my_titles (title_id char(6), title varchar(80) , price money default null, total_sales int defa ult 0) Slo puede incluirse una clusula default por columna de tabla. El uso de la clusula default para asignar valores predeterminados es ms sencillo q ue el mtodo de dos pasos de Transact-SQL. En Transact-SQL, es posible utilizar cr eate default para declarar el valor predeterminado y luego vincularlo a la colum na 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 c olumnas con restricciones primary key no pueden contener valores nulos. La restr iccin 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 d efine 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 colu mna. En Transact-SQL, es posible definir la columna para que admita valores nulo s con la restriccin unique , ya que el ndice nico usado para imponer la restriccin p ermite insertar valores nulos.

Note: No confunda las restricciones de integridad unique y primary key con la in formacin definida por los procedimientos del sistema sp_primarykey , sp_foreignke y y sp_commonkey . Las restricciones unique y primary key crean ndices para defin ir los atributos nicos o de clave primaria de las columnas de tablas. sp_primaryk ey , 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 colum nas 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 especificar se una restriccin unique clustered o primary key clustered . Las restricciones unique y primary key pueden emplearse para crear ndices nicos (i ncluidas las opciones with fillfactor , with max_rows_per_page y on segment_name ) al reforzar la integridad de datos. Sin embargo, los ndices proporcionan funci ones adicionales. Para obtener ms informacin sobre los ndices y sus opciones, inclu idas las diferencias entre los ndices agrupados y no agrupados, consulte el Captul o 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 c oincidentes en una tabla "referenciada". Una restriccin de integridad de referenc ia se satisface con cualquiera de las siguientes condiciones: Si una columna de la tabla de referencia incluida con la restriccin contiene un v alor nulo Si las columnas de la tabla de referencia incluidas con la restriccin coinciden c on 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 smal lint, constraint salesdet_constr foreign key (stor_id, ord_num) references my_sales (stor_id, ord_num)) La primera restriccin garantiza que cualquier fila insertada en my_salesdetail te nga 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 q ue los valores insertados para las columnas stor_id y ord_num de una fila coinci dan 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 referenc iada 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 col umna de la clusula references son opcionales slo si las columnas de la tabla refer enciada se designan como clave primaria a travs de una restriccin primary key . Cualquier columna referenciada que se especifique debe estar restringida por un n dice nico de dicha tabla. Dicho ndice nico puede crearse mediante la restriccin uniq ue 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 d atos de las columnas de la tabla referenciada. Por ejemplo: create table test_type (col1 char(4) not null references publishers(pub_i d), 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 pe rmisos, consulte la Gua del Usuario de las Caractersticas de Seguridad . Las restricciones de integridad de referencia proporcionan imponer la integridad de los datos cuando se comparan con ores. Sin embargo, los disparadores proporcionan funciones ner la integridad de referencia entre tablas. Para obtener paradores, consulte el Captulo 15. un modo ms sencillo de la creacin de disparad adicionales para impo ms informacin sobre dis

Especificacin de restricciones check Es posible declarar una restriccin check para limitar los valores que los usuario s pueden insertar en una columna de una tabla. Una restriccin check especifica un a condicin de bsqueda ( search_condition) que los valores deben cumplir antes de s u 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 incorpo radas. 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 determin ados 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 r eferencia 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 t able permite mltiples restricciones check en una definicin de columna. #endregion #region Diseo y creacin de tablas Esta seccin proporciona un ejemplo de una instruccin create table que se puede uti

lizar 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 predeterm inados 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 ell os durante algn tiempo antes de crear ndices, valores predeterminados, reglas, dis paradores o vistas. Esto ofrece la oportunidad de ver el tipo de transacciones q ue 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 cr ear la tabla y los objetos que la acompaan. Decida qu columnas necesita en la tabla, as como el tipo de datos, longitud, preci sin y escala de cada una. Cree los nuevos tipos de datos definidos por el usuario antes de establecer la t abla 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 lo s hubiera, es necesario aadir a las columnas de la tabla. Esto tambin implica deci dir cundo deben utilizarse las restricciones y valores predeterminados de columna en lugar de los valores predeterminados, reglas, ndices y disparadores para impo ner la integridad de los datos. Decida si necesita valores predeterminados y reglas y, en caso afirmativo, deter mine su ubicacin y tipo. Tenga en cuenta la relacin entre el estado NULL y NOT NUL L de una columna, as como los valores predeterminados y las reglas. Decida qu tipo de ndices necesita y su ubicacin. Los ndices se explican en el Captulo 11. Cree la tabla y sus ndices con los comandos create table y create index . Cree los nuevos valores predeterminados y reglas necesarios con los comandos cre ate default y create rule . Estos comandos se explican en el Captulo 12. Vincule los valores predeterminados y reglas necesarios con los procedimientos d el sistema sp_bindefault y sp_bindrule . Si hubiera algn valor predeterminado o r egla en un tipo de datos definido por el usuario utilizado en una instruccin crea te table , se activar de forma automtica. Estos procedimientos del sistema se expl ican en el Captulo 14. Cree disparadores con el comando create trigger . Los disparadores se explican e n el Captulo 15. 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 nd ices, valores predeterminados, reglas, disparadores, etc.. Dicha tabla puede con

tener 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 , consult e al administrador del sistema o propietario de la base de datos. La persona res ponsable deber cerciorarse de que, si otro usuario cre la tabla, sus ndices, valore s predeterminados, reglas y disparadores, la tabla haya sido omitida a fin de ev itar cualquier conflicto al crear los objetos. La siguiente tabla muestra la estructura propuesta de la tabla y los ndices, valo res 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 nm NOT NULL nmind (compuesto)

sname nm NOT NULL nmind (compuesto)

address varchar(30) NULL

city varchar(30) NOT NULL citydflt state char(2) NOT NULL statedflt zip char(5) NULL zipind zipdflt

ziprule phone p# NULL phonerule age tinyint NULL agerule bday datetime NOT NULL bdflt sex bit NOT NULL sexdflt debt money NOT NULL sexdflt notes varchar(255) NULL

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 d efinido 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 u n mximo de 30 bytes. El tipo de datos p # permite un tipo de datos char con un ta mao 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 nece sario especificar NOT NULL en la definicin de tabla, porque se trata del valor pr edeterminado. Este diseo de tabla especifica NOT NULL de forma explcita para facil itar la lectura. El valor predeterminado NOT NULL quiere decir que se precisa una entrada, por ej emplo, para las dos columnas de nombre de esta tabla. Los dems datos no tienen se ntido 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, cu ando no se proporciona ningn otro valor en la entrada, se introduce el valor pred eterminado, en lugar de NULL. Si se designa una columna NULL y se vincula con un a regla que no especifica NULL, cuando no se introduce ningn valor para la column a, la definicin de columna ignora la regla. Las columnas pueden tener valores pre determinados 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 friends_etc (pname nm not null, sname no not null, address varchar(30) null, city var char(30) not null, state char(2) not null, postalcode cha r(5) null, phone p# null, age tinyint null, bday datetime not null, sex bit not null, debt money not null, notes varchar(255) null Ahora hay columnas definidas para nombre y apellido, direccin, ciudad, estado, cdi go postal, nmero de telfono, edad, fecha de nacimiento, sexo, informacin sobre deud as y notas. En otros captulos se describe el modo de crear reglas, valores predet erminados, ndices, disparadores y vistas usados con la tabla. #endregion #region 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 tab la permanente, slo si la opcin de base de datos select into/bulkcopy est definida c omo on . El administrador del sistema puede activar esta opcin con el procedimien to 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 dbid created status --------- ------- ----- ----- ----------- ------------ pubs 2 MB sa 5 Jun 3 1988 select into /bulkcopy (1 row affected) device size usage ---------------- ---------------------- master 2 MB data and log (1 r ow 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 la s 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 instruc cin 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 operac in no registrada no es utilizable con load transaction . A diferencia de una vista que muestra parte de una tabla, una tabla creada con s elect into es una entidad diferente e independiente. Consulte el Captulo 9 para o btener 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 reg las 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 p ublishers . Dado que esta instruccin concreta no incluye ninguna clusula where , l os 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 insertada s en newtable . Este es el aspecto de newtable : select * from newtable pub_id pub_name ------ ------------------------------------ 0736 New A ge Books 0877 Binnet & Hardley 1389 Algodata Infosystems (3 rows a ffected) La tabla nueva contiene los resultados de la instruccin select y pasa a formar pa rte 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 p ara 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 con dicin falsa en la clusula where . Por ejemplo: select * into newtable2 from publishers where 1=2 (0 rows affected) select * from newtable2 pub_id pub_name city state ---------------------- ---------(0 rows affected) 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 d atos 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 psycholo gy 21,275.00 trad_cook 19,000.00 (6 rows affected)

Siempre debe proporcionarse un nombre de columna para cualquier columna de la ta bla de resultados de select into que resulte de una funcin agregada o de cualquie r otra expresin, como la realizacin de operaciones aritmticas ( amount*2 ), la conc atenacin ( lname + fname ) o el uso de funciones incorporadas de SQL Server ( low er(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 nom bre 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 unio n o combinacin. Adicin de una nueva columna IDENTITY con select into Para definir una nueva columna IDENTITY en una instruccin select into , hay que aa dir la definicin de columna antes de la clusula into . Observe que la definicin inc luye la precisin de la columna, pero no su escala: select column_list identity_column_name = identity( precision ) into table_name from table_name No es posible utilizar select into para crear una tabla nueva con mltiples column as 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 sob re columnas IDENTITY en el Manual de Referencia de SQL Server . #endregion #region Omisin de tablas El comando para quitar una tabla de una base de datos es drop table . Su sintaxi s 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 est ar vinculados, pero no son afectados. Es necesario ser el propietario de una tabla para poder omitirla. Sin embargo, n adie 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 e n 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 trunc ate table , la tabla continuar existiendo hasta que se omita (con drop ). El permiso drop table y truncate table no puede transferirse a otros usuarios. #endregion #region Alteracin de tablas existentes Si cambia de opinin sobre la estructura de una tabla despus de haberla utilizado d urante algn tiempo y decide que es necesario modificar la manera en que est defini da, tiene estas alternativas: Aadir columnas y restricciones, omitir restricciones o cambiar valores predetermi nados 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 existen tes: 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}] {[{identi ty | null}] | [[constraint constraint_name ] {{unique | primary key} [clustered | nonclustered] [with {fillfactor | max_r ows_per_page} = x] [on segment_name ] | references [[ dat abase .] owner .] ref_table [( ref_column )] | ch eck ( search_condition )}]}... {[, next_column ]}... | 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 }...]) refer ences [[ database .] owner .] ref_table [( ref_column [{, ref_column }...])] | check ( search_condition )} | drop constraint constraint_name | replace column_name default { constant_expression | user | null }} El nmero de columnas de una tabla no puede ser superior a 250, tanto si se aaden c on una instruccin alter table como si se definen con la instruccin create table or iginal. 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 IDEN TITY. 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 o mitir el procedimiento y volver a crearlo. Por ejemplo, se puede aadir una columna a la tabla friends_etc de la siguiente ma nera: 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 (coun try 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 determin ar los nombres de las restricciones definidas para una tabla, utilice el procedi miento almacenado del sistema sp_helpconstraint , descrito en "Uso de sp_helpcon straint en tablas". alter table tambin permite cambiar el valor predeterminado definido para una colu mna (o aadir un valor predeterminado de columna si no existe ninguno). Por ejempl o: alter table friends_etc replace country default "USA" Para obtener ms informacin sobre valores predeterminados de columna y restriccione s de integridad, consulte la seccin "Definicin de restricciones de integridad para tablas". Cambio de nombre de tablas y otros objetos Para cambiar el nombre de las tablas y otros objetos de base de datos (vistas, nd ices, reglas, valores predeterminados, procedimientos y disparadores), utilice e l 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 infor macin 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 sigu iente: sp_rename friends_etc, infotable Tambin puede utilizarse sp_rename para cambiar el nombre de otros objetos: column as, valores predeterminados, reglas, procedimientos, vistas, disparadores, restr icciones de verificacin, restricciones de integridad de referencia y tipos de dat os 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, u

se 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 dato s del sistema. El objeto cuyo nombre se est cambiando debe estar en la base de da tos actual. Slo el propietarios de los objetos puede cambiar los nombres de los m ismos. Sin embargo, el propietario de la base de datos puede cambiar el nombre d e 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 d e 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 r ecompilacin tiene lugar por diversas razones y sin notificacin al usuario, por eje mplo, 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 de jan de funcionar. El usuario debe cambiar su texto para reflejar el nombre de ob jeto nuevo. Adems, el nombre de objeto antiguo aparecer en los resultados de la co nsulta 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 de pendiente al ejecutar sp_rename . El procedimiento del sistema sp_depends propor ciona una lista de objetos dependientes. #endregion #region 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 usua rios, 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 Tener acceso a tablas, vistas y columnas Ejecutar procedimientos almacenados Algunos comandos pueden ser utilizados por cualquier usuario a cualquier hora, s in 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 revoc arse 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 usuari o concreto recibi un permiso con la opcin para conceder este permiso a otro usuari

o. El propietario de una base de datos no recibe permisos sobre objetos que son pro piedad de otros usuarios de forma automtica. Sin embargo, el propietario de la ba se de datos o el administrador del sistema pueden adoptar cualquier permiso asum iendo la identidad del propietario del objeto mediante el comando setuser y escr ibiendo la instruccin grant o revoke apropiada. Es posible asignar dos clases de permisos con grant y revoke : permisos de acces o a objetos y permisos de creacin de objetos . Los permisos de acceso a objetos controlan el uso de determinados comandos que p roporcionan 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 a uthors . Los permisos de acceso a objetos los concede y revoca el propietario de l objeto en cuestin. La siguiente instruccin concede a Mary y Joe permiso de acceso a objetos para rea lizar 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 obj etos y slo pueden ser concedidos por el administrador del sistema o el propietari o 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 C aractersticas de Seguridad . #endregion #region Obtencin de informacin sobre bases de datos y tablas SQL Server proporciona varios procedimientos almacenados del sistema para obtene r informacin sobre bases de datos, tablas y otros objetos de base de datos. En es ta 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 e l 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 ba se de datos especificado (es decir, cualquier objeto enumerado en sysobjects ), un tipo de datos especificado (enumerado en systypes ) o todos los objetos y tip os 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 : Name Owner Type ------------------------------------ -------- publisher dbo user table Data_located_on_segment When_created ------------------------------------------------ default Jan 1 1900 12:

00AM Column_name ----varchar ULL Nulls -------NULL

Type Length Prec Scale ----------- ------- ------ ----pub_id char 4 NULL NULL pub_name 40 NULL NULL city varchar 20 NULL N state char 2 NULL NULL Default_name Rule_name Identity ----------------- -------0 NULL NULL 0 1 NULL 0 1 NULL NULL 0 1 NULL NULL 0 index_name index_description index_keys ------------- ------------------------------------ ---------- pubind clustered, uni que located on default pub_id (1 row affected) keytype object related_object object_keys related_keys ------- --------- -------------- ----------------------------- -------------------------- p rimary publishers -- none -pub_id, *, *, *, *, *, *, * *, *, *, *, *, * , *, * foreign titles publishers pub_id, *, *, *, *, *, *, * pub_id, *, *, *, *, *, *, * (return status = 0) Si ejecuta sp_help sin suministrar un nombre de objeto, el informe resultante mu estra 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 sy stypes y su nombre, tipo de almacenamiento y longitud, si se admiten valores nul os, y los nombres de los valores predeterminados o reglas vinculados a l. El info rme indica, adems, si se han definido columnas de claves primarias o externas par a una tabla o vista con los procedimientos del sistema sp_primarykey o sp_foreig nkey . 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 a lter table . Sin embargo, no ofrece informacin sobre las restricciones de integri dad 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 d atos especificada, o sobre todas las bases de datos de SQL Server. sp_helpdb mue stra 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 ] A continuacin se muestra cmo obtener un informe sobre pubs2 : sp_helpdb pubs2 name db_size owner dbid created status ----- ------- ----- ---- --------------- ------------- pubs2 2 MB sa 4 Jan 10 19 88 no se ha establecido ninguna opcin (1 row affected) device size usage ----------------- ----------- ------------- pubsdev 2 MB data + log (1 row affected) Uso de sp_helpconstraint en tablas El procedimiento del sistema sp_helpconstraint proporciona informacin sobre cualq uier 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 sin taxis 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 mens ajes 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 defn ----------------------- -------------------------------------- states_popula_1088006907 CHECK (population > 1000000) stat econstr 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 procedimient o 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 d e filas y pginas de datos utilizadas por una tabla o un ndice agrupado o no agrupa do. 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 r esumen del espacio utilizado por todos los objetos de base de datos. #endregion #endregion #region ADICIN, MODIFICACIN Y ELIMINACIN DE DATOS #region Opciones disponibles para la modificacin de datos El comando insert permite aadir nuevas filas a la base de datos. El comando updat e permite cambiar las filas existentes en la base de datos. El comando delete pe rmite eliminar filas de la base de datos. El comando writetext permite aadir y mo dificar datos de tipo text e image sin escribir cambios largos en el diario de t ransacciones del sistema. Estas operaciones se denominan colectivamente instrucciones de modificacin de dat os . 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 transferirl os 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 pu eden basarse en los datos de otras tablas, e incluso de otras bases de datos. Es ta 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: limitac in del acceso a datos", para obtener ms detalles al respecto.

Permisos Los comandos de modificacin de datos no estn necesariamente a disposicin de todos l os usuarios. El propietario de la base de datos y los propietarios de los objeto s de base de datos usan los comandos grant y revoke para decidir quines tendrn acc eso 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 Segur idad . Integridad de referencia insert , update , delete , writetext y truncate table permiten modificar los dat os de la base de datos. Sin embargo, si modifica los datos de una tabla sin alte rar 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 colu mna 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 co lumna au_id . El problema general de mantener la consistencia de las modificaciones de datos e n todas las tablas de una base de datos se denomina integridad de referencia. Un a forma de solucionar este problema es crear procedimientos especiales, llamados disparadores, que se activan automticamente al ejecutar los comandos insert , up date y delete en tablas o columnas concretas (el comando truncate table no es at rapado por los disparadores). Otra posibilidad es definir restricciones de integ ridad de referencia para la tabla. Los disparadores se tratan en el Captulo 15, " Disparadores: imposicin de la integridad de referencia" y las restricciones de in tegridad 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 d e writetext . Esto significa que si comienza una transaccin ejecutando el 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 pro cedimientos remotos (RPC) no se pueden revertir. El modo de funcionamiento predeterminado de writetext no registra las transaccio nes. Esto evita que el diario de transacciones se llene con los largusimos bloque s de datos que pueden contener los campos text e image . Para registrar los camb ios realizados con este comando, utilice la opcin with log del comando writetext . En el Captulo 17, "Transacciones: mantenimiento de la consistencia y recuperacin d e 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 pub s2 . Si comienza con una copia limpia de la base de datos pubs2 , puede evitar que lo s cambios realizados sean permanentes incluyendo todas las instrucciones en una transaccin y abortando la transaccin una vez que termine con este captulo. Inicie l

a transaccin escribiendo lo siguiente: begin tran modify_pubs2 Esta transaccin se llama modify_pubs2 . Se puede cancelar la transaccin en cualqui er momento y restaurar la base de datos a la situacin original, escribiendo: rollback tran modify_pubs2 #endregion #region 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, "Crea cin 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 entr e comillas simples o dobles al ser introducidos y cuando se buscan. Utilice comi llas simples si la opcin quoted_identifier est definida como on (activada). Si emp lea comillas dobles, SQL Server tratar el texto como un identificador. Consulte e l 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_rt runcation para recibir un mensaje de aviso cuando esto ocurra. Hay dos formas de especificar comillas literales dentro de una entrada de caract eres. 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 part e de la entrada, emplee dos comillas simples seguidas: 'I don' 't understand'. C on 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 v iceversa. 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, "Consulta s: seleccin de datos de una tabla", pueden utilizarse para buscar datos de tipo c haracter , text y datetime . Consulte la seccin sobre tipos de datos en el Manual de Referencia SQL Server par a obtener informacin sobre los espacios en blanco finales en los datos character . 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 f ormatos de entrada. Los formatos de visualizacin y de entrada se controlan por se parado. El formato de visualizacin predeterminado proporciona una salida que tien e el siguiente aspecto: "Apr 15 1987 10:23PM". El comando convert proporciona va rias opciones para mostrar los segundos y milisegundos y presentar la fecha con ordenaciones distintas de sus componentes. Consulte el Captulo 10, "Uso de funcio nes 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 fec has. Las maysculas y minsculas siempre se ignoran y los espacios pueden tener cual quier ubicacin entre los componentes de la fecha. Cuando introduzca valores de ti po datetime y smalldatetime , inclyalos siempre entre comillas simples o dobles ( use comillas simples si la opcin quoted_identifier est activada; si emplea comilla s 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 l as dos partes. SQL Server proporciona valores predeterminados, descritos tambin a continuacin. Si se omiten las dos partes, la fecha predeterminada es el 1 de ene ro 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 (Jan uary 1, 1753) y la ltima el 31 de diciembre de 9999 (December 31, 9999). Para sma lldatetime , la fecha ms antigua que puede usarse es el 1 de enero de 1900 y la lt ima 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 Serve r rechaza todos los valores que no puede reconocer como fechas comprendidas en l os 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 co mo una hora, debe contener un signo de dos puntos (:) o el calificador AM/PM. Ob serve que smalldatetime slo precisa hasta los minutos. Los milisegundos pueden ir precedidos de un signo de dos puntos o de un punto. S i van precedidos de dos puntos, el nmero expresar milsimas de segundo y, si van pre cedidos 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, se gn 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 u tilice y puede estar precedido o seguido de una especificacin horaria, segn lo des crito anteriormente. El mes se introduce en formato alfanumrico. El mes puede ser una abreviatura de 3 caracteres o el nombre completo del mes, d e 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 interp retan como "20yy" ("20aa"), mientras que el 50 y los valores mayores que 50 se i nterpretan 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 (consu lte 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 (.). Se debe especificar el mes, da y ao. Las cadenas deben tener el siguiente formato: <num> <sep> <num> <sep> <num> [ <t ime spec> ] o bien: [ <time spec> ] <num> <sep> <num> <sep> <num> La interpretacin de los valores que componen las fechas depende del parmetro de da teformat . 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 e jemplo, "12/10/08" podra interpretarse como seis fechas distintas, dependiendo de l parmetro de dateformat . Consulte el comando set para obtener ms informacin al re specto. Para introducir "15 de abril de 1988" (April 15, 1988) en el orden mdy de datefo rmat , 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 sepa radores, aunque tambin pueden emplearse guiones o puntos: 15/[0]4/[19]88 (dmy) [19]88/[0]4/15 (ymd) [19]88/15/[0]4 (ydm) [0]4/[19]88/15 (myd) 15/[19]88/[0]4 (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. El parmetro de dateformat siempre se ignora con este formato de entrada. 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. Las cadenas de 6 y 8 dgitos siempre se interpretan como ymd; el mes y el da siempr e deben tener 2 dgitos. El siguiente formato se reconoce: [19]880415 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 ti po datetime y smalldatetime , as como con char , nchar, varchar , nvarchar y text . Cuando se usa like con valores datetime o smalldatetime , SQL Server conviert e las fechas al formato estndar de datetime y luego a varchar . Puesto que el for mato de visualizacin estndar no incluye segundos ni milisegundos, stos no pueden bu scarse con like y un patrn de coincidencia. Utilice la funcin de conversin de tipo , convert , para buscar los segundos y milisegundos. Es conveniente usar like para buscar valores datetime o smalldatetime , dado que las entradas de estos tipos de datos pueden contener diversos componentes de fe cha. 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 entr e 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" encontra r todas las fechas entre el 20 y el 29 de mayo, pero no el 2 de mayo. No es neces ario 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 co mparacin con like . binary , varbinary e image Cuando se introducen o buscan datos binary , varbinary o image , stos deben ir pr ecedidos 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 pre cedido 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 c omo un valor money o smallmoney . Los valores money y smallmoney pueden introducirse precedidos o no de un smbolo m onetario, 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 disponi

bles con datos money . float, real y double precision Los tipos de datos numricos aproximados, float , real y double precision , se int roducen como una mantisa seguida por un exponente opcional. La mantisa puede inc luir 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 dato s float , real y double precision : Tabla 8-1: Evaluacin de datos numricos Datos introducidos Mantisa Exponente Valor 10E2 10 2 10 * 102 15.3e1 15.3 1 15.3 * 101 -2.e5 -2 5 -2 * 105 2.2e-1 2,2 -1 2.2 * 10-1 +56E+2 56 2 56 * 102

La precisin binaria de la columna determina el nmero mximo de dgitos binarios permit idos en la mantisa. Para las columnas float, puede especificar una precisin de ha sta 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 cal e ) decimales de la columna, que se definen mediante la siguiente sintaxis: datatype [( SQL Server trata to. Por ejemplo, . La precisin y precision [, scale ])] cada combinacin de precisin y escala como un tipo de datos concre numeric (10,0) y numeric (5,0) son dos tipos de datos distintos la escala determinan los lmites de los valores que pueden almacena

rse 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 p redeterminada de 18 dgitos. La escala especifica el nmero mximo de dgitos que pueden almacenarse a la derecha d el punto decimal y debe ser menor o igual a la precisin. Puede especificar una es cala 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 i ndicador 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 numeric (5,3) 5 3 12.345 -1234.567 dec (8,4) 8 4 -1234.567

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

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 n ulo explcito, tecleando "NULL" en la columna, o usar un valor nulo implcito, propo rcionando una lista de columnas que se salte la columna timestamp . SQL Server a ctualiza el valor timestamp automticamente tras cada insercin o actualizacin. Consu lte "Insercin de datos en columnas especficas" para obtener ms informacin. #endregion #region Adicin de datos nuevos Se puede utilizar el comando insert para aadir filas a la base de datos de dos fo rmas: con la palabra clave values o con una instruccin select . La palabra clave values se utiliza para especificar valores en algunas o todas l as columnas de una fila nueva. Este es un ejemplo simplificado de la sintaxis de l 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 obtene r valores de una o varias tablas. Este es un ejemplo simplificado de la sintaxis del comando insert usando una instruccin select : insert table_name select column_list from table_list e search_conditions Sintaxis de insert A continuacin se muestra la sintaxis completa del comando insert : wher

insert [into] [ database .[ owner .]]{ table_name | view_name } [( c olumn_list )] {values ( constant_expression [, constant_expression ]... ) | select_statement } Note: Cuando se aaden valores text e image con insert , todos los datos se escrib en en el diario de transacciones. El comando writetext permite aadir estos valore s sin registrar los grandes bloques de datos que pueden conformar los valores te xt 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 nombr es de columna de la instruccin create table original, es decir, primero el nmero d e ID, despus el nombre, la ciudad y, finalmente, el estado. Los datos de values s e colocan entre parntesis y todos los datos de caracteres van entre comillas simp les 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, especific ando estas columnas y los datos que les correspondan. Todas las columnas excluid as de la lista de columnas deben definirse para permitir valores nulos. Las colu mnas excluidas tambin aceptan valores predeterminados. Si se salta una columna co n un valor predeterminado vinculado a ella, se emplea dicho valor. Esta forma del comando puede ser especialmente til para insertar todos los valore s 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 val ores. 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 p ublishers 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. La siguiente instruccin select muestra la fila que se ha aadido a publishers : select * from publishers where pub_name = 'The Health Center' pub_id pub_name city state ------- --------------------- ------- 1756 The Health Center 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 permi te 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 IDENTI TY 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 gener ado 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 d e estas cuatro situaciones en las columnas sin valores: Se introduce un valor predeterminado, si existe, en la columna o en el tipo de d atos definido por el usuario. Consulte el Captulo 12, "Definicin de valores predet erminados y reglas para datos", o la entrada create default del Manual de Refere ncia de SQL Server para obtener informacin detallada. Se introduce NULL si se especific el valor nulo al crear la tabla y no existe nin gn valor predeterminado para la columna o el tipo de datos. Consulte tambin la ent rada 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 valo r 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 Nula IDENTITY S El valor predeterminado El valor predeterminado Siguiente valor secuencial No Mensaje de error NULL 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 enumer ado en la tabla del sistema sysobjects . Para ver la definicin de un valor predet erminado, utilice el procedimiento del sistema sp_helptext . Insercin explcita de datos en una columna IDENTITY En ocasiones, desear introducir un valor especfico en una columna IDENTITY, en lug ar de aceptar el valor generado por el servidor. Por ejemplo, puede que quiera a signar el valor 101, en lugar del 1, a la columna IDENTITY de la primera fila in sertada 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 administr ador del sistema pueden insertar un valor de forma explcita en una columna IDENTI TY. 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, p ara las que se ha especificado un valor. Cuando la opcin identity_insert est activ ada, todas las instrucciones insert ejecutadas para la tabla deben incluir una l ista explcita de columnas. La lista de valores deber incluir un valor para la colu mna IDENTITY, puesto que esta columna no admite valores nulos. Note: SQL Server no impone la exclusividad del valor insertado. Se puede especif icar cualquier nmero entero positivo que est dentro del margen admitido por la pre cisin declarada de la columna. Para asegurarse de que slo se aceptan valores de co lumna 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 definid o por el usuario. Las reglas rigen los tipos de datos que pueden aadirse. Un ejemplo de da pub_idrule inculada a la , o cualquier de introducir ello es la columna pub_id de la tabla publishers . Una regla llama , que especifica los nmeros de identificacin de editores vlidos, est v columna. Las IDs vlidas son "1389", "0736", "0877", "1622" y "1756" nmero de cuatro dgitos cuyos primeros dos dgitos sean "99". Si trata 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", "07 36", "0877", "1622", "1756") or @pub_id like "99[0-9][0-9]" (1 row affecte d) 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 alg una de las columnas definidas en la tabla tiene una regla. En el Captulo 12, "Def inicin de valores predeterminados y reglas para datos", se describen las reglas c on mayor detalle. Adicin de filas nuevas con select Para insertar valores en una tabla procedentes de una o ms tablas diferentes, inc luya una clusula select en la instruccin insert . La clusula select permite inserta r valores en algunas o todas las columnas de una fila. La insercin de valores en algunas columnas solamente puede ser til si se desea tom ar valores de una tabla existente. Despus, puede usar update para aadir los valore s de las dems columnas. Antes de insertar valores en algunas columnas de una tabla, asegrese de que exist a 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 estructu ras compatibles, es decir, las columnas coincidentes deben tener el mismo tipo d e 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 respecti vas, no es necesario especificar los nombres de las columnas en ninguna de las t ablas. Suponga que existe una tabla newauthors que contiene algunas filas de inf ormacin 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 necesa rio que las columnas de ambas estn enumeradas en el mismo orden en sus respectiva s 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 n ewauthors 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 newauthor s Si la secuencia de columnas de las dos tablas no coincide, SQL Server no puede c ompletar la operacin insert o la completa de forma incorrecta, colocando datos en columnas equivocadas. Por ejemplo, podran aparecer datos de direcciones en la co lumna au_lname de nombres. Columnas calculadas

Se puede usar columnas calculadas en una instruccin select dentro de una instrucc in 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 pr ice deben multiplicarse por dos. Una instruccin que permite incrementar los preci os e insertar las filas tmp en titles tendra el siguiente aspecto: insert titles select title_id, title, type, pub_id, price*2, advance, to tal_sales, notes, pubdate, contract from tmp Al realizar clculos en una columna, no es posible usar la sintaxis select * . Cad a 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 f ila, exactamente igual que con la clusula values . Simplemente, especifique las c olumnas 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 extr aer 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) Sin embargo, esta instruccin no es legal, ya que se requiere un valor para la col umna title_id . No se permiten valores nulos y tampoco se ha especificado un val or predeterminado. Puede introducir el valor ficticio "xx1111 " para titles_id e mpleando 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 col umna 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 l os 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 pub_name city state ------- -------------------- ------------ 0736 New Age Books Boston MA 0877 Binnet & Hardley Washington DC 1389 Algodata Infosystems Berkeley CA 9999 test Boston MA (4 rows affected) El ejemplo inserta las dos constantes ("9999" y "test") y los valores de las col umnas city y state en la fila que se ajusta a la consulta. #endregion #region 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 d

atos, 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 ejemp lo, si afecta a la columna IDENTITY de la tabla, o si alguno de los valores aadid os no es del tipo de datos correcto o viola una regla definida para una de las c olumnas 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 actualiz aciones realizadas con una misma instruccin no se acumulan. Es decir, si una inst ruccin 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 resultado s son imprevisibles, puesto que dependen del orden de procesamiento. Consulte el Captulo 9, "Vistas: limitacin del acceso a datos", para obtener inform acin 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". Sintaxis de update Esta es una versin simplificada de la sintaxis de update para actualizar filas es pecificadas con una expresin: update table_name set column_name = expression where search_c onditions Por ejemplo, si Reginald Blotchet-Halls decide cambiar su nombre por el de Goodb ody Health para potenciar su proceso de visualizacin, la manera de modificar su f ila en la tabla authors es la siguiente: update authors set au_lname = "Health", au_fname = "Goodbody" where au_lnam e = "Blotchet-Halls" Esta instruccin de sintaxis simplificada actualiza una tabla basada en datos de o tra tabla: update table_name set column_name = expression from table_n ame where search_conditions El siguiente ejemplo actualiza la columna total_sales de la tabla titles para re flejar las ventas ms recientes registradas en la tabla salesdetail : update titles set total_sales = total_sales + qty from titles, sales, sales detail 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 u n 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_na me1 = { 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 clu sula 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 volv er 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 Tambin es posible utilizar valores de columnas calculadas en una actualizacin. Par a 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 fila s de la tabla. Uso de la clusula where con update La clusula where especifica qu filas deben actualizarse. Por ejemplo, en el caso p oco probable de que se cambiara el nombre de California del norte por el de Paci fica (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 ac tualizar 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 = "C A" 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 es ta actualizando. Por ejemplo, anteriormente en este captulo se di un ejemplo que insertaba nuevas f ilas para autores sin ttulos en la tabla titleauthor , rellenando la columna au_i d y colocando valores ficticios o nulos en las dems. Si uno de estos autores, Dir k 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, a uthors 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_i ds 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 u na 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 inst ruccin 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.

#endregion #region Modificacin de datos text e image El comando writetext se usa para modificar valores text o image cuando no se des ea almacenar los largos valores de texto en el diario de transacciones de la bas e de datos. Los comandos update , que tambin pueden emplearse para columnas text o image , siempre se registran. En el modo predeterminado, los comandos writetex t no se registran. Note: Para emplear writetext en su estado predeterminado y no registrado, el adm inistrador del sistema debe usar sp_dboption para activar select into/bulkcopy . Esto permite la insercin de datos no registrados. Despus de usar writetext , es n ecesario 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 . 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 upd ate 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 ejemp lo de writetext aade un texto a una fila existente de la tabla blurbs : declare @val varbinary(16) select @val = textptr(copy) from blurbs where a u_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, write text coloca la cadena de texto nueva en la fila a la que apunta @ val . #endregion #region 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 o curre con las dems instrucciones de modificacin de datos, es posible eliminar fila s basadas en los datos de otras tablas. Por ejemplo, si decide eliminar una fila de publishers (la fila aadida para Jardi n, Inc.), escriba: delete publishers where pub_name = "Jardin, Inc." Sintaxis de delete Esta es una versin simplificada de la sintaxis de delete : delete table_name where 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 basndo se 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. Uso de la clusula from con delete La clusula from en la segunda posicin de una instruccin delete es una funcin especia l de Transact-SQL que permite seleccionar datos de una o varias tablas y elimina r los datos correspondientes de la tabla indicada en primer lugar. Las filas sel eccionadas 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 inmediat amente y, sin embargo, no se conocen los ttulos ni los nmeros de identificacin corr espondientes a esos autores. La nica informacin que se dispone son sus nombres y d irecciones. Se pueden borrar las filas de titles buscando los nmeros de identificacin de los a utores cuyas filas tienen Big Bad Bay City como ciudad en la tabla authors y usa ndo 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 p ara 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 emb argo, slo se eliminan las filas de la tabla titles que cumplen con las condicione s 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 = tit leauthor.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 #endregion #region 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 desasign acin de pginas de datos completas. truncate table libera inmediatamente todo el es pacio ocupado por los datos e ndices de la tabla. El espacio liberado lo puede us ar entonces cualquier objeto. Las pginas de distribucin de todos los ndices tambin q uedan 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 perman ece 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 , corre sponde 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 obte ner detalles sobre los disparadores. #endregion #endregion #region VISTAS: LIMITACIN DEL ACCESO A DATOS #region 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 fsicamen te en la base de datos. Las tablas que originan la vista se denominan tablas bas e 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 est a definicin almacenada. Los datos que se ven se almacenan en las tablas subyacent es. 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 ot ra tabla. Transact-SQL fue modificado para que no haya ninguna restriccin en las consultas mediante vistas, y menos restricciones de las normales en la modificac in 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 dato s de las tablas subyacentes se reflejan automticamente en las vistas que se deriv an de ellas. Ventajas de las vistas Los ejemplos de este captulo demuestran que las vistas pueden utilizarse para cen trar, simplificar y personalizar la percepcin que cada usuario tiene de la base d e datos. Las vistas tambin proporcionan una medida de seguridad de fcil manejo. Ad ems, pueden ser tiles cuando los cambios se realizan en la estructura de la base d e 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 inte resa 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 fue ra de la vista. Simplificacin de la manipulacin de datos Las vistas no slo simplifican la percepcin que los usuarios tienen de los datos, s ino tambin su forma de manipularlos. Las combinaciones, proyecciones y seleccione s usadas con frecuencia pueden definirse como vistas para evitar que los usuario s tengan que especificar todas las condiciones y calificaciones cada vez que rea licen una operacin adicional con dichos datos. Personalizacin Gracias a las vistas, distintos usuarios pueden ver los mismos datos de formas d iferentes, 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 p ueden 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 p uede limitarse a objetos de base de datos especificados, incluidas las vistas. S i 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 Administra cin de Seguridad para obtener informacin detallada sobre los comandos grant y revo ke . Mediante la definicin de vistas diferentes y la concesin selectiva de permisos par a 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 co n 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 q ue 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 dec ir, un subconjunto independiente del valor. Por ejemplo, se puede definir una vi sta que contenga todas las filas de la tabla titles , pero que omita las columna s 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 ta bla 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 inf ormacin 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 vist

as y tablas base. Por ejemplo, mediante la vista hiprice_computer , el usuario p uede 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 pro pietario 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 da tos. 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 situac in: el propietario de la base de datos ha concedido el permiso create view a " ha rold " y un usuario llamado " maude " ha concedido a " harold " el permiso para usar select desde una tabla propiedad de " maude " . Dados estos permisos, " har old " puede crear una vista que seleccione todas las columnas y filas de la tabl a de " maude ". Si "maude" despus revoca el permiso de " harold " para usar selec t desde su tabla, " harold " todava podr ver los datos de " maude " a travs de la v ista que l ha creado. Independencia lgica de datos Las vistas ayudan a proteger a los usuarios de los cambios realizados en la estr uctura 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 : titletext (title_id, title, type, notes) titlenumbers (title_id, pub_id, p rice, 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 ba se de datos de los usuarios, puede crear una vista que sea la combinacin de las d os tablas nuevas. Incluso le puede asignar el nombre titles . Cualquier consulta o procedimiento almacenado que antes haca referencia a la tabl a base titles ahora har referencia a la vista titles . En lo que respecta a los u suarios, las operaciones select siguen funcionando exactamente igual que antes. Los usuarios que slo realizan la recuperacin a partir de la vista nueva ni siquier a necesitan saber que se ha producido una reestructuracin. Desafortunadamente, las vistas slo proporcionan independencia lgica parcial. Algun as 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 e st interesado en los libros con un precio superior a $15 y para los que se ha pag ado un anticipo de ms de $5000. Esta sencilla instruccin select hallara las filas q ue cumplen las condiciones: select * from titles where price > $15 and advance > $5000 Ahora supongamos que tiene que realizar muchas operaciones de recuperacin y actua lizacin en este conjunto de datos. Lgicamente, podra combinar las condiciones mostr adas en la consulta anterior con cualquier comando que ejecute. Sin embargo, par a 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 adv ance > $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 he cho la definicin de la vista hiprice , en la tabla del sistema syscomments . Tamb in 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 tod os 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 > $50 00 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 lo s precios de las filas que cumplen las condiciones de las columnas price y advan ce , proporcionadas en la definicin de vista, y las de la instruccin de actualizac in. Al emitir la primera instruccin de actualizacin, es decir, la de hiprice , es posi ble ver su efecto en la vista o en la tabla titles . A la inversa, si hubiera cr eado la vista y luego hubiera ejecutado la segunda instruccin de actualizacin, que opera directamente en la tabla base, los precios cambiados tambin se hubieran vi sualizado mediante la vista. La actualizacin de una tabla subyacente de una vista de modo que las diferentes f ilas 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 vis ta, se considera parte de la vista. Sin embargo, si altera la estructura de la tabla subyacente de e la adicin de columnas, las columnas nuevas no aparecern en n una clusula select * a menos que la vista se omita y vuelva e debe a que la abreviatura mediante asterisco se interpreta y sta se crea por primera vez. #endregion #region 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 identifica dor delimitado para la vista. En caso contrario, el nombre de la vista debe ajus tarse 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. N o es posible asociar reglas, valores predeterminados ni disparadores a las vista s, ni tampoco crear ndices en ellas. No es posible crear vistas temporales, ni ta mpoco generarse vistas en tablas temporales. Sintaxis de create view A continuacin se muestra la sintaxis completa para la creacin de una vista: una vista mediant una vista definida co a definirse. Esto s ampla cuando la vi

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 vist a. 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 l a 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 cla ve 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 algun a de las siguientes condiciones, los nombres de columna deben especificarse en l a 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 sue le 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 column a de la que se deriva. Tambin puede cambiar el nombre de las columnas en la instr uccin select . Se cambie o no el nombre de una columna de vista, sta hereda el tip o 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 ca mbiando el nombre de las columnas en la instruccin select : create view pub_view2 as select Publisher = pub_name, city, state from publ ishers Los ejemplos de instrucciones de definicin de vista proporcionados en una seccin p osterior 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 clav e distinct y la clusula with check option de las definiciones de vista. El comand o drop view se explica despus. Uso de la instruccin select con create view La instruccin select de la instruccin create view define la vista. Es necesario te ner el permiso select para seleccionar cualquier objeto referenciado en la instr uccin select de una vista que se est creando. Una vista no tiene que ser necesariamente un simple subconjunto de filas y colum nas de una tabla concreta, como en el ejemplo. Es posible crear una vista a part ir 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 sub conjunto 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 v ista titles_view heredar los nombres de columna que aparecen en la lista de selec cin. Definicin de vista con una columna calculada A continuacin se muestra una instruccin de definicin de vista que crea una vista co n una columna calculada generada a partir de las columnas price , royalty y tota l_sales : create view accounts (title, advance, amt_due) as select titles.title_id, adv ance, (price * royalty /100 ) * total_sales from titles, roysched where pric e > $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_d ue . 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 fun ciones agregadas y la clusula group by . La extensin Transact-SQL que no limita la s 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" En el caso anterior, posiblemente se esperaba que la vista limitase sus resultad os a las categoras de "negocios", pero los resultados tienen informacin sobre otra s categoras. Para obtener ms informacin sobre group by y esta extensin Transact-SQL 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 mues tra un ejemplo de una vista derivada de las tablas authors y publishers . La vis ta contiene los nombres y ciudades de los autores que viven en la misma ciudad q ue un editor, junto con el nombre y la ciudad de cada editor. create view cities (authorname, acity, publishername, pcity) as select au_lna me, authors.city, pub_name, publishers.city from authors, publishers where a uthors.city = publishers.city

Vistas derivadas de otras vistas Se puede definir una vista en relacin con otra vista, como en el siguiente ejempl o: create view hiprice_computer as select title, price from hiprice where ty pe = '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 coinc iden de forma exacta con los valores de las mismas columnas contenidos en otra f ila. Dos valores nulos se consideran idnticos. SQL Server aplica el requisito distinct a la definicin de vista cuando accede a l a vista por primera vez y antes de realizar cualquier proyeccin o seleccin. Las vi stas tienen el mismo aspecto y comportamiento que cualquier tabla de base de dat os. Si selecciona una proyeccin de la vista distinct (es decir, si selecciona alg unas de las columnas de la vista, pero todas sus filas), puede obtener resultado s que parezcan duplicados. Sin embargo, cada fila de la vista en s contina siendo n ica. Por ejemplo, supongamos que usted crea una vista distinct , myview , con tr es columnas, a, b y c , que contiene estos valores: Tabla 9-1: Valores de muestra de la vista distinct myview a b c 1 1 2 1 2 3 1 1 0

Cuando introduce esta consulta: select a, b from myview el resultado tiene el siguiente aspecto: a b --- --- 1 1 1 2 1 1 La primera y tercera fila parece que estn duplicadas. Sin embargo, las filas de l a vista subyacente siguen siendo nicas. 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 i nstruccin 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 selecc in de la vista. Cuando lizada as las es por se crea una vista con with check option, cada operacin insert y update rea mediante la vista se valida segn los criterios de seleccin de la vista. Tod filas insertadas o actualizadas mediante la vista deben permanecer visibl medio de sta, o la instruccin no se ejecuta correctamente. , creada con with ch ubicadas en Californ cualquier otro estad stores cuya column

A continuacin se muestra un ejemplo de una vista, stores_cal eck option . Esta vista incluye informacin sobre las tiendas ia, pero excluye la informacin sobre las tiendas ubicadas en o. La vista se crea seleccionando todas las filas de la tabla a 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 instruc cin 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 instru ccin 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 vist a. 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 vi sta "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 fi las 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 i ncluye informacin sobre tiendas de California con condiciones de pago "Net 30": 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 a ctualizadas 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 di stinto de "Net 30" mediante stores_cal30 . La siguiente instruccin update se ejec utara 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. S e 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 resul tados pueden ser distintos de los previstos. La calificacin de la consulta no res tringe el nmero de filas devueltas, pero afecta a las filas que contienen el valo r NULL. Para las filas que no cumplen la calificacin, aparece un valor NULL en la s columnas de la tabla interna de dichas filas. Esto es resultado del hecho de q ue en Transact-SQL la representacin interna de una consulta en una vista es una c ombinacin 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 a c

----- ----1 10 Combina y califica en c 2 NULL Combina, pero no cumple las calificaciones 3 NULL (3 rows affected) No combina

La calificacin (c = 10) no afecta al nmero de filas devueltas. Sin embargo, NULL a parece en la columna de la tabla interna para cada fila que no cumple la calific acin o no se combina con filas de la tabla externa. #endregion #region 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 con texto de la instruccin. Si las verificaciones son satisfactorias, SQL Server comb ina la instruccin con la definicin almacenada de la vista y la convierte en una co nsulta 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 captul o y una consulta contra ella: create view hiprice ce > $5000 select title, type De forma interna, SQL virtiendo la consulta as select * from titles where price > $15 and advan

from hiprice where type = 'popular_comp' Server combina la consulta de hiprice con su definicin, con en:

select title, type from titles where price > $15 and advance > $5000 an d 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 , subconsult as 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. Consult e 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 co lumna sensitivity de una vista. Resolucin de vistas Cuando se define una vista, SQL Server comprueba si todas las tablas o vistas es pecificadas 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 in struccin, las cosas pueden cambiar. Por ejemplo, una o ms tablas o vistas indicada

s en la clusula from de la definicin de vista pueden haberse omitido. O, tambin, un a 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 mod ificacin 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 A diferencia de muchos otros sistemas de administracin de bases de datos, SQL Ser ver permite redefinir una vista sin necesidad de redefinir otras vistas que depe nden 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 sa tisfactoria 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 vi ew1 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 ke "94%" v iew2 : create view view2 as select au_lname, phone from view1 [M-Z]%" view3 : where postalcode li

where au_lname like "

create view view3 as select au_lname, phone from view2 where au_lname = "Mac Feather" La tabla authors en la que se basan estas vistas se compone de estas columnas: a u_id , au_lname , au_fname , phone , address , city , state y postalcode. Se puede omitir view2 y sustituirse por otra vista, llamada tambin view2 , que co ntenga criterios de seleccin ligeramente diferentes, como au_lname , phone from v iew_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 referenci a 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 us arse 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 v iew2 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 l as vistas dependientes siempre que la lista select de las vistas dependientes si ga siendo vlida. Si se viola esta regla, una consulta que haga referencia a la vi sta 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_rena me , 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 pu ede 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 propi etario de la base de datos puede cambiar el nombre de la vista de cualquier usua rio. La vista debe estar en la base de datos actual. Alteracin u omisin de objetos subyacentes Pueden surgir problemas si se cambia el nombre de un objeto subyacente de una vi sta. 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 Se rver las recompila. La recompilacin tiene lugar por diversas razones y sin notifi cacin al usuario; por ejemplo, si se carga una base de datos o si un usuario omit e y vuelve a crear una tabla u omite un ndice. Debido a esto, los intentos de con sultar o modificar la vista pueden hacer que SQL Server devuelva mensajes de err or 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 pro blemas, la forma ms segura es no cambiar el nombre de ninguna tabla o vista refer enciada por una vista, o bien modificar las definiciones de sus vistas dependien tes al cambiar su nombre. La situacin es similar cuando la vista depende de una tabla o vista que se ha omi tido. 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 s e 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 aparece rn. Esto se debe a que la abreviatura mediante asterisco se interpreta y ampla cua ndo se crea la vista por primera vez. Para ver las columnas nuevas mediante la v ista, omita la vista y vuelva a crearla. #endregion #region Modificacin de datos mediante vistas Aunque SQL Server no pone ninguna restriccin en la recuperacin de datos mediante v istas y Transact-SQL pone menos restricciones en la modificacin de datos mediante vistas que otras versiones de SQL, existen varias clases de operaciones de modi ficacin de datos no permitidas mediante vistas: No se permiten las operaciones update , insert o delete que hacen referencia a u na columna de la vista que es un clculo, es decir, una columna calculada o una fu ncin incorporada.

No se permiten las operaciones update , insert o delete que hacen referencia a u na vista que incluye agregados o agregados de fila, es decir, funciones incorpor adas y una clusula group by o compute . No se permiten las operaciones insert, delete y update que hacen referencia a un a vista distinct . No se permiten instrucciones insert a menos que todas las columnas NOT NULL de l as tablas subyacentes o las vistas se incluyan en la vista mediante la que se es tn 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 ac tualizadas 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 opti on . La actualizacin no se efecta de forma correcta si alguna de las columnas afec tadas aparece en la clusula where , en una expresin que incluya columnas de ms de u na tabla. No se permiten instrucciones insert y update en vistas distinct de mltiples tabla s. Las instrucciones update no pueden especificar un valor para una columna IDENTIT Y. El propietario de la tabla, el propietario de la base de datos o el administr ador del sistema pueden insertar (mediante insert ) un valor explcito en una colu mna IDENTITY despus de definir identity_insert on para la tabla base de la column a. 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 c omprueba que no se viola ninguna de las restricciones anteriores ni ninguna de l as reglas de integridad de datos. Por qu algunas vistas pueden actualizarse y otras no? Si examina los ejemplos de c ada uno de los tipos de vistas que no pueden actualizarse, entender mejor las res tricciones. 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 ca lculadas o funciones incorporadas. Por ejemplo, la columna amt_due de la vista a ccounts , 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 where pri ce > $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 amt_due ----------------------- PC1035 7,000.00 32,240.16 PC8888 8,000.00 8,190.00 PS1372 7,000.00 809.63 TC3218 7,000.00 785.63 (4 rows affected) Las operaciones update e insert no se permiten en la columna amt_due porque no h ay forma de deducir los valores subyacentes de precio, derechos de autor o venta s 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 ni ngn valor subyacente que eliminar. group by o compute en la definicin de vista La segunda restriccin se aplica a todas las columnas de vistas que contengan valo res agregados, es decir, vistas cuya definicin incluya una clusula group by o comp ute . 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_coo k 15.96 (6 rows affected) No tendra sentido insertar filas (mediante insert ) en la vista categories . A qu g rupo de filas subyacentes pertenecera una fila insertada? No es posible realizar actualizaciones en la columna average_price porque no hay forma de saber cmo debe ran cambiar los precios subyacentes a partir de los valores introducidos en dicha columna. En teora, se podran permitir eliminaciones y actualizaciones en la columna categor y , 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 t abla sobre la que se basa una vista. Generalmente, cuando se insertan filas nuev as (con insert ) mediante una vista, todas las columnas de las tablas subyacente s que no estn incluidas en la vista reciben valores nulos. Si no se permiten valo res nulos en una o ms de estas columnas, no se permitirn inserciones mediante la v ista. Considere la vista: create view titleview as select title_id, price, total_sales from titles w here type = 'business' La columna title de la tabla subyacente titles no admite valores nulos, por lo q ue no es posible realizar ninguna operacin insert mediante titleview . Aunque la columna title ni siquiera existe en la vista, su prohibicin de valores nulos conv ierte 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, incl uso 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 c heck option , cada fila insertada o actualizada mediante la vista debe estar vis ible 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 instrucci ones 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 publ ishers 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 instruc cin 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 s on actualizables. Las actualizaciones mediante una vista no pueden especificar u n valor de columna IDENTITY. Las inserciones en columnas IDENTITY estn limitadas al propietario de la tabla, e l 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 ta bla base de la columna. No es suficiente con definir set identity_insert o n par a la vista mediante la que se est realizando la insercin. #endregion #region Omisin de vistas Para eliminar una vista de la base de datos, utilice el comando drop view , cuya sintaxis es la siguiente: drop view [[ database .] owner .] view_name [, [[ database .] ow ner .] 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 , sys comments , sysprotects y sysdepends . Tambin se eliminan todos los privilegios pa ra 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 r eferenciadas en la definicin de vista. #endregion #region Uso de vistas como mecanismos de seguridad El permiso para acceder al subconjunto de datos de una vista debe concederse o r evocarse de forma explcita, independientemente de los permisos vigentes en las ta blas subyacentes de la vista. Los datos de una tabla subyacente que no est inclui da en la vista se ocultan de los usuarios que tienen autorizacin para acceder a l a 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 g enerar una vista de titles que omita dichas columnas y luego conceder a todos lo s usuarios el permiso sobre la vista y nicamente al departamento de ventas el per miso 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 re voke , respectivamente), consulte la Gua del Usuario de las Caractersticas de Segu ridad . #endregion #region Obtencin de informacin sobre vistas Varios procedimientos del sistema proporcionan informacin sobre las vistas a part ir 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 type Created_on -------------- ----- ------------------ hiprice dbo view Feb 12 1987 11:57AM Data_lo cated_on_segment When_created ------------------------------ ------------------Column_name Type Length Precision Scale ---------------------- --------- ----- title_id tid 6 NULL NULL title varchar 80 NULL NULL type char 12 NULL NULL pub_id char 4 NULL NULL pr ice money 8 NULL NULL advance money 8 NULL NULL royalty int 4 NULL NULL total_ sales int 4 NULL NULL notes varchar 200 NULL NULL pubdate datetime 8 NULL NULL Null Default_name Rule_name Identity ----------------- --------------- 0 NULL NULL 0 0 NULL NULL 0 0 NULL NULL 0 1

NULL NULL 0 1 NULL 0 1 NULL NULL 0 1 NULL 0 1 NULL NULL NULL NULL 0 0 NULL 0 No existe ninguna clave definida para este objeto.

NULL NULL 0 1 NULL (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 wher e 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 hace n 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.hipr ice vista dbo.titleview vista dbo.reptq1 procedimiento almacen ado dbo.reptq2 procedimiento almacenado dbo.reptq3 procedimiento almacenado (return status = 0) Para obtener informacin completa sobre los procedimientos del sistema, consulte e l Manual de Referencia de SQL Server . #endregion #endregion #region USO DE FUNCIONES INCORPORADAS EN CONSULTAS #region Funciones del sistema Las funciones del sistema devuelven informacin especial de la base de datos. Much as 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 e l 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 o mite:

select user_name() --------- dbo (1 row affected) Tenga presente que el administrador del sistema se convierte en propietario de l a base de datos que est utilizando al asumir la ID de usuario de servidor 1. Al u suario "invitado" siempre se le asigna la ID de usuario de servidor -1. Dentro d e una base de datos, el nombre de usuario ( user_name ) del propietario de la ba se 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 Funcin Argumento Resultado col_name ( object_id , column_id [, database_id ]) Devuelve el nombre de la columna. col_length ( object_name , column_name ) Devuelve la longitud definida de la columna. Use datalength para ver el tamao de datos real. curunreservedpgs (dbid, lstart, unreservedpgs ) Devuelve el nmero de pginas libres de una seccin del disco. Si la base de datos es t abierta, el valor se toma de la memoria; si la base de datos no est en uso, el v alor se toma de la columna u nreservedpgs de sysusages . data_pgs ( object_id , { doampg | ioampg }) 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. datalength ( expression ) 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 co millas. db_id ( [ database_name ] ) 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 co millas. Si no se proporciona ningn d atabase_name , db_id devuelve el nmero de ID de la base de datos actual. db_name ([ database_id ]) Devuelve el nombre de la base de datos. d atabase_id debe ser una expresin numric a. Si no se proporciona ninguna d atabase_id , db_name devuelve el nombre de la base de datos actual. host_id ( ) Devuelve la ID de proceso principal del proceso cliente (no el proceso SQL Serv er).

host_name ( ) Devuelve el nombre de computadora principal actual del proceso cliente (no el p roceso SQL Server). index_col ( object_name , index_id , key_ # [, user_id ]) Devuelve el nombre de la columna indexada; devuelve NULL si o bject_name no es un nombre de tabla ni de vista. isnull ( expression1 , expression2 ) Sustituye el valor indicado en e xpression2 cuando e xpression1 da como resulta do NULL. Los tipos de datos de las expresiones deben convertirse de forma implcit a, o es necesario usar la funcin c onvert . lct_admin Maneja el umbral de ltima oportunidad del segmento de diario. lastchance crea un umbral de ltima oportunidad en la base de datos especificada. logfull devuelve 1 si se ha cruzado el umbral de ltima oportunidad de la base de datos especificada y 0 en caso contrario. unsuspend activa las tareas suspendidas de la base de datos e inhabilita el umbr al de ltima oportunidad si ste se ha cruzado. reserve devuelve el nmero de pginas de diario libres necesarios para volcar de for ma correcta un diario de transacciones del tamao indicado. object_id ( object_name ) Devuelve la ID del objeto. object_name ( object_id [, database_id ] ) Devuelve el nombre del objeto. proc_role ( "sa_role" | "sso_role" | "oper_role" ) Comprueba si el usuario solicitante tiene el rol correcto para ejecutar el proc edimiento. Si el rol es correcto, el resultado es 1. En caso contrario, el resul tado es 0. reserved_pgs ( object_id , { doampg | ioampg }) Devuelve el nmero de pginas asignadas a la tabla o ndice. Esta funcin s indica las pg inas usadas para las estructuras internas. rowcnt ( doampg ) Devuelve el nmero de filas de una tabla (valor estimado). show_role ( ) Devuelve los roles activos actuales del usuario, si hay (sa_role, sso_role u op er_role). Si el usuario carece de roles, el resultado es NULL.

suser_id ([ server_user_name ]) Devuelve el nmero de ID del usuario de servidor de s yslogins. Si no se proporci ona ningn s erver_user_name , el resultado es la ID de servidor del usuario actua l. suser_name ([ server_user_id ]) 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 re sultado es el nombre del usuario actual. used_pgs ( object_id , doampg , ioampg ) Devuelve el nmero total de pginas usadas por una tabla y su ndice agrupado. tsequal ( timestamp , timestamp2 ) Compara valores t imestamp para evitar operaciones de actualizacin en una fila q ue 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 al macenada. Esta funcin permite usar el modo de examinacin sin llamar a DB-Library ( consulte la seccin sobre el modo de examinacin). user Devuelve el nombre del usuario. user_id ([ user_name ]) Devuelve el nmero de ID del usuario. Indica el nmero de s ysusers en la base de d atos actual. Si no se proporciona ningn u ser_name , el resultado es la ID del us uario actual. user_name ([ user_id ]) 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 u suario actual. valid_name ( character_expression ) Devuelve 0 si c haracter expression no es un identificador vlido (caracteres ile gales o ms de 30 bytes de longitud) y un nmero distinto de cero en caso contrario. valid_user ( server_user_id ) Devuelve 1 si la ID especificada es un usuario o alias vlido en al menos una bas e de datos de este SQL Server. Debe tener el rol s a_role o sso_role para usar e sta funcin en una s erver_user_id distinta de la propia.

Cuando el argumento de una funcin del datos, computadora principal, usuario tuales. Con la excepcin de user , las parntesis, incluso si el argumento es

sistema es opcional, se utilizan la base de de servidor o usuario de base de datos ac funciones incorporadas siempre se usan con 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, dat alength 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 d e 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 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) #endregion #region Funciones de cadena Las funciones de cadena se utilizan para diversas operaciones en cadenas de cara cteres o expresiones. Algunas funciones de cadena pueden usarse tanto en datos b inarios como de caracteres. Tambin es posible concatenar datos binarios, cadenas de caracteres o expresiones. Las funciones de cadena incorporadas devuelven valores que suelen necesitarse pa ra 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 necesa rio 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 implcit amente a char o varchar . Algunas funciones de cadena tambin pueden usarse en dat os binary y varbinary . patindex puede utilizarse en columnas text , char , ncha r , varchar y nvarchar . La concatenacin puede utilizarse en columnas binary y varbinary , as como en colum

nas char , nchar , varchar y nvarchar . Sin embargo, no es posible concatener co lumnas text. Las funciones de cadena pueden estar anidadas y emplearse en cualquier lugar don de se permita una expresin. Cuando se usan constantes con una funcin de cadena, ha y que incluirlas entre comillas dobles o simples. La Tabla 10-2 muestra los argumentos utilizados en las funciones de cadena. Si u na funcin usa ms de una expresin del mismo tipo, los argumentos se numeran, como ch ar_expr1 , char_expr2. Tabla 10-2: Argumentos usados en funciones de cadena Tipo de argumento Puede sustituirse por char_expr Un nombre de columna de tipo de caracteres, variable, o expresin constante de ti po char , varchar , nchar o nvarchar . Las funciones que aceptan nombres de colu mna text se indican en la explicacin. Las expresiones constantes deben aparecer e ntre comillas. expression Un nombre de columna binario o de caracteres, variable o expresin constante. Pue den ser datos char , varchar, ncha r o nvarchar , en cuanto a char_expr , ms bina ry o varbinary . pattern 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 adm itidos por SQL Server. approx_numeric Cualquier numrico aproximado ( float , real o double precision ), nombre de colu mna, variable o expresin constante. integer_expr Cualquier nmero entero (como tinyint, smallint o int ), nombre de columna, varia ble o expresin constante. Los mrgenes de tamao mximo se mencionan a medida que se ap lican. start Una expresin entera ( integer_expr). length Una expresin entera ( integer_expr).

Cada funcin tambin acepta argumentos que pueden convertirse implcitamente al tipo e specificado. Por ejemplo, las funciones que aceptan expresiones numricas aproxima das 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 Argument o Resultado ascii ( char_expr ) Devuelve el cdigo ASCII del primer carcter de la expresin.

char ( integer_expr ) Convierte un valor integer de un solo byte en un valor character . char se util iza generalmente como el inverso de ascii . integer_expr debe estar entre 0 y 25 5. Devuelve un tipo de datos char . Si el valor resultante es el primer byte de un carcter multibyte, el carcter puede estar indefinido. charindex ( expression1, expression2 ) 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. char_length ( char_expr ) 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 q uita los espacios en blanco finales de la expresin antes de contar el nmero de car acteres. Para los juegos de caracteres multibyte, el nmero de caracteres de la ex presin es generalmente menor que el nmero de bytes; use la funcin del sistema datal ength para determinar el nmero de bytes. difference ( char_expr1, char_expr2 ) Devuelve un valor entero que representa la diferencia entre dos valores soundex . Consulte soundex ms adelante. lower ( char_expr ) Convierte maysculas en minsculas. Devuelve un valor de caracteres. ltrim ( char_expr ) Quita los espacios en blanco iniciales de la expresin de caracteres. Slo se quita n los valores equivalentes al carcter de espacio en la especificacin de caracteres especiales de SQL. patindex ("% pattern %", char_expr [ using { bytes | chars | characters }] ) 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 pa ttern . De forma predeterminada, patindex devuelve el desplazamiento en caracter es. Para devolver el desplazamiento en bytes, es decir, cadenas de caracteres mu ltibyte, hay que especificar using bytes . El carcter comodn '%' debe preceder y s eguir a pattern , excepto cuando se buscan caracteres iniciales o finales. Consu lte la seccin sobre caracteres comodn en el Manual de Referencia de SQL Server par a obtener una descripcin de los caracteres comodn que pueden emplearse en pattern . Puede utilizarse en datos text . replicate ( char_expr, integer_expr ) 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 e n un espacio de 255 bytes, cualquiera que sea inferior. reverse ( char_expr )

Devuelve el inverso de char_expr ; si char_expr es "abcd", devuelve "dcba". right ( char_expr, integer_expr ) Devuelve la parte de la expresin de caracteres que empieza por el nmero de caract eres desde la derecha. El valor de retorno tiene el mismo tipo de datos que la e xpresin de caracteres. rtrim ( char_expr ) Quita los espacios en blanco finales. Slo se quitan los valores equivalentes al carcter de espacio en la definicin de caracteres especiales de SQL. soundex ( char_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. space ( integer_expr ) Devuelve una cadena con el nmero indicado de espacios de un solo byte. str ( approx_numeric [, length [, decimal ] ]) Devuelve una representacin de caracteres del nmero de e el nmero de caracteres que se devolvern (incluido el tos situados a la derecha e izquierda del punto decimal, o); decimal define el nmero de dgitos decimales que se coma flotante. length defin punto decimal, todos los dgi y los espacios en blanc devolvern.

length y decimal son opcionales. Si se especifican, deben ser no negativos. La l ongitud predeterminada es 10; el decimal predeterminado es 0. str redondea la po rcin decimal del nmero para que los resultados quepan dentro de la longitud especi ficada. stuff ( char_expr1 , start , length Elimina los caracteres length en char_expr1 en start . Para , char_expr2 debera ser NULL, , char_expr2 ) de char_expr1 en start , despus inserta char_expr2 eliminar caracteres sin insertar otros caracteres no " ", que indica un solo espacio.

substring ( expression , start , length ) Devuelve parte de una cadena de caracteres o binaria. start especifica la posic in de carcter donde empieza la subcadena. length especifica el nmero de caracteres de la subcadena. upper ( char_expr ) Convierte minsculas en maysculas. Devuelve un valor de caracteres.

Ejemplos del uso de funciones de cadena charindex y patindex Las funciones charindex y patindex devuelven la posicin inicial de un patrn especi ficado. Ambas toman dos argumentos, pero funcionan de forma ligeramente diferent e, puesto que patindex puede utilizar caracteres comodn, pero charindex no. chari

ndex slo puede utilizarse en columnas char , nchar , varchar y nvarchar ; patinde x 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 pat rn, a menos que se est buscando el patrn como el primer carcter (se omite el % inici al) 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 caractere s, generalmente un nombre de columna, en el que SQL Server busca el patrn especif icado. Para encontrar la posicin en la que el patrn "wonderful" comienza en una fila dete rminada de la columna notes de la tabla titles usando ambas funciones, escriba e sta consulta: select charindex("wonderful", notes), patindex("%wonderful%", notes) fr om titles where title_id = "TC3218" ------------- ------------46 46 (1 row affected) Si no limita las filas que deben buscarse, la consulta devolver todas las filas d e la tabla y mostrar valores cero para aquellas filas que no contengan el patrn. E n el siguiente ejemplo, patindex busca todas las filas de sysobjects que empiece n con "sys" y cuyo cuarto carcter sea a, b, c o d: select name from sysobjects where patindex("sys[a-d]%", name) > 0 name -----------------------------sysalternat es sysattributes syscharsets syscolumns syscomments sysconfigures sysconst raints syscurconfigs sysdatabases sysdepends sysdevices (11 rows affecte d) str La funcin str convierte nmeros en caracteres, con argumentos opcionales para la es pecificacin de la longitud del nmero (incluido el signo, el punto decimal y los dgi tos a la derecha e izquierda del punto decimal) y el nmero de posiciones despus de l punto decimal. Los argumentos de longitud y decimal de str (si se proporcionan) deben ser posit ivos. 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 de l nmero. La parte decimal del resultado se redondea para que quepa dentro de la l ongitud 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, -- ** (1 row Un approx_numeric corto un approx_numeric largo 4) affected) se justifica a la derecha en la longitud especificada y 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 longitu d es negativa, se devuelve una cadena NULL. Si la posicin inicial es mayor que expr1 , se devuelve una cadena NULL. Si la lon gitud que debe eliminarse es mayor que expr1 , se elimina hasta el ltimo carcter e n 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 po r 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 p ara su uso en una comparacin. Las vocales se ignoran en la comparacin. Los caracte res no alfabticos terminan la evaluacin soundex . Esta funcin siempre devuelve algn valor. Estos dos nombres tienen cdigos soundex idnticos: select soundex ("smith"), soundex ("smythe") ----- ----S530 S530 La funcin difference compara los valores soundex de dos cadenas y evala la similit ud entre ellos, devolviendo un valor de 0 a 4. Un valor de 4 es la mejor coincid encia 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. P or ejemplo: Tabla 10-4: Ejemplos de funciones de cadena Instruccin Resultado select right("abcde", 3) cde select right("abcde", 6) abcde select upper("torso") TORSO select ascii("ABC") 65

substring El siguiente ejemplo usa la funcin substring . En l se muestra el apellido y la le tra 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 cade na de caracteres o binaria. La funcin substring siempre toma tres argumentos. El primero puede ser una de caracteres o binaria, un nombre de columna o una expresin con valor de que incluya un nombre de columna. El segundo indica la posicin donde debe r la subcadena. El tercero especifica la longitud, en nmero de caracteres, cadena que ha de devolverse. Este es el aspecto de la sintaxis de substring : cadena cadena empeza de la

substring( expression , start , length ) Por ejemplo, a continuacin se indica cmo especificar los caracteres segundo, terce ro 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 cad enas de caracteres o binarias, datos de caracteres o binarios, o una combinacin d e los mismos) mediante el operador de concatenacin de cadenas +. Si concatena cadenas de caracteres, incluya cada expresin de caracteres entre com illas simples o dobles. Esta es la sintaxis de la concatenacin: 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 c olumna Moniker , en el orden apellido-nombre y con una coma y un espacio despus d el apellido: select Moniker = (au_lname + ", " + au_fname) from authors where state = "C A" Moniker ------------------------------------------------- White, Johnson Green, Marjorie Carson, Cheryl O'Leary, Michael Straight, Dick Bennet, A braham Dull, Ann Gringlesby, Burt Locksley, Chastity Yokomoto, Akiko S tringer, 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 c onvert : 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 d espus del primer nombre, puede teclear: select (au_lname + "," + " " + substring(au_fname, 1, 1) + ".") from authors where city = "Oakland" -------------------------------------------- Green, M. Straight, D. Strin ger, D. MacFeather, S. Karsen, L. (5 rows affected) Para mostrar la pub_id y los dos primeros caracteres de cada title_id de los lib ros por encima de $20, escriba:

select substring(pub_id + title_id, 1, 6) -------------- 1389PC 0877PS 0877TC #endregion

from titles where price > $20 (3 rows affected)

#region 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 l a Tabla 10-5. Tabla 10-5: Funciones de texto incorporadas para datos text e image Funcin Argumento Resultado patindex ("% pattern %", char_expr [ using { bytes | chars | characters } ] ) 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 pa ttern . De forma predeterminada, patindex devuelve el desplazamiento en caracter es; para devolver el desplazamiento en bytes para cadenas de caracteres multibyt e, hay que especificar using bytes . El carcter comodn % debe preceder y seguir a pattern , excepto cuando se buscan caracteres iniciales o finales. Consulte la s eccin sobre caracteres comodn del Manual de Referencia de SQL Server para obtener una descripcin de los caracteres comodn que se pueden utilizar en pattern . textptr ( text_columname ) Devuelve el valor del puntero de texto, un valor binario de 16 bytes. El punter o de texto se verifica para garantizar que apunte a la primera pgina de texto. textvalid (" table_name .. col_name ", textpointer ) Verifica si es vlido un puntero de texto dado. Tenga en cuenta que el identifica dor 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. set textsize { n | 0 } Especifica el lmite, en bytes, de los datos t ext o image que van a ser devuelto s 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 dev olver; 0 restaura el lmite predeterminado de 32K.

Adems de estas funciones, datalength (descrita en "Funciones del sistema") funcio na en columnas text . Tambin pueden usarse las variables globales @@textcolid , @ @textdbid , @@textobjid , @@textptr y @@textsiz e para manipular datos text e im age . Ejemplos del uso de funciones de texto Este ejemplo utiliza la funcin textptr para localizar la columna text , blurb , a sociada con la title_id BU7832 de la tabla texttest . El puntero de texto, una c adena binaria de 16 bytes, se incluye en una variable local, @val , y se suminis tra como parmetro del comando readtext . readtext devuelve 5 bytes empezando en e l 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 a

nnotated analysis of what computers can do for you: a no-hype guide fo r the critical user", "1389") declare @val varbinary(16) select @val = textptr(blurb) from texttest whe re title_id = "BU7832" readtext texttest.blurb @val 1 5 La funcin textptr devuelve una cadena binaria de 16 bytes. Es una buena idea pone r esta cadena en una variable local, como en el ejemplo anterior, y utilizarla c omo 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 a nnotated analysis of what computers can do for you: a no-hype guide fo r 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 real izada en un campo text o image por el proceso actual de SQL Server. Las insercio nes 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 im age se truncan a 255 bytes. La conversin de datos text o image a tipos de datos d istintos de los indicados no se admite, ni implcita ni explcitamente. #endregion #region Funciones matemticas Las funciones matemticas incorporadas devuelven valores que normalmente son neces arios 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 funcione s matemticas incorporadas: Tabla 10-6: Argumentos usados en las funciones matemticas Tipo de argumento Puede sustituirse por approx_numeric Cualquier numrico aproximado ( float , real o double precision ), nombre de colu mna, variable, expresin constante, o una combinacin de los mismos. integer Cualquier nmero entero ( tinyint , smallint o int), nombre de columna, variable, expresin constante, o una combinacin de los mismos. numeric Cualquier numrico exacto ( numeric , dec , decimal , tinyint , smallint o int ), numrico aproximado ( float , real o double precision ), o columna money , variab le, expresin constante, o una combinacin de los mismos power Cualquier numrico exacto, numrico aproximado o columna money , variable, expresin constante, o una combinacin de los mismos.

Cada funcin tambin acepta argumentos que pueden convertirse implcitamente al tipo e specificado. Por ejemplo, las funciones que aceptan tipos numricos aproximados ta mbin 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 numera das (por ejemplo, approx_numeric1 , approx_numeric2 ). A continuacin se muestran las funciones matemticas, sus argumentos y los resultado s que devuelven: Tabla 10-7: Funciones matemticas Func in Argumento Resultado abs ( numeric ) Devuelve el valor absoluto de una expresin dada. Los resultados son del mismo ti po y tienen la misma precisin y escala que la expresin numrica. acos ( approx_numeric ) Devuelve el ngulo (en radianes) cuyo coseno es el valor especificado. asin ( approx_numeric ) Devuelve el ngulo (en radianes) cuyo seno es el valor especificado. atan ( approx_numeric ) Devuelve el ngulo (en radianes) cuya tangente es el valor especificado. atn2 ( approx_numeric1 , approx_numeric2 ) Devuelve el ngulo (en radianes) cuya tangente es ( approx_numeric1 / approx_nume ric2 ). ceiling ( numeric ) Devuelve el nmero entero ms pequeo mayor o igual que el valor especificado. Los re sultados son del mismo tipo que la expresin numrica. Para expresiones numeric y de cimal , los resultados tienen una precisin igual que la de la expresin y una escal a de 0. cos ( approx_numeric ) Devuelve el coseno trigonomtrico del ngulo especificado (en radianes). cot ( approx_numeric ) Devuelve la cotangente trigonomtrica del ngulo especificado (en radianes). degrees ( numeric ) Convierte radianes en grados. Los resultados son del mismo tipo que la expresin numrica. Para expresiones numeric y decimal , los resultados tiene una precisin in terna 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.

exp ( approx_numeric ) Devuelve el valor exponencial del valor especificado. floor ( numeric ) Devuelve el nmero entero ms grande menor o igual que el valor especificado. Los r esultados son del mismo tipo que la expresin numrica. Para expresiones de tipo num eric o decimal , los resultados tendrn una precisin igual a la de la expresin y una escala de 0. log ( approx_numeric ) Devuelve el logaritmo natural del valor especificado. log10 ( approx_numeric ) Devuelve el logoritmo de base 10 del valor especificado. pi () Devuelve el valor constante de 3.1415926535897936. power ( numeric , power ) 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 re sultados tienen una precisin de 77 y una escala igual a la de la expresin. radians ( numeric_expr ) Convierte grados a radianes. Los resultados son del mismo tipo que numeric. Par a expresiones de tipo numeric o decimal , los resultados tienen una precisin inte rna de 77 y una escala igual a la de la expresin numrica. Cuando se utiliza el tip o de datos money, la conversin interna a float puede provocar una prdida de precis in. rand ([ integer ]) Devuelve un valor float aleatorio entre 0 y 1, utilizando el integer opcional c omo valor semilla. round ( numeric , integer ) Redondea el valor numeric para que tenga dgitos integer significativos. Un valor entero positivo determina el nmero de dgitos significativos a la derecha del punt o decimal; un entero negativo, el nmero de dgitos significativos a la izquierda de l 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 i gual a la de la expresin numrica. sign ( numeric ) Devuelve el signo de numeric : positivo (+1), cero (0) o negativo (-1). Los res ultados son del mismo tipo y tienen la misma precisin y escala que la expresin numr ica. sin ( approx_numeric )

Devuelve el seno trigonomtrico del ngulo especificado (medido en radianes). sqrt ( approx_numeric ) Devuelve la raz cuadrado del valor especificado. tan ( approx_numeric ) Devuelve la tangente trigonomtrica del ngulo especificado (medido en radianes).

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 fun ciones 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 ari thabort y arithignore para determinar el modo en que se manipulan los errores. P ara obtener ms informacin sobre estas opciones, consulte la seccin "Errores de conv ersin". A continuacin se muestran ejemplos sencillos de funciones matemticas: Tabla 10-8: Ejemplos de funciones matemticas Instruccin Resultado select floor(123) select floor(123.45) select floor(1.2345E2) select floor(-123.45) select floor(-1.2345E2) select floor($123.45) 123 123.000000 123.000000 -124.000000 -124.000000 123.00 select ceiling(123.45) select ceiling(-123.45) select ceiling(1.2345E2) select ceiling(-1.2345E2) select ceiling($123.45) 124.000000 -123.000000 124.000000 -123.000000 124.00 select round(123.4545, 2) select round(123.45, -2) select round(1.2345E2, 2) select round(1.2345E2, -2) 123.4500 100.00

123.450000 100.000000

La funcin round(numeric, integer) devuelve siempre un valor. Si integer es negati vo 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 ). #endregion #region Funciones de fecha Las funciones de fecha incorporadas se utilizan para mostrar informacin sobre fec has y horas. Estas funciones manipulan valores datetime y smalldatetime, y reali zan 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 S erver 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 f echa 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 preci sin 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 f echas van desde el 1 de enero de 1900 hasta el 6 de junio de 2079, con una preci sin al minuto. El formato de visualizacin predeterminado de las fechas tiene el siguiente aspect o: Apr 15 1987 10:23PM Consulte la seccin sobre convert , ms adelante en este captulo, para obtener ms info rmacin sobre cmo cambiar el formato de visualizacin de datetime o smalldatetime . C uando se introducen valores datetime o smalldatetime , hay que incluirlos entre comillas simples o dobles. SQL Server reconoce una amplia variedad de formatos d e entrada de datos de fecha y hora. Para obtener ms informacin sobre los valores d atetime y smalldatetime , consulte el Captulo 7, "Creacin de bases de datos y tabl as", 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 Argumento Resultado getdate ( ) Fecha y hora actuales del sistema.

datename ( datepart , date ) Parte de un valor datetime o smalldatetime como una cadena ASCII. datepart ( datepart , date ) Parte de un valor datetime o smalldatetime , por ejemplo, el mes, como un valor entero. datediff (datepart, date, date) La cantidad de tiempo entre la segunda y la primera de las dos fechas, converti da al componente de fecha especificado, por ejemplo, meses, das, horas. dateadd (datepart, number, date) Una fecha generada al aadir componentes de fecha a otra fecha.

Las funciones datename , datepart , datediff y dateadd toman como argumentos un componente de fecha (ao, mes, hora, etc.). La siguiente tabla enumera cada compon ente 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 yy 1753-9999 quarter qq 1 - 4 month mm 1 - 12 week wk 1 - 366 day dd 1 - 31 dayofyear dy 1 - 54 weekday dw 1 - 7 (1 es domingo en us_english) hour

hh 0 - 23 minute mi 0 - 59 second ss 0 - 59 millisecond ms 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 Se rver 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 i mpriman cada vez que se genere el informe. getdate tambin resulta til para funcion es 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, cuand o se utiliza un valor smalldatetime con cualquiera de estas funciones, los segun dos 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) select datename ( month , getdate ()) ------------- July (1 row affected) 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, datedi ff halla un intervalo entre dos fechas. El resultado es un valor entero con sign o 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 re sultado generado por la consulta anterior es 40, el nmero de das entre el 21 de oc tubre 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 v alor 5 para las filas con una pubdate en junio. Cuando la primera fecha de la fu ncin datediff es posterior a la segunda fecha especificada, el valor resultante e s negativo. Dado que dos de las filas de titles tienen valores pubdate que se ha n 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 valore s negativos en las dos consultas anteriores. Si uno o ambos argumentos de fecha es un valor smalldatetime, se convierten en v alores datetime internamente para el clculo. Los segundos y milisegundos de los v alores smalldatetime se definen automticamente en 0 de cara al clculo de diferenci as. 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 tre s 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 1 2:00AM Jun 25 1985 12:00AM Jun 12 1985 12:00AM Jun 21 1985 12:00AM Sep 1 1 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 1 2:00AM Jun 15 1985 12:00AM (18 rows affected) Si el argumento de fecha se proporciona como un valor smalldatetime , el resulta do tambin ser smalldatetime . Puede utilizar dateadd para aadir segundos o milisegu ndos a un smalldatetime , pero slo tiene sentido si la fecha resultante devuelta por dateadd cambia al menos en un minuto.

#endregion #region 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 deter minadas conversiones de tipo de datos de forma automtica, que reciben el nombre d e conversiones implcitas. Por ejemplo, si compara una expresin char y otra datetim e , o una expresin smallint y otra int , o expresiones char de longitudes diferen tes, SQL Server convierte automticamente un tipo de datos a otro. Otras conversiones de tipo de datos deben solicitarse de forma explcita, utilizan do una de las funciones de conversin de tipos de datos incorporadas. Por ejemplo, antes de concatenar expresiones numricas, es necesario convertirlas a expresione s de caracteres. SQL Server proporciona tres funciones de conversin de tipos de datos, convert , i nttohex y hextoint . Estas funciones pueden emplearse en la lista select , la clu sula where y cualquier lugar donde se permita una expresin. SQL Server no permite convertir ciertos tipos de datos a otros tipos de datos, n i de forma implcita ni explcita. Por ejemplo, no se pueden convertir datos smallin t a datetime , ni datos datetime a smallint . Las conversiones no admitidas gene ran mensajes de error. Conversiones soportadas La Figura 10-1: Conversiones de tipos de datos implcitas, explcitas y no soportada

s resume las conversiones de tipos de datos soportadas por SQL Server: Las conversiones marcadas como "I" se manipulan implcitamente y no requieren ning una funcin de conversin de tipos de datos, aunque es posible utilizar la funcin con vert en ellas sin error. Las conversiones marcadas como "E" deben realizarse explcitamente, con la funcin d e conversin de tipo de datos adecuada . Las conversiones marcadas como "IE" se manipulan implcitamente cuando no existe u na 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 conve rsin de este tipo, SQL Server generar un mensaje de error. Las conversiones de un tipo en s mismo se marcan como "-" . En general, SQL Serve r 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 en tre una amplia variedad de tipos de datos y especificar un nuevo formato de visu alizacin 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 Gar lic: Cooking Secrets of the Mediterranean 125 Fifty Years in Buc kingham Palace Kitchens 15096 Sushi, Anyone? 5405 (3 rows affected) En este ejemplo, la columna total_sales , una columna int , se convierte a una c olumna char (5) para que pueda utilizarse con la palabra clave like : select title, total_sales from titles where convert(char(5), total_sales) l ike "15%" and type = "trad_cook" title ------------------------------------- Fifty Years in Bucking ham Palace Kitchens 15096 (1 row affected) Algunos tipos de datos esperan una longitud o una precisin y escala. Si no especi fica una longitud, SQL Server utiliza la longitud predeterminada 30 para los dat os de caracteres y binarios. Si no especifica una precisin o escala, SQL Server u tiliza los valores predeterminados 18 y 0, respectivamente. Reglas de conversin En las siguientes secciones se describen las reglas que SQL Server tiene en cuen ta 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 compon en totalmente de caracteres que son vlidos para el tipo nuevo. Los espacios en bl anco iniciales se ignoran. Los errores de sintaxis se generan cuando los datos incluyen caracteres inacepta bles. Los siguientes son algunos ejemplos de caracteres que pueden generar error

es 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 car acteres sin un equivalente de un solo byte se convierten en espacios en blanco. Las columnas text pueden convertirse explcitamente a char, nchar , varchar o nvar char . El lmite viene determinado por la longitud mxima de los tipos de datos de c aracteres, 255 bytes. Si no especifica la longitud, el valor convertido tiene un a 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 caracter es. Si el tipo nuevo es demasiado corto para albergar la cadena completa, se gen era 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 '1 2.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 decim al, pero redondean hasta la centena ms prxima (.01) para fines de visualizacin. Cua ndo los datos se convierten a un tipo monetario, se redondean hasta cuatro posic iones. Si es posible, los datos convertidos de un tipo monetario siguen el mismo compor tamiento de redondeo. Si el tipo nuevo es un numrico exacto con menos de tres pos iciones decimales, los datos se redondean a la escala del tipo nuevo. Por ejempl o, cuando $4.50 se convierte a un valor entero, el resultado es 4: select convert(int, $4.50) ----------4 Los datos convertidos a money o smallmoney se supone que estn en unidades monetar ias 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 sm alldatetime . Los nombres de meses incorrectos provocan errores de sintaxis. Las fechas que se encuentran fuera del margen aceptable del tipo de datos generan e rrores de desbordamiento aritmtico. Cuando los valores datetime se convierten a smalldatetime , se redondean al minu to ms prximo. Conversin entre tipos numricos Los datos pueden convertirse de un tipo numrico a otro. Si el tipo nuevo es un nu mrico exacto cuya precisin o escala no es suficiente para albergar los datos, se p ueden producir errores. Use las opciones arithabort y arithignore se para determ inar el modo en que se manipulan estos errores.

Note: Las opciones arithabort y arithignore se han redefinido para SQL Server, V ersin 10.0. Si utiliza estas opciones en sus aplicaciones, examnelas para asegurar se 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 ti po de hardware que se utiliza determina el modo en que se almacenan e interpreta n los datos. Algunas plataformas consideran el primer byte despus del prefijo 0x como el ms significativo; otras consideran el primer byte como el menos significa tivo. 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 importa ncia 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 prefi jo 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 alg unas plataformas, esta cadena representa el nmero 1; en otras, el nmero 256. Depen diendo 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 l as funciones hextoint e inttohex . hextoint acepta literales o variables que se componen de dgitos y las letras de l a 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 lo s trunca. Si los datos tienen menos de ocho dgitos, hextoint los justifica a la d erecha y los rellena con ceros. A continuacin, hextoint devuelve el valor entero equivalente independiente de la plataforma. Las expresiones descritas anteriorme nte devuelven el mismo valor, 256, independientemente de la plataforma que ejecu te 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. Conversin de datos image a binary o La funcin convert se puede utilizar arbinary . Los tipos de datos binary es. Si no se especifica la longitud, eterminada de 30 caracteres. varbinary para convertir una columna image a binary o v tienen una longitud mxima, que es de 255 byt el valor convertido tiene una longitud pred

Errores de conversin En las siguientes secciones se describen los tipos de errores que pueden produci rse 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 res ultados. Esto ocurre durante: Conversiones explcitas o implcitas a tipos exactos con una precisin o escala inferi or. Conversiones de datos explcitas o implcitas que se encuentran fuera del margen ace ptable 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 explcita s. Use la opcin arithabort arith_overflow para determinar el modo en que SQL Serv er manipula estos errores. El valor predeterminado, arithabort arith_overflow on , revierte toda la transaccin o lote donde se genera el error. Si define arithab ort arith_overflow off , SQL Server aborta la instruccin que origina el error, pe ro 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 me nsaje de advertencia cuando se produce un error de divisin por cero o una prdida d e precisin. La definicin de arithignore arith_overflow on suprime los mensajes de advertencia tras estos errores. La palabra clave arith_overflow puede omitirse s in 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 exp lcitamente un tipo numrico float , numeric o decimal a un integer , SQL Server sup one 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 deter minar la gravedad de un error de ese tipo. El valor predeterminado, arithabort n umeric_truncation on , aborta la instruccin que origina el error, pero contina pro cesando otras instrucciones de la transaccin o lote. Si define arithabort numeric _truncation off , SQL Server trunca los resultados de la consulta y sigue proces ando. Errores de dominio La funcin convert genera un error de dominio cuando el argumento de la funcin se e ncuentra fuera del margen sobre el que se define la funcin. Esto debera ocurrir co n 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 inte rpretan de forma distinta en plataformas diferentes. Por ejemplo, la cadena 0x00 00100 representa 65536 en las mquinas que consideran el byte 0 como el ms signific ativo 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 fun cin 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 demas iado largos.

convert y las conversiones de tipos de datos implcitas evalan los datos binarios d e forma distinta en plataformas diferentes. Debido a esto, los resultados pueden variar de una plataforma a otra. Emplee la funcin hextoint para la conversin inde pendiente de la plataforma de cadenas de caracteres hexadecimales a valores ente ros y la funcin inttohex para la conversin independiente de la plataforma de valor es enteros a valores hexadecimales. La funcin hextoint La funcin hextoint se utiliza para las conversiones independientes de la platafor ma de datos hexadecimales a valores enteros. hextoint acepta una cadena hexadeci mal 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 siem pre devuelve el mismo entero equivalente para una cadena de caracteres hexadecim al dada, independientemente de la plataforma en la que se ejecute. La funcin intt ohex La funcin inttohex se utiliza para conversiones independientes de la plataforma d e 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 rbinary . Los tipos de datos binary s. Si no especifica la longitud, el minada de 30 caracteres. Conversin para convertir una columna image a binary o va tienen una longitud mxima, que es de 255 byte valor convertido tiene una longitud predeter de otros tipos de datos al tipo de bits

Los tipos numricos exactos y aproximados pueden convertirse al tipo de bits de fo rma 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. Ca mbio del formato de visualizacin de las fechas El parmetro style de convert proporciona una gran variedad de formatos de visuali zacin 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 u n 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 varieda d de formatos de fecha que puede utilizarse. Cuando utilice style con smalldatet ime , los estilos que incluyen segundos o milisegundos mostrarn ceros en dichas p osiciones. Tabla 10-11: Conversin de formatos de fecha con el parmetro style Sin siglo (yy) Con siglo (yyy0) Norma Salida 0 o 100

Valor predeterminado mon dd yyyy hh:mm AM (o PM) 1 101 EE.UU. mm/dd/yy 2 2 Norma SQL yy.mm.dd 3 103 Ingls/francs dd/mm/yy 4 104 Alemn dd.mm.yy 5 105 dd-mm-yy 6 106 dd mon yy 7 107 mon dd, yy 8 108 hh:mm:ss 9 o 109 Valor predeterminado + milisegundos mon dd yyyy hh:mm:sss AM (o PM) 10 110 EE.UU. mm-dd-yy 11 111 Japn yy/mm/dd 12 112

ISO yymmdd

Los valores predeterminados, estilo 0 o 100, y 9 o 109, siempre devuelven el sig lo (yyyy). A continuacin se muestra un ejemplo del uso del parmetro style de convert : select convert(char(12), getdate(), 3) Esto convierte la fecha actual al estilo ''3'', dd/mm/yy . #endregion #endregion #region CREACIN DE NDICES EN TABLAS Es posible crear uno o ms ndices en una tabla a fin de acelerar el proceso de recu peracin 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 recupera cin de informacin indicando a SQL Server la posicin que ocupan los datos de una col umna 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 p ara hacer referencia a un ndice en una consulta. Slo es posible crear u omitir ndic es de una tabla; SQL Server decide si usarlos o no para cada una de las consulta s ejecutadas para esa tabla. A medida que los datos de una tabla van cambiando c on el tiempo, SQL Server puede cambiar los ndices de la tabla de modo que refleje n 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 rel acin lgica existente entre ellas. Indices nicos : estos ndices no permiten que dos filas de las columnas especificad as tengan el mismo valor. SQL Server verifica si existen valores duplicados cuan do 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 qu e ordene y vuelva a ordenar continuamente las filas de la tabla de modo que su o rden fsico sea siempre el mismo que el orden lgico (o indexado). Slo se permite un n dice agrupado por tabla. Los ndices no agrupados no requieren que el orden fsico d e las filas sea el mismo que el orden indexado. Todos los ndices no agrupados pue den 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 es tn 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 c reate 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 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 column a. 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 fo rma automtica cuando un ndice agrupado se reconstruye. Otra razn es que la insercin, eliminacin o actualizacin de datos de columnas indexad as 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 ndic es 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 usad o. Una columna a la que se acceda con frecuencia segn criterios de ordenacin, es deci r, 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 indexa rse, dado que el sistema puede llevar a cabo la combinacin con mayor rapidez si l as columnas estn ordenadas segn criterios de ordenacin. La columna que almacena la clave primaria de la tabla tiene con frecuencia un ndi

ce 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 l a fila con el primer valor del margen, se garantiza que las filas con los valore s subsiguientes sern fsicamente adyacentes. Un ndice agrupado no ofrece ventajas ta n 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, tampoc o se benefician de los ndices. Si el sistema tiene que buscar en una columna no indexada, lo hace examinando la s 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 form ato 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 si guiente: 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 l a contiene. No es posible crear ndices en columnas que tienen los tipos de datos bit , text o image . 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 [, column_name ] ...) [with {{fillfactor | max_rows_per_page}= x, ignore_dup_key, sort ed_data, [ignore_dup_row | allow_dup_row]}] [on segment_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 s egmento que apunte a un dispositivo de bases de datos especfico o a un conjunto d e dispositivos de bases de datos. Antes de crear un ndice en un segmento, consult e al administrador del sistema o al propietario de la base de datos a fin de obt ener una lista de los segmentos que puede utilizar. Algunos segmentos pueden est ar 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 co mpuesto 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 l os 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 inver tir en la instruccin de creacin de ndices anterior. Es posible combinar hasta 16 columnas en un mismo ndice compuesto. Todas las colu mnas 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 long itudes 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 column as, junto con la columna sensitivity , forman un ndice compuesto de los valores c ombinados 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 tien e un ndice compuesto en pname , sname y sensitivity (aadida de forma automtica por SQL Server). Cuando especifique las columnas en la instruccin create index , pong a 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, co mo 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 invertirs e en la instruccin de creacin de ndices anterior. SQL Server siempre aade sensitivit y 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 d e ndice, incluido el valor NULL. El sistema verifica la existencia de valores dup licados cuando el ndice se crea, si ya existen datos, y realiza esta verificacin c ada vez que se aaden o modifican datos con una instruccin insert o update . La especificacin de un ndice nico slo es til cuando la unicidad es una caracterstica d e los datos propiamente dichos. Por ejemplo, no es conveniente asignar un ndice ni co 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 nmero s de la seguridad social. En este caso, la unicidad es una caracterstica propia d e 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 e jemplo, 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 administra cin pblica. Si intenta crear un ndice nico en , el comando se aborta y SQL Server imer duplicado. No es posible crear res nulos en ms de una fila; stos datos existentes que incluyen valores duplicados muestra un mensaje de error que indica el pr un ndice nico en una columna que contiene valo se consideran valores duplicados para fines de i

ndexacin. 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 opcion es de ndices ms adelante en este captulo. Es posible usar la palabra clave unique en ndices compuestos. Esto no se ha lleva do 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 TY en las claves de ndice de una tabla para que todos los ndices creados en la sean nicos. Esta opcin de base de datos hace que los ndices lgicamente an nicos internamente y permite usarlos para procesar cursores actualizables cturas de nivel de aislamiento 0. IDENTI la tab no nicos se y le

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 a l definir la opcin de base de datos auto identity como true antes de crear la tab la. 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 l a instruccin create index . Estas opciones se proporcionan para mejorar el rendim iento 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 SQ L 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 deja r 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 pre determinado con el procedimiento del sistema sp_configure . Consulte la Gua de Ad ministracin 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 = 10 0 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 La opcin max_rows_per_page limita el nmero de filas que SQL Server puede incluir e n cada pgina de ndice. Un valor max_rows_per_page bajo reduce la contienda de bloq ueo y slo resulta til para las tablas a las que se accede con frecuencia. Los valo res bajos tambin hacen que el ndice ocupe espacio. El valor predeterminado es 0, que se emplea cuando no se especifica un valor mxim

o. 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_pa ge = 10 Uso de ndices agrupados o no agrupados Con un ndice agrupado, SQL Server ordena las filas de forma continuada de modo qu e 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 esto s 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 e n 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 clav es externas y las claves comunes (pares de claves que se combinan con frecuencia ) con los procedimientos del sistema sp_primarykey , sp_foreignkey y sp_commonke y . Puede mostrar informacin sobre las claves y sobre las columnas que son probab les candidatos de combinacin mediante sp_helpkey y sp_helpjoins , respectivamente . Como alternativa, es posible especificar restricciones primary key con las instr ucciones create table o alter table a fin de crear un ndice e imponer los atribut os 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 infor macin completa sobre los procedimientos del sistema, consulte el Manual de Refere ncia de SQL Server. Con un ndice no agrupado, do. El nivel de hoja de un las pginas de datos. Ms y un puntero hacia la fila no agrupado tiene un nivel piamente dichos. el orden fsico de las filas no es el mismo que el indexa ndice no agrupado contiene punteros hacia las filas de concretamente, cada pgina hoja contiene un valor indexado que contiene dicho valor. En otras palabras, un ndice adicional entre la estructura de ndice y los datos pro

Cada uno de los hasta 249 ndices no agrupados permitidos en una tabla puede propo rcionar 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 re cuperan muchas filas con valores clave contiguos, es decir, en las columnas dond e 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 indexad os subsiguientes sern fsicamente adyacentes, y no ser necesaria ninguna bsqueda adic ional. Si no se usa la palabra clave clustered ni la palabra clave nonclustered , se cr ea un ndice no agrupado. A continuacin se muestra la forma de crear el ndice de la columna title_id de la t

abla titles (si desea ejecutar este comando, primero debe omitir el ndice con dro p index ): create clustered index titleidind on titles(title_id) Puesto que piensa que ser necesario ordenar con frecuencia las personas de la tab la friends_etc segn su cdigo postal, debera crear un ndice no agrupado en la columna postalcode de la siguiente manera: create nonclustered index postalcodeind on friends_etc(postalcode) Un ndice nico no tendra ningn sentido en este caso, puesto que es probable que algun os de sus contactos tengan el mismo cdigo postal. Un ndice agrupado no sera adecuad o 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 d e nombre y apellidos. Para crear este ndice agrupado, primero omita el ndice no ag rupado 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 disp ositivo 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 reserv ados por razones de rendimiento. Especificacin de opciones de ndices Las opciones de ndices ignore_dup_key, ignore_dup_row y allow_dup_row controlan l o que ocurre cuando se crea una clave o fila duplicada con insert o update . A c ontinuacin se muestra una tabla que indica cundo se deben usar estas opciones de nd ices: Tabla 11-1: Opciones de ndices Tipo de ndice Opciones Agrupado ignore_dup_row | allow_dup_row Agrupado nico ignore_dup_key No agrupado 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 incluy endo la opcin ignore_dup_key con un ndice unique .

El ndice unique puede ser agrupado o no agrupado. Cuando se comienza la introducc in de datos, cada intento de insercin de una clave duplicada se cancela, con un me nsaje 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 a ctivas en ese momento pueden continuar como si la actualizacin con update no hubi ese 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 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 iden tificacin de fila nico, no es necesario preocuparse por las filas duplicadas, ni s iquiera 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 r equisito 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 cla ve 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 dat os. Cuando se introduce una fila duplicada, esta fila se ignora y el comando ins ert en cuestin se cancela, con un mensaje de error informativo. Las filas no dupl icadas se insertan de la forma habitual. La opcin ignore_dup_row se aplica slo a las tablas con ndices no nicos: no puede usa r 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 a ctualizacin 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 dup licadas y a los intentos de introduccin de filas duplicadas en una tabla. Tabla 11-2: Opciones de filas duplicadas en ndices Opcin Duplicados existentes Introduccin de duplicados Ninguna opcin definida El comando create index no se ejecuta de forma correcta. El comando de introduccin de filas duplicadas no se ejecuta de forma correcta. allow_dup_row definida El comando se ejecuta de forma correcta.

El comando se ejecuta de forma correcta. ignore_dup_row<Default Para Font> definida Se crea el ndice, pero las filas duplicadas se eliminan; mensaje de error. 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 op cin create index sin ningn efecto sobre su funcionamiento. Si se especifica sorted_data , pero los datos no estn ordenados, aparece un mensa je de error y el comando se aborta. Esta opcin agiliza la creacin de ndices slo para ndices agrupados o ndices no agrupado s 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 seg mento distinto del de las pginas de datos. Por ejemplo: create index titleind on titles(title) on seg1 Omisin de ndices El comando drop index se usa para quitar un ndice de la base de datos. Su sintaxi s es: drop index table_name . index_name [, table_name . index_name ]...

Cuando se ejecuta este comando, SQL Server quita los ndices especificados de la b ase de datos, dejando libre el espacio de almacenamiento. Slo el propietario del ndice puede omitirlo. El permiso drop index no puede transf erirse 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 de l sistema sp_helpindex . A continuacin se muestra un informe sobre la tabla frien ds_etc : sp_helpindex friends_etc index_name index_description index_keys -------------- --------------------------------------- nmind clustered located on default pname, sname postalcode_ind nonclustered located on default pos

talcode postalcodeind nonclustered located on default postalcode affected, return status = 0) sp_help tambin informa sobre los ndices de una tabla.

(3 rows

Actualizacin de estadsticas sobre los ndices El comando update statistics ayuda a SQL Server a tomar las mejores decisiones s obre qu ndices debe usar cuando procesa una consulta, proporcionndole informacin act ualizada sobre la distribucin de los valores clave de los ndices. Este comando deb e utilizarse cuando se han aadido, modificado o eliminado grandes cantidades de d atos de una columna indexada. El permiso para ejecutar el comando update statistics est asignado de forma prede terminada 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 di stribucin 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_he lpindex . 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 index_keys ---------- --------------------------------- auidind clustered, unique au_id aunmind nonclustered au_lname, au_fname (2 rows affe cted) 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. SQ L Server ejecuta update statistics de forma automtica cuando se crea un ndice en l os datos existentes. #endregion #region DEFINICIN DE VALORES PREDETERMINADOS Y REGLAS PARA DATOS #region 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 bas es 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 integri dad de los datos en toda la base de datos. En un sistema de administracin de bases de datos relacionales, todos los elemento s de datos, es decir, cada columna determinada de cada fila concreta, deben cont ener algn valor, incluso aunque ste sea NULL (nulo). Tal como se describe en el Ca ptulo 7, "Creacin de bases de datos y tablas", algunas columnas no aceptan el valo r nulo. En estos casos, es necesario insertar otro valor, ya sea un valor introd ucido 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 in sertar 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 usua rio concreto. Cada vez que un usuario introduce un valor con una instruccin insert o update , S QL Server lo compara con la ltima regla vinculada a la columna en cuestin. Los dat os introducidos antes de la creacin y vinculacin de una regla no se verifican. 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 vincularla s. En este captulo se explica cmo crear valores predeterminados y reglas mediante cre ate 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 p ara llevar a cabo algunas de las mismas tareas. Sin embargo, dichos elementos so n especficos a esa tabla y no pueden vincularse a columnas de otras tablas ni a t ipos de datos definidos por el usuario. Para obtener ms informacin acerca de las r estricciones de integridad, consulte el Captulo 7, "Creacin de bases de datos y ta blas". #endregion #region 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 c olumnas o a todas las columnas de la base de datos que tengan un tipo de datos d efinido por el usuario determinado. Utilice el procedimiento del sistema sp_bind efault para asociar un valor predeterminado a una columna o tipo de datos defini do por el usuario. Quite la asociacin mediante sp_unbindefault . A continuacin se muestran algunos puntos que hay que comprobar al crear y vincula r 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 co mo "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 vinc ula 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 us uario nicamente para la columna indicada. El valor predeterminado del tipo de dat os definido por el usuario se vincula a todas las dems columnas que tengan ese ti po de datos. Sin embargo, una vez vinculado otro valor predeterminado a una colu

mna 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 predeterminad os y las reglas. Cercirese de que la regla permite el valor predeterminado, ya qu e, de lo contrario, la regla podra eliminarlo. Si una regla permite entradas entre 1 y 100, por ejemplo, y el valor predetermin ado est definido en 0, la regla har que el valor predeterminado se rechace cada ve z que se intente insertar y el resultado ser un error, a no ser que la columna ac epte 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 .] default_name as constant _expression 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 se r nicos para cada usuario. No puede crear dos valores predeterminados con el nomb re phonedflt . Sin embargo, como usuario "invitado", puede crear un valor predet erminado phonedflt aunque dbo. phonedflt ya exista porque los nombres de los pro pietarios los diferencian entre s. A continuacin se indica cmo crear el valor predeterminado "Oakland" para usarlo co n la columna city de la tabla friends_etc (la tabla cuya creacin se trat en el Capt ulo 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 nom bre de ciudad que resulte til para la distribucin demogrfica de las personas que te nga previsto introducir en su tabla personal. Para crear el valor predeterminado : create default citydflt as "Oakland" Despus de as puede usar cualquier constante. Las constantes de caracteres y de fe cha deben incluirse entre comillas; las constantes de tipo monetario, de nmeros e nteros y de punto flotante no las requieren. Los datos binarios deben ir precedi dos de 0x y los datos monetarios, de un smbolo de dlar ($). El valor predeterminad o tiene que ser compatible con el tipo de datos de la columna. No puede usar "ni nguno", 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 em bargo, en una sesin en la que desee introducir mltiples filas con los mismos valor es en una o ms columnas, puede ser conveniente crear un valor predeterminado espe cial 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 colum na o tipo de datos definido por el usuario adecuados con el procedimiento del si stema sp_bindefault . sp_bindefault phonedflt, "authors.phone" El valor predeterminado tendr efecto slo si no hay ninguna entrada en la columna p hone 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 up date con una lista de columnas que no incluya la columna con el valor predetermi nado. El valor predeterminado slo se aplica a las filas nuevas y no cambia de forma ret roactiva las filas existentes. Lgicamente, dicho valor slo tiene efecto cuando no se realiza ninguna entrada. Si el usuario suministra un valor para la columna, a unque 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 pu ntuacin incrustada, es decir, el punto. Note: No es posible vincular un valor predeterminado a un tipo de datos del sist ema, porque el objeto de destino sera demasiado extenso. Tampoco se puede vincula r un valor predeterminado a una columna timestamp , porque SQL Server genera val ores para columnas de este tipo. Es posible vincular un valor predeterminado a l a 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 insert a una fila en una tabla sin especificar un valor para la columna IDENTITY, SQL S erver 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 l as tablas de la base de datos, puede vincular citydflt al tipo de datos con la c ompleta 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 cont inuacin se indica cmo se vinculara citydflt al mismo: sp_bindefault citydflt, citytype El parmetro futureonly puede usarse cuando se vincula un valor predeterminado a u n tipo de datos de usuario. Este parmetro evita que las columnas existentes de es e tipo de datos de usuario hereden el nuevo valor predeterminado. Nunca se utili za cuando se vincula un valor predeterminado a una columna. A continuacin se indi ca cmo crear y vincular el nuevo valor predeterminado "Berkeley" al tipo de datos citytype para su uso slo en las columnas de tabla nuevas. "Oakland" seguir aparec iendo 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 pos tal, puede crear un valor predeterminado para ahorrar tiempo de introduccin de da tos. 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 . objnam

e es el nombre de la tabla y la columna, o del tipo de datos definido por el usu ario, a la que debe vincularse el valor predeterminado. Si el parmetro no tiene e l formato table . column , el sistema supone que se trata de un tipo de datos de finido por el usuario. Todas las columnas de un tipo de datos definido por el usuario especificado qued an asociadas al valor predeterminado indicado, a no ser que: Utilice el tercer parmetro opcional, futureonly , que evita que las columnas exis tentes 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 va lor 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 predeterminad o de una regla de una columna correspondiente al tipo de datos de que se trate d efinido 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 u suario para los que ya existen valores predeterminados: Tabla 12-1: Precedencia de valores predeterminados Valor predeterminado nuevo vi nculado a: Valor predeterminado antiguo vinculado a: Tipo de datos de usuario Column a Tipo de datos de usuario Sustituye al valor predeterminado antiguo. Ningn cambio; valor predeterminado antiguo. Column a Sustituye al valor predeterminado antiguo. Sustituye al valor predeterminado antiguo.

Las columnas existentes del tipo de datos definido por el usuario heredan el nue vo valor predeterminado, a no ser que su valor predeterminado se haya cambiado p reviamente o que el valor del tercer parmetro opcional sea futureonly . Las colum nas nuevas del tipo de datos definido por el usuario siempre heredan el valor pr edeterminado. Por ejemplo, supongamos que se crea una tabla llamada foes con una columna llama da city del tipo citytype , que es un tipo de datos definido por el usuario. Ini cialmente, el tipo de datos definido por el usuario citytype no tiene ningn valor predeterminado. Tras crearse un valor predeterminado llamado citydflt , se vinc ula a la columna foes.city . Luego se vincula otro valor predeterminado, newcity dflt , al tipo de datos definido por el usuario citytype . Aunque foes.city es u na 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 durant e el mismo lote. sp_bindefault no puede estar en el mismo lote que las instrucci ones insert que ejecutan el valor predeterminado.

Desvinculacin de valores predeterminados Desvincular un valor predeterminado significa desconectarlo de una columna o tip o de datos definido por el usuario en particular. Un valor predeterminado desvin culado 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 l a vinculacin entre un valor predeterminado y una columna o tipo de datos. A continuacin se indica cmo desvincular el valor predeterminado actual de la colum na 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 colum na city porque no est conectado a la misma. Para desvincular un valor predeterminado del tipo de datos definido por el usuar io 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 s upone que se trata de un tipo de datos definido por el usuario. Cuando se desvin cula un valor predeterminado de un tipo de datos definido por el usuario, el val or 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 exis tentes 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 usu ario se haya cambiado y su valor actual sea distinto del valor predeterminado qu e se est desvinculando. A continuacin se muestra un ejemplo que ilustra el caso anterior: Cree un tipo de datos definido por el usuario llamado nm . Use nm en las instrucciones create correspondientes a las tablas friends_etc y e nemies para crear las columnas friends_etc . pname , friends_etc . sname y enemi es . nickname. Cree un valor predeterminado llamado nmdflt y vinclelo a nm . Cambie el valor predeterminado de enemies.nickname creando un nuevo valor predet erminado 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 ca mbiado, el valor predeterminado de esa columna no se desvincula, aunque est defin ido como del tipo nm . #endregion #region 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 l as columnas y tipos de datos definidos por el usuario antes de poder omitirlo. S

i trata de omitir un valor predeterminado que todava est vinculado, SQL Server mue stra 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. #endregion #region Efecto de los valores predeterminados sobre los valores nulos 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 inser ta una fila y no introduce datos en dicha columna. Cuando se omite un valor predeterminado de una columna NULL, SQL Server NULL en esa posicin cada vez que el usuario aade filas sin introducir ara esa columna. Cuando se omite un valor predeterminado de una columna , el programa muestra un mensaje de error cada vez que el usuario aade introduce de forma explcita ningn valor para esa columna. inserta ningn valor p NOT NULL filas y no

La siguiente tabla ilustra la relacin entre la existencia de un valor predetermin ado 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 Sin entrada Sin valor predeterminado Sin entrada, Con valor predeterminado Se introduce null Sin valor predeterminado Se introduce null Valor predeterminado NULL Nulo Valor predeterminado Nulo Nulo NOT NULL Error Valor predeterminado Error Error #endregion #region 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_bin drule . 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 colum na 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 . S in embargo, dos usuarios distintos pueden crear una regla llamada socsecrule , p orque sus respectivos nombres de usuario las diferencian entre s. A continuacin se indica cmo crear una regla que permite cinco nmeros pub_id distint os 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 valo r 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 p ara el argumento, pero el primer carcter debe ser "@". El uso del nombre de la co lumna 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 wher e 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 po r el usuario sean compatibles con una "imagen" concreta. En este caso, cada valo r introducido en la columna deber comenzar por los dgitos "415", seguidos de siete o ms caracteres: 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 vinc ular 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 si stema 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 d e 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 , im age o timestamp . Vinculacin de reglas a columnas Para vincular una regla a una columna, utilice el procedimiento del sistema sp_b indrule con el nombre de la regla, y el nombre de tabla y de columna entre comil las. 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 t res 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 No se puede vincular una regla a e datos definido por el usuario. nido por el usuario llamado p# , datos definidos por el usuario un tipo de datos del sistema, pero s a un tipo d Para vincular phonerule a un tipo de datos defi escriba:

sp_bindrule phonerule, "p#" Precedencia de las reglas Las reglas vinculadas a las columnas siempre tienen precedencia sobre las vincul adas 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 usuari o de esa 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 cuan do se intenta insertar un valor en una columna de base de datos del tipo de dato s definido por el usuario, o actualizar dicha columna. Dado que las reglas no ve rifican 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 c olumna 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 Columna Tipo de datos de usuario Sustituye a la regla antigua.

Sin cambios. Columna 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 e jemplo, 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. P ara evitar la introduccin accidental de una cantidad fuera de este margen, cree u na regla como la siguiente (la definicin de regla permite una entrada de $0.00 pa ra 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 verifi can mediante una instruccin insert o update . Desvinculacin de reglas Desvincular una regla significa desconectarla de una columna o tipo de datos def inido por el usuario en particular. La definicin de una regla desvinculada perman ece 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 un a 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] 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 desv incula una regla de un tipo de datos definido por el usuario, la regla se desvin cula de todas las columnas de ese tipo, a no ser que: Indique el segundo parmetro opcional futureonly , que evita que las columnas exis tentes 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 mod ificado de modo que su valor actual sea distinto de la regla que se est desvincul

ando. #endregion #region 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 us uario antes de poder omitirse. Si intenta omitir una regla que an est vinculada, S QL Server muestra un mensaje de error y el comando drop rule no se ejecuta corre ctamente. 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 a nteriormente regidas por sta se introducirn sin restricciones. Los datos existente s no se vern afectados de ningn modo. Slo su propietario puede omitir una regla. #endregion #region Obtencin de informacin sobre valores predeterminados y reglas El procedimiento del sistema sp_help , cuando se usa con un nombre de tabla, mue stra las reglas y los valores predeterminados vinculados a las columnas. Este ej emplo muestra informacin sobre la tabla authors de la base de datos pubs , inclui das las reglas y los valores predeterminados: sp_help authors El procedimiento del sistema sp_help tambin informa sobre una regla vinculada a u n tipo de datos definido por el usuario. Para verificar si una regla est vinculad a 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. #endregion #endregion #region USO DE LOTES Y LENGUAJE DE CONTROL DE FLUJO #region Definicin de lote y Un lote de instrucciones SQL ca a SQL Server que contine La seal de fin de lote para n una lnea. de lenguaje de control de flujo se termina mediante una seal de fin de lote que indi y ejecute las instrucciones. la utilidad SQL autnoma isql es la palabra "go" sola e

El lenguaje de control de flujo se puede utilizar en instrucciones sencillas, lo tes, procedimientos almacenados y disparadores. #endregion #region Reglas asociadas a lotes

Existen reglas que controlan qu instrucciones SQL pueden combinarse en un solo lo te. Estas reglas de lotes incluyen lo siguiente: Algunos comandos de base de datos no pueden combinarse con otras instrucciones e n 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 inclu yen: 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 utilizars e 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 re ferencia 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 opcion es de set no se aplicarn a las consultas de dicho lote. #endregion #region USO DEL LENGUAJE DE CONTROL DE FLUJO El control de flujo y las palabras clave relacionadas y sus funciones son: if Define una ejecucin condicional. ...else Define una ejecucin alternativa cuando la condicin if es falsa. begin Comienzo de un bloque de instrucciones. ...end Final de un bloque de instrucciones. while Repite la ejecucin de instrucciones mientras la condicin es verdad era. break Sale del final del siguiente bucle while ms exterior. ...continue Reinicio del bucle while . declare Declara variables locales. goto label Va a un rtulo ( label:) , una posicin en un bloque de instrucciones. return Sale de forma incondicional. waitfor Define el retardo para la ejecucin del comando. print Imprime un mensaje definido por el usuario o una variable local en la pantalla del usuario. raiserror 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 . /* comentario */ Inserta un comentario en cualquier punto de una instruccin SQL. #region if ... else 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 c

olumna y constantes conectados por operadores aritmticos o basados en bits, o una subconsulta, siempre que sta devuelva un solo valor. Si la expresin booleana cont iene una instruccin select , debe incluirse entre parntesis y devolver un solo val or. A continuacin se muestra un ejemplo del uso de if sola: if exists (select postalcode from authors where postalcode = '94705') print "Be rkeley 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 dev uelve 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. A continuacin se muestra un ejemplo con if y else que verifica la presencia de ob jetos 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 nme ros de ID. if (select max(id) from sysobjects) < 50 print "There are no user-created objec ts in this database." else select name, type, id from sysobjects where id > 50 and type = "U" Las estructuras if...else se utilizan frecuentemente en procedimientos almacenad os 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 inst ruccin 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 qu e pueden anidarse vara con la complejidad de las instrucciones select (u otras es tructuras de lenguaje) que se incluyan con cada estructura if...else . #endregion #region begin...end Las palabras clave begin y end se utilizan para englobar una serie de instruccio nes 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 set pr ice = 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 se gunda instruccin se ejecutara independientemente de la primera. Los bloques begin ... end pueden anidarse dentro de otros bloques begin...end . #endregion #region while y break...continue while se utiliza para definir una condicin para la ejecucin repetida de una instru

ccin o un bloque de instrucciones. Las instrucciones se ejecutan reiteradamente s iempre 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 pre cio 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 = pri ce * 2 end (0 rows affected) title_id price ------------ PC1035 22.95 PS1372 21.59 TC3218 20.95 (3 rows affected) (18 rows affec ted) (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 b ucle while . break permite salir del bucle while . Todas las instrucciones que a parecen despus de la palabra clave end , que marca el final del bucle, se ejecuta n. continue hace que el bucle while se inicie de nuevo, omitiendo cualquier inst ruccin despus de continue menos dentro del bucle. break y continue se activan frec uentemente mediante una prueba if . La sintaxis de break...continue es: while boolean expression begin statement [ stateme nt ]... break [ statement ]... continue [ state ment ]... end A continuacin se muestra un ejemplo con while , break , continue e if que inviert e el aumento producido en los ejemplos anteriores. Siempre que el precio promedi o permanezca por encima de $20, todos los precios se reducen a la mitad. Despus s e 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 inst ruccin 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 . #endregion #region declare y variables locales Una variable es una entidad a la que se asigna un valor. Este valor puede cambia r durante el lote o el procedimiento almacenado donde se utiliza la variable. SQ

L Server tiene dos tipos de variables: locales y globales. Las variables locales estn definidas por el usuario, mientras que las variables globales las suministr a 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 vari ables 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 alma cenado como contadores de bucles while o bloques if...else . Cuando se usan en p rocedimientos almacenados, las variables locales se declaran para su uso automtic o no interactivo por parte del procedimiento cuando ste se ejecuta. Los nombres de las variables locales deben empezar con el smbolo "@" y despus segu ir 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 sis tema distinto de text , image o sysname . Las variables locales se declaran con esta sintaxis: declare @ variable_name datatype [, @ variable_name datatype ] ... Cuando se declara una variable, tiene el valor NULL. Los valores se asignan a la s variables locales con una instruccin select . A continuacin se muestra la sintax is: select @ variable_name = { expression | ( select_statement ) } [, @ v ariable = { expression | ( select_statement ) } ...] [from clause ] [where clause ] [group by clause ] [having clause ] [order by cl ause ] [compute clause ] Las variables locales deben declararse y utilizarse en el mismo lote o procedimi ento. La instruccin select que asigna un valor a la variable local generalmente devuelv e un solo valor. Una subconsulta que asigna un valor a la variable local debe de volver 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 title s), @pcount = (select count(*) from publishers) select @tcount, @pcount Las instrucciones select que utilizan expresiones que devuelven ms de un valor as ignan 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 pue de utilizarse para devolver datos al usuario. La primera instruccin select del si guiente ejemplo asigna el precio mximo a la variable local @ veryhigh ; la segund a instruccin select es necesaria para mostrar el valor: declare @veryhigh money select @veryhigh = max(price) from titles sele ct @veryhigh 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 varia ble 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 r ow affected) Observe que la instruccin de asignacin indica el nmero de filas afectadas (devuelta s) 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 espe cial 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 nu los y expresiones con valores nulos usando operadores de comparacin diferentes (u na expresin puede ser una variable, un literal, o una combinacin de variables, lit erales 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 FALSE Comparando c olumn_value y e xpression TRUE FALSE Comparando e xpression y c olumn_value TRUE FALSE Comparando e xpression y e xpression TRUE FALSE

Por ejemplo, esta prueba: declare @v int, @i int if @v = @i select "null = null, true" if @v > @i selec t "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 declare y variables locales Las variables globales son variables predefinidas suministradas por el sistema. Se distinguen de las variables locales por tener dos smbolos "@" precediendo a su s nombres, por ejemplo, @@ error . Estas son las variables globales: Tabla 13-3: Variables globales de SQL Server Variable Contenido @@char_convert Contiene 0 si la conversin del juego de caracteres no est en efecto. Contiene 1 s i la conversin del juego de caracteres est en efecto. @@client_csname 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, co ntiene el nombre del ltimo juego de caracteres utilizado. @@client_csid Contiene la ID del juego de caracteres del cliente. Se define como -1 si el jue go de caracteres del cliente nunca fue inicializado; en caso contrario, contiene la id de syscharsets del ltimo juego de caracteres usado. @@connections Contiene el nmero de logins o intentos de login. @@cpu_busy Contiene la cantidad de tiempo, en pulsos, que la CPU emple en realizar el traba jo de SQL Server desde la ltima vez que se inici. @@error 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 @@err or 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. @@identity 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 column a 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 conse rva el ltimo valor insertado en una columna IDENTITY, aunque la instruccin que la haya insertado no se consigne. @@idle

Contiene la cantidad de tiempo, en pulsos, que SQL Server estuvo inactivo. @@io_busy Contiene la cantidad de tiempo, en pulsos, que SQL Server emple para efectuar op eraciones de entrada y salida. @@isolation Contiene el nivel de aislamiento actual del programa Transact-SQL. @@isolation toma el valor del nivel activo (1 o 3). @@langid Define la ID de idioma local del idioma en uso, segn el valor de syslanguages.la ngid . @@language Define el nombre del idioma en uso, segn el valor de syslanguages.name . @@maxcharlen Contiene la longitud mxima, en bytes, de los caracteres multibyte del juego de c aracteres predeterminado. @@max_connections Contiene el nmero mximo de conexiones simultneas que se pueden realizar con SQL Se rver en este entorno informtico. El usuario puede configurar SQL Server para cual quier nmero de conexiones menor o igual que el valor de @@max_connections con sp_ configure " number of user connections ". @@ncharsize Contiene la longitud media, en bytes, de un carcter nacional. @@nestlevel Contiene el nivel de anidacin de la ejecucin actual, inicialmente cero. Cada vez que un procedimiento almacenado o disparador llama a otro procedimiento almacena do o disparador, se incrementa el nivel de anidacin. Si se supera el mximo de 16, la transaccin se aborta. @@pack_received Contiene el nmero de paquetes de entrada ledos por SQL Server. @@pack_sent Contiene el nmero de paquetes de salida escritos por SQL Server. @@packet_errors Contiene el nmero de errores generados mientras SQL Server enviaba y reciba paque tes. @@procid Contiene la ID de procedimiento almacenado del procedimiento en ejecucin. @@rowcount Contiene el nmero de filas afectadas por la ltima consulta. @@rowcount es definid a como cero por cualquier comando que no devuelve filas, como una instruccin if . @@servername Contiene el nombre de este SQL Server. @@spid Contiene el nmero de la ID de proceso de servidor del proceso actual.

@@sqlstatus Contiene informacin de estado resultante de la ltima instruccin fetch . @@textcolid Contiene la ID de columna de la columna referenciada por @@ textptr . El tipo d e datos de esta variable es tinyint . @@textdbid 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 s mallint. @@textobjid Contiene la ID de objeto de un objeto que contiene la columna referenciada por @@ textptr . El tipo de datos de esta variable es int @@textptr Contiene el puntero de texto de la ltima columna text o image insertada o actual izada por un proceso. El tipo de datos de esta variable es binary(16) (no confun da esta variable con la funcin textptr ). @@textsize Contiene el lmite del nmero de bytes de datos text o image devueltos por una inst ruccin select . El lmite predeterminado es 32K bytes para isql ; el valor predeter minado depende del software del cliente. Puede cambiarse el lmite de una sesin med iante set textsize . @@textts Contiene la marca horaria de texto de la columna referenciada por @@ textptr . El tipo de datos de esta variable es varbinary(8) . @@thresh_hysteresis Contiene la disminucin de espacio libre necesaria para activar un umbral. Esta c antidad, tambin conocida como valor de histresis, se mide en pginas de base de dato s de 2K. Determina la proximidad a la que se pueden colocar los umbrales en un s egmento de base de datos. @@timeticks Contiene el nmero de microsegundos por pulso. La cantidad de tiempo por pulso es dependiente de la mquina. @@total_errors Contiene el nmero de errores generados mientras SQL Server realizaba una lectura o escritura. @@total_read Contiene el nmero de lecturas de disco realizadas por SQL Server desde la ltima v ez que se inici. @@total_write Contiene el nmero de escrituras de disco realizadas por SQL Server desde la ltima vez que se inici. @@tranchained Contiene el modo de transaccin actual del programa Transact-SQL. @@tranchained d evuelve 0 para no encadenadas o 1 para encadenadas. @@trancount Contiene el nmero de transacciones activas del usuario actual.

@@transtate 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 . @@version 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 informa cin completa sobre los procedimientos del sistema, consulte el Manual de Referenc ia de SQL Server . Si un usuario declara una variable local que tiene el mismo nombre que una varia ble 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 seg uido 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 = count = @count + 1 while @count <=4 Como en este ejemplo, goto generalmente se una prueba if , o alguna otra condicin, a oto y el rtulo. #endregion #region 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 retur n no se ejecutan. La sintaxis es simplemente: return [ int_expression ] A continuacin se muestra un ejemplo de un procedimiento almacenado que utiliza re turn , 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..sy slogins where master..syslogins.name = @nm and sysobjects.uid = master ..syslogins.suid and sysobjects.type = "R" end 1 restart: print "yes" select @ goto restart hace dependiente de un bucle while o fin de evitar un bucle infinito entre g

Si no se proporciona ningn nombre de usuario como parmetro cuando se llama a findr ules , 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 d e procedimientos almacenados". #endregion #region print La palabra clave print , utilizada en el ejemplo anterior, muestra un mensaje de finido por el usuario o el contenido de una variable local en la pantalla del us uario. La variable local debe declararse dentro del mismo lote o procedimiento e n el que se utiliza. El mensaje en s puede tener hasta 255 bytes de longitud. La sintaxis es: print { format_string le } [, arg_list ] He aqu otro ejemplo: | @ local_variable | @@ global _ variab

if exists (select postalcode from authors where postalcode = '94705') pr int "Berkeley author" A continuacin se indica cmo utilizar print para mostrar el contenido de una variab le 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 impri mirse. Las cadenas de formato pueden contener hasta 20 marcadores de lugar nicos colocados en cualquier orden. Estos marcadores se sustituyen por el contenido fo rmateado de cualquier argumento que aparezca despus de format_string cuando el te xto del mensaje se enva al cliente. Para permitir la reordenacin de los argumentos cuando las cadenas de formato se t raducen a un idioma con una estructura gramatical diferente, los marcadores de l ugar se numeran. El marcador de lugar de un argumento aparece en este formato: % 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 lug ar 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 de l 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 ord en 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 l a reordenacin de los argumentos que, en ocasiones, es necesaria en el formato tra

ducido. 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 n umrico. Por ejemplo, no se pueden tener los marcadores de lugar 1 y 3 en una cade na 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. U n argumento puede ser cualquier tipo de datos excepto text o image ; se conviert e al tipo de datos char antes de incluirse en el mensaje final. Si no se proporc iona ninguna lista de argumentos, la cadena de formato debe ser el mensaje que h a 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. #endregion #region raiserror raiserror muestra un error definido por el usuario o un mensaje de variable loca l 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 varia ble 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 }] [, a rg_list ] [ extended_value = extended_value [{, extended_value = extended_value }...]] El nmero de error ( error_number ) se sita en la variable global @@ error , que al macena 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 usuari o 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 p rocedimientos 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 byt es. Las variables locales utilizadas para los mensajes de raiserror deben ser ch ar o varchar . La cadena de formato o la variable son opcionales. Si no se inclu ye ninguna, SQL Server usa el mensaje correspondiente al error_number de sysuser messages 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 aplic acin Open Client(TM) (cuando se incluyen valores extendidos con raiserror ). Para obtener ms informacin sobre los datos de error extendidos, consulte la documentac in de Open Cliente o raiserror en el Manual de Referencia de SQL Server . Use raiserror en lugar de print cuando desee almacenar un nmero de error en @@ er ror . Por ejemplo, a continuacin se indica cmo podra utilizar raiserror en el proce dimiento 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. #endregion #region 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 s istema sp_addmessage para crear un conjunto de mensajes. El ejemplo que aparece a continuacin utiliza sp_addmessage , sp_getmessage y prin t para instalar un mensaje en sysusermessages en ingls y alemn, recuperarlo para s u uso en un procedimiento almacenado definido por el usuario e imprimirlo. /* ** Instalar mensajes ** Primero, en ingls (langid = NULL) */ set language us_english go sp_addmes sage 25001, "There is already a remote user named '%1!' for remote server '%2 !'." go /* Luego, en alemn*/ sp_addmessage 25001, "Remotebenutzerna me '%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 varch ar(40) /* ** verificar que no hay ningn ** @remotenam e para el @remoteserver. */ if exists (select * f rom master.dbo.sysremotelogins l, master.dbo.sysservers s where l.remoteserverid = s.srvid and s.srvname = @remot eserver and l.remoteusername = @remotename) begin exec sp_getmessage 25001, @msg output select @arg1=isnull( @remotename,"null") print @msg, @arg1, @remoteserver r eturn (1) end return(0) go #endregion #region 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 inst rucciones, un procedimiento almacenado o una transaccin. A continuacin se muestra la sintaxis: waitfor {delay " time " | time " time " | errorexit | processexit | mirror exit} La palabra clave delay indica a SQL Server que espere hasta que haya transcurrid o el tiempo especificado. time indica a SQL Server que espere hasta la hora espe cificada, proporcionada en uno de los formatos aceptables para datos datetime . Sin embargo, no es posible especificar fechas, no se permite el componente de fe cha 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 f ormato "hh:mm:ss". Por ejemplo, waitfor time "16:23" indica a SQL Server que esp ere hasta las 4:23 pm. La instruccin waitfor delay "01:30" indica a SQL Server qu e espere una hora y 30 minutos. Para obtener una revisin de los formatos aceptabl es para los valores de time , consulte el Captulo 8, "Adicin, modificacin y elimina cin de datos". errorexit indica a SQL Server que espere hasta que un proceso termine de forma a normal. processexit espera hasta que un proceso termina por cualquier razn. mirro rexit espera hasta que falla una lectura o una escritura de un dispositivo dupli cado. 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 otr o modo seran ocupados por un proceso infectado. Para averiguar cul es el proceso i nfectado, verifique la tabla sysprocesses con el procedimiento del sistema sp_wh o . 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 almacenad o llamado sendmessage , que inserta un mensaje en una de las tablas de Judy, inf ormndole que ahora existe un nuevo movimiento en la tabla chess . He aqu el ejempl o: begin waitfor time "14:20" insert chess(next_move) values('Q-KR5') exec ute 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 ha sta que llegue la hora o tenga lugar el evento especificado. #endregion #region Comentarios La notacin del comentario se utiliza para anexar comentarios a instrucciones, lot es y procedimientos almacenados. Un comentario tiene el siguiente aspecto: /* texto del comentario */ Los comentarios no tienen una longitud mxima y pueden insertarse en cualquier lug ar, 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 inv ertida y un asterisco, y finalice con un asterisco y una barra invertida. Todo l o que se encuentra entre "/*" y "*/" se trata como parte del comentario. Los com entarios 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 comentar io finaliza con "*/" como siempre. A continuacin se muestra el aspecto que tiene: select * from titles /* Un comentario incluido aqu puede explicar las ** reg las relacionadas con el uso de un asterisco ** como una abreviatura en la lis ta 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 ind ica ningn ** parmetro*/ print "You must give a user name" lse 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 #endregion #endregion #endregion #region USO DE PROCEDIMIENTOS ALMACENADOS

#region Definicin de procedimiento almacenado Los procedimientos almacenados son grupos formados por instrucciones SQL y el le nguaje de control de flujo. Cuando se ejecuta un procedimiento, se prepara un pl an 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 pot encia, eficacia y flexibilidad de SQL. Los procedimientos compilados mejoran la ejecucin de las instrucciones y lotes de SQL de forma dramtica. Adems, los procedim ientos almacenados pueden ejecutarse en otros SQL Server si el servidor del usua rio y el remoto estn configurados para permitir logins remotos. Escriba disparado res en su SQL Server local que ejecuten procedimientos en un servidor remoto sie mpre que determinados eventos, como las eliminaciones, actualizaciones o inserci ones, tengan lugar a nivel local. Los procedimientos almacenados se diferencian de las instrucciones SQL ordinaria s y de los lotes de instrucciones SQL en que estn precompilados. La primera vez q ue se ejecuta un procedimiento, el procesador de consultas de SQL Serverlo anali za 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 almacenad o. Puesto que ya se ha realizado la mayor parte del trabajo de procesamiento de consultas, los procedimientos almacenados se ejecutan casi de forma instantnea. SQL Server proporciona una gran variedad de procedimientos almacenados como herr amientas adecuadas para el usuario. Estos procedimientos almacenados se llaman p rocedimientos 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 procedi miento almacenado solo, siempre que sea la primera palabra de una instruccin o lo te. Ejemplos de creacin y uso de procedimientos almacenados La sintaxis para la creacin de un procedimiento almacenado sencillo, sin funcione s 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 i nstrucciones 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 pro

cedimiento, siempre que se enve a SQL Server solo o sea la primera instruccin de u n 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 proporci onar el nombre del servidor. La sintaxis completa de una llamada de procedimient o remoto es: execute server_name .[ database_name ].[ owner ]. procedure_name Los siguientes ejemplos ejecutan el procedimiento namelist en la base de datos p ubs2 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 usu ario. El nombre de la base de datos es opcional slo si el procedimiento almacenado se e ncuentra en la base de datos predeterminada del usuario. El nombre del propietar io es opcional slo si el propietario de la base de datos ( " dbo " ) es el propie tario 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 procedure showall as select count(*) from sysusers select count(*) f rom sysobjects select count(*) from syscolumns Cuando se ejecuta el procedimiento, los resultados de cada comando se muestran e n el orden en que la instruccin aparece en el procedimiento. showall -----------5 (1 row affected) -----------88 (1 row affected) -----------349 (1 row affected, return status = 0) Cuando el comando create procedure se ejecuta de forma correcta, el nombre del p rocedimiento se almacena en sysobjects y su texto en syscomments . Se puede mostrar el texto de un procedimiento con el procedimiento del sistema s p_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 au nque no tenga permisos en las tablas o vistas referenciadas en el mismo ni permi so 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 p ara acceder a sus tablas pueden volver a optimizarse recompilndolos con el proced

imiento 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 Refe rencia de SQL Server . #endregion #region Creacin y ejecucin de procedimientos almacenados La sintaxis completa de create procedure es: create procedure datatype [= default] ] [output]]...[)]] Slo se puede crear un [owner.]procedure_name[;number] [[ (]@parameter_name [output] [, @parameter_name datatype [= default [with recompile] as sql_statements procedimiento en la base de datos actual.

El permiso para emitir create procedure est asignado de forma predeterminada al p ropietario 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 .] owner .] proce dure_name [; number ] [[@ parameter_name =] value | [@ parame ter_name =] @ variable [output] [,[@ parameter_name =] value | [@ parameter_name =] @ variable [output]...]] [with recompile] Note: Las llamadas de procedimientos remotos no se consideran parte de una trans accin. Si ejecuta una llamada de procedimientos remotos despus de begin transactio n y luego usa rollback transaction , los cambios realizados por la llamada en lo s datos remotos no se revierten. El diseador del procedimiento almacenado debe as egurarse de que se comprueban todas las condiciones que puedan originar una reve rsin 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 u no 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 proc edure al ejecutarse el procedimiento. Los nombres de los parmetros deben estar precedidos del smbolo "@" y ajustarse a l as reglas para identificadores. Es necesario asignarles un tipo de datos del sis tema 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 l os 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 sele ct au_lname, au_fname, title, pub_name from authors, titles, publishers, title author where au_fname = @firstname and au_lname = @lastname and authors.au _id = titleauthor.au_id and titles.title_id = titleauthor.title_id and title s.pub_id = publishers.pub_id

Ahora ejecute au_info : au_info Ringer, Anne au_lname au_fname title ----------- ---------- Ringer pub_name -------- -------- ---------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 n ombre 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 El ltimo formato de sintaxis, sin exec ni execute , es aceptable siempre que la i nstruccin 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 e specificarlos en cualquier orden. En caso contrario, debe proporcionar los parmet ros en el orden de su instruccin create procedure . Si suministra un valor con el formato "@ parameter = value ", todos los parmetros subsiguientes han de suminis trarse de este modo. Parmetros predeterminados Se puede asignar un valor predeterminado al parmetro de la instruccin create proce dure . 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 au tores que han escrito un libro publicado por el editor introducido como parmetro. Si no se proporciona ningn nombre de editor, el procedimiento muestra los autore s publicados por Algodata Infosystems. create proc pub_info @pubname varchar(40) = "Algodata Infosystems" as sel ect au_lname, au_fname, pub_name from authors a, publishers p, titles t, title author ta where @pubname = p.pub_name and a.au_id = ta.au_id and t.title_i d = ta.title_id and t.pub_id = p.pub_id Tenga en cuenta que si el valor predeterminado es una cadena de caracteres que c ontiene espacios en blanco o signos de puntuacin incrustados, es necesario inclui rlo entre comillas simples o dobles. Cuando ejecuta pub_info , puede proporcionar cualquier nombre de editor como val or del parmetro. Si no suministra ningn parmetro, SQL Server utiliza el predetermin ado, Algodata Infosystems.

exec pub_info au_lname au_fname pub_name ------------- ------------ -------------------- Green Marjorie Algodata Infosystems Bennet Abraham Algodata Info systems O'Leary Michael Algodata Infosyste ms MacFeather Stearns Algodata Infosystems Straight Dick Algodata Infosystems Carson Cheryl Algodata Infosystems Dull Ann Algodata Infosystems Hunter Sheryl Algodata Infosystems Loc ksley Chastity Algodata Infosystems (9 rows a ffected, return status = 0) En este procedimiento, showind2 , se asigna "titles" como valor predeterminado d el parmetro @ table : create proc showind2 @table varchar(30) = titles as select table_name = sys objects.name, index_name = sysindexes.name, index_id = indid from sysind exes, sysobjects where sysobjects.name = @table and sysobjects.id = sysindex es.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 l a tabla authors : 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 predetermin ado, 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 most rar 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 n ulo. 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 = sysinde xes.id Si el usuario no proporciona ningn parmetro, SQL Server imprime el mensaje del pro cedimiento en la pantalla. Para otros ejemplos de definicin del valor predeterminado como NULL, examine el t exto de los procedimientos del sistema utilizando sp_helptext . Caracteres comodn en el parmetro predeterminado El valor predeterminado puede incluir los caracteres comodn (%, _, [] y [^]) si e

l procedimiento utiliza el parmetro con la palabra clave like . Por ejemplo, showind puede modificarse para mostrar informacin sobre las tablas d el sistema si el usuario no proporciona ningn parmetro, como se muestra a continua cin: create procedure showind4 @table varchar(30)="sys%" as select table_name = sysobjects.name, index_name = sysindexes.name, index_id = indid from sysi ndexes, sysobjects where sysobjects.name like @table and sysobjects.id = sys indexes.id Uso de ms de un parmetro A continuacin se muestra una variante del procedimiento almacenado au_info que ti ene valores predeterminados con caracteres comodn para ambos parmetros: create proc au_info2 @lastname varchar(30) = "D%", @firstname varchar(18) = "%" as select au_lname, au_fname, title, pub_name from authors, titles, pub lishers, titleauthor where au_fname like @firstname and au_lname like @lastn ame 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 apellid os comienzan por "D": au_info2 au_lname au_fname title pub_name -------- ------- ------------------------ ------------- Dull Ann Secrets of Silicon Valley Algodata Infosystems DeFrance Michel The Gourmet Microwave Binnet & H ardley (2 rows affected) Si hay valores predeterminados disponibles para parmetros, stos pueden omitirse en la ejecucin, comenzando por el ltimo parmetro. No puede saltarse un parmetro a meno s que NULL sea su valor predeterminado suministrado. Note: Si proporciona los parmetros en el formato " @parameter = value ", puede su ministrarlos 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 predete rminados para dos parmetros, puede buscar los libros y editores de todos los auto res cuyo apellido es "Ringer", de la siguiente manera: au_info2 Ringer au_lname au_fname title Pub_name -------- --------------------------------------- Ringer Anne The Gourmet Mic rowave Binnet & Hardley Ringer Anne Is Anger the Enemy? N ew Age Books Ringer Albert Is Anger the Enemy? New Age Books Ringer Albert Life Without Fear New Age Books (4 rows affected) Grupos de procedimientos El punto y coma (;) y el nmero entero opcionales despus del nombre del procedimien to en las instrucciones create procedure y execute permiten agrupar los procedim ientos que tienen el mismo nombre para que puedan omitirse juntos mediante un so lo 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 with recompile en create procedure En la instruccin create procedure , la clusula opcional with recompile aparece jus to antes de las instrucciones SQL. Esto indica a SQL Server que no guarde ningn p lan 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. G eneralmente, este plan de ejecucin es correcto. 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 pr oponga un plan de ejecucin distinto del que cre la primera vez que se ejecut el pro cedimiento. 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 infor macin. with recompile en En la instruccin lquier parmetro. o se utiliza para execute execute , la clusula opcional with recompile aparece despus de cua Esto indica a SQL Server que compile un plan nuevo. El plan nuev ejecuciones subsiguientes.

Use with recompile cuando ejecute un procedimiento si los datos han sufrido un g ran cambio o si el parmetro que proporciona es atpico, es decir, si tiene alguna r azn 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, a unque use la opcin with recompile de execute , no toma ninguna columna nueva aadid a 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 l lamado inicia la ejecucin y disminuye cuando el procedimiento o disparador llamad o finaliza la ejecucin. Si se supera el mximo de 16 niveles de anidacin, el procedi miento 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, pe ro la tabla temporal slo existe mientras dura el procedimiento almacenado que la crea. Cuando el procedimiento finaliza, SQL Server omite la tabla temporal de fo rma 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:

Cree la tabla temporal que precisa con una instruccin create table o una select i nto . Por ejemplo: create table #tempstores (stor_id char(4), amount money) Cree los procedimientos que accedan a la tabla temporal (pero no el que la gener a). create procedure inv_amounts nt) from #tempstores Omita la tabla temporal: as select stor_id, "Total Due" =sum(amou group by stor_id

drop table #tempstores Cree el procedimiento que genera la tabla y llama a los procedimientos creados e n el paso 2: create procedure inv_proc as create table #tempstores (stor_id char(4), amou nt money) insert #tempstores select stor_id, sum(qty*(100-discount)/100*price) from s alesdetail, 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 te mpdb..tablename... desde dentro de un procedimiento almacenado. Estas tablas no desaparecen cuando finaliza el procedimiento, de modo que es posible hacer refer encia a ellas mediante procedimientos independientes. Siga los pasos descritos a nteriormente 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 cualqui er procedimiento en el SQL Server remoto con slo usar el nombre del servidor como parte del identificador. Por ejemplo, para ejecutar un procedimiento llamado re moteproc en un servidor denominado GATEWAY: exec gateway.remotedb.dbo.remoteproc Consulte la Gua de Administracin del Sistema para obtener informacin sobre cmo confi gurar 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 siguiente s, puede utilizarse para capturar y transmitir mensajes de informacin sobre el es tado de ejecucin de los procedimientos. Warning! Las llamadas de procedimientos remotos no se consideran parte de una tr ansaccin. 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. #endregion #region 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 va lor puede almacenarse en una variable cuando se llama a un procedimiento y utili zarse en futuras instrucciones Transact-SQL. Los valores del estado de retorno d efinidos 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 e scala.

Otra forma en la que los procedimientos almacenados pueden devolver informacin al solicitante es mediante los parmetros de retorno. Los parmetros designados como p armetros de retorno en las instrucciones create procedure y execute informan sobr e los valores de parmetro al solicitante. Despus el solicitante puede utilizar ins trucciones condicionales para verificar el valor devuelto. El estado de retorno y los parmetros de retorno permiten modularizar los procedim ientos almacenados. Un conjunto de instrucciones SQL usadas por varios procedimi entos almacenados puede crearse como un solo procedimiento que devuelve su estad o de ejecucin o los valores de sus parmetros al procedimiento de llamada. Por ejem plo, muchos de los procedimientos del sistema suministrados por SQL Server ejecu tan un procedimiento que verifica que determinados parmetros son identificadores vlidos. Las llamadas de procedimientos remotos, que son procedimientos almacenados ejecu tados en un SQL Server remoto, tambin devuelven ambos tipos de informacin. Todos l os ejemplos que se muestran ms abajo se podran ejecutar de forma remota si la sint axis de la instruccin execute incluyese el servidor, la base de datos y los nombr es 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 retorno. Los usuarios tambin pueden definir sus propios valores de retorno. A co ntinuacin 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 @ sta tus . Este ejemplo solamente imprime el valor con una instruccin select ; ejemplo s 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 Procedimiento ejecutado sin error -1 Falta objeto -2 Error de tipo de datos -3 Se eligi un proceso como vctima de un bloqueo insoluble -4 Error de permiso -5 Error de sintaxis

-6 Errores de usuario diversos -7 Error de recursos, como espacio insuficiente -8 Problema interno no fatal -9 Se ha alcanzado el lmite del sistema -10 Inconsistencia interna fatal -11 Inconsistencia interna fatal -12 La tabla o el ndice estn corrutpos -13 La base de datos est corrupta -14 Error de hardware

Los valores entre -15 y -99 estn reservados para su uso futuro por parte de SQL S erver. Si se produce ms de un error durante la ejecucin, se devolver el estado que tenga e l valor absoluto ms alto. Valores de retorno generados por el usuario El usuario puede generar sus propios valores de retorno en procedimientos almace nados aadiendo un parmetro a la instruccin return . Los nmeros entre 0 y -99 estn res ervados para su uso por parte de SQL Server; pueden utilizarse todos los dems nmer os enteros. El siguiente ejemplo devuelve 1 cuando un libro tiene un contrato vli do y 2 en todos los dems casos: create proc checkcontract @titleid tid as if (select contract from titles w here title_id = @titleid) = 1 return 1 else return 2 El siguiente procedimiento almacenado llama a checkcontract y utiliza clusulas co ndicionales para verificar el estado de retorno: create proc get_au_stat @titleid tid as declare @retvalue int execute @re tvalue = checkcontract @titleid if (@retvalue = 1) print "Contract is va lid" 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 d el sistema o la seguridad, es posible que desee asegurarse de que slo los usuario s con un rol especfico puedan ejecutarlo (consulte la Gua del Usuario de las Carac tersticas de Seguridad para obtener informacin sobre roles). La funcin proc_role pe

rmite 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 alm acenado test_proc para que la persona solicitante sea el administrador del siste ma: 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 ro le" 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 pue de ser un lote SQL u otro procedimiento almacenado. El valor devuelto puede util izarse en instrucciones adicionales en el lote o el procedimiento de llamada. Cu ando 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 ejecu ten las instrucciones subsiguientes del lote. Este procedimiento almacenado realiza la multiplicacin con dos valores enteros. E l 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, de be declarar la variable @result e incluirla en la instruccin execute . La adicin d e la palabra clave output a la instruccin execute muestra el valor de los parmetro s 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 t res valores enteros, no vera los resultados de la multiplicacin. La instruccin sele ct del procedimiento asigna valores, pero no imprime: mathtutor 5, 6, 32 (return status = 0) El valor del parmetro output debe pasarse como una variable, no como una constant e. Este ejemplo declara la variable @ guess para almacenar el valor que debe pas arse a mathtutor para su uso en @ result . SQL Server imprime los parmetros de re torno: 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 "@ paramete r = @ 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 parmet ro que ha de pasarse a mathtutor . Aunque el valor cambiado de @ result se devuelve al solicitante en la variable a

signada en la instruccin execute , en este caso @ guess , se muestra bajo su prop io 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 l lamada al procedimiento. El siguiente ejemplo ilustra los ltimos dos puntos utili zando @ store para mantener el valor de la variable durante la ejecucin del proce dimiento 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 parameter s: @result ----------30 Your_answer Right_answe r ----------- -----------32 30 (1 row affected) Wrong, wrong, wrong! A continuacin se muestra un procedimiento almacenado que verifica si las nuevas v entas 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 + @newsal es from titles where title_id = @title) select @pc = royal ty from roysched where @newtotal >= roysched.lorange and @new total < roysched.hirange and roysched.title_id = @title El siguiente lote SQL llama al procedimiento roy_check , despus de asignar un val or a la variable percent . Los parmetros de retorno se imprimen antes de que se e jecute 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 de clare @stor_pc int select @percent = (select royalty from roysched, titles where roysched.title_id = @title and total_sales >= roysched.lo range and total_sales < roysched.hirange and roysched.title_i d=titles.title_id) select @stor_pc = @percent execute roy_check @title, @new sales, @pc = @percent output if @stor_pc != @percent begin print "Royalty is changed" select Percent = @percent end else print "Royal ty is the same" Si ejecuta este procedimiento almacenado con los mismos parmetros utilizados en e l 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 pa rmetro 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 devuelt o en @percent puede cambiar dependiendo de los otros parmetros que se pasen. Si q uiere 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 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 Ser ver, excepto text e image . Note: Si el procedimiento almacenado requiere varios parmetros, pase el parmetro d el valor de retorno en ltimo lugar en la instruccin execute o pase todos los parmet ros subsiguientes con el formato "@parameter = value". La palabra clave output La palabra clave output puede abreviarse como out , del mismo modo que execute p uede acortarse como exec . Un procedimiento almacenado puede devolver varios valores; cada uno debe definir se como una variable output en el procedimiento almacenado y en las instruccione s 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 d e retorno sin solicitar los valores de retorno con output . Sin embargo, no se o btendrn 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 v ariables. #endregion #region 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 ti po 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 po sible 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 ocupa r 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 p rocedimiento se ejecuta, no cuando se compila. Si ejecuta un procedimiento que llama a otro, el procedimiento llamado puede acc eder 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 e se 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 dete rminados 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 instr ucciones, como select o insert , dentro de un procedimiento almacenado no necesi tan estar calificados porque los nombres se resuelven cuando se compila el proce dimiento. 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 ot ros usuarios puedan ejecutar el procedimiento donde se emplea la tabla: 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 ejec uta el procedimiento. Si marytab no est calificada y el usuario " john" intenta e jecutar el procedimiento, SQL Server busca una tabla llamada marytab propiedad d e John. El ejemplo anterior muestra el uso correcto: indica a SQL Server que bus que una tabla llamada marytab propiedad de Mary. #endregion #region Omisin de procedimientos almacenados Los procedimientos se quitan con el comando drop procedure , cuya sintaxis es: drop procedure [ owner .] procedure_name [, [ owner .] procedure_n ame ]... Si un procedimiento almacenado llama a otro procedimiento almacenado que se ha o mitido, SQL Server muestra un mensaje de error. Sin embargo, si se define un pro cedimiento 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 co n el mismo nombre pero con sufijos number diferentes, mediante una sola instrucc in drop procedure . Una vez agrupados los procedimientos, los procedimientos pert enecientes al grupo no podrn omitirse de forma individual. #endregion #region Cambio de nombre de los procedimientos almacenados Se puede cambiar el nombre de un procedimiento almacenado mediante el procedimie nto 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 pr ocedimiento almacenado de cualquier usuario. El procedimiento almacenado deber es tar 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 r eferencia a una tabla o una vista cuyos nombres se han cambiado puede parecer qu e 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 not ificarse al usuario. Utilice sp_depends para obtener un informe sobre los objetos a los que hace refe rencia un procedimiento. #endregion #region Uso de procedimientos almacenados como mecanismos de seguridad Es posible usar los procedimientos almacenados como mecanismos de seguridad a fi n de controlar el acceso a la informacin de las tablas y la capacidad para efectu ar modificaciones en los datos. Por ejemplo, puede denegar a otros usuarios el p ermiso para emplear el comando select en una tabla que es suya y crear un proced imiento almacenado que les permita visualizar slo determinadas filas o columnas. Tambin puede utilizar los procedimientos almacenados para limitar las instruccion es update , delete o insert . La persona que posee el procedimiento almacenado debe ser propietario de la tabl a o vista usada en el procedimiento. Ni siquiera el administrador del sistema pu ede generar un procedimiento almacenado para realizar operaciones en las tablas de otro usuario si no ha recibido permiso sobre ellas. Para obtener informacin sobre cmo conceder y revocar permisos de procedimientos al macenados y otros objetos de base de datos, consulte la Gua del Usuario de las Ca ractersticas de Seguridad . #endregion #region 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 proc edimientos del sistema. Un administrador del sistema puede permitir actualizacio nes directas en las tablas del sistema cambiando una variable de configuracin y e mitiendo el comando reconfigure with override . Consulte la Gua de Administracin d el 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 ins talacin 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 sybs ystemprocs , 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 pr opietario 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 sybsys temprocs , sus permisos tambin se definen aqu. Algunos procedimientos del sistema slo pueden ser ejecutados por los propietarios de las bases de datos. Estos proce dimientos garantizan que el usuario que ejecuta el procedimiento es el propietar io 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 otorgars e en la base de datos sybsystemprocs . Esta situacin tiene dos consecuencias: Un usuario puede tener permiso para ejecutar un procedimiento del sistema en tod as las bases de datos o en ninguna. El propietario de una base de datos de usuario no puede controlar directamente l os 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 S QL 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_pa ssword . Servidores remotos Esta categora incluye procedimientos para: Aadir, omitir e informar sobre los servidores remotos que pueden acceder a este S QL Server 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_dr

opremotelogin , sp_dropserver , sp_helpremotelogin , sp_helpserver , sp_remoteop tion , 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 u tilizado por tablas e ndices Los procedimientos de esta categora son: sp_bindefault fault , sp_unbindrule , sp_foreignkey , sp_primarykey , y , sp_depends , sp_addtype , sp_droptype , sp_rename , sp_helpdb , sp_helpindex , sp_helpjoins , sp_helpkey , ect , 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 p ara su uso en instrucciones print y raiserror Los procedimientos de esta categora son: sp_addmessage , sp_dropmessage y sp_getm essage . 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_hel pdevice , 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 esta s tareas administrativas en la Gua de Administracin del Sistema . Para obtener inf ormacin completa sobre los procedimientos del sistema, consulte el Manual de Refe , sp_bindrule , sp_unbinde sp_commonkey , sp_dropke sp_spaceused , sp_help , sp_helptext , sp_indsusp

rencia de SQL Server . #endregion #region Obtencin de informacin sobre procedimientos almacenados Varios procedimientos del sistema proporcionan informacin sobre procedimientos al macenados a partir de las tablas del sistema. sp_help Se puede obtener un informe sobre un procedimiento almacenado con el procedimien to del sistema sp_help . Por ejemplo, se puede obtener informacin sobre el proced imiento almacenado byroyalty , que forma parte de la base de datos pubs2 , de la siguiente forma: sp_help byroyalty Name Owner type Created_on -------- ------ --------------------------------- byroyalty dbo stored procedure Feb 9 1 987 3:56PM Data_located_on_segment When_created --------------------------------------------- Parameter_name Type Length Param_order ------------- ------ ------ ----------- @percentage int 4 1 (return status = 0) 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 procedimient o 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 titleaut hor where titleauthor.royaltyper = @percentage (1 row affected, return sta tus = 0) Es posible ver el texto de un procedimiento del sistema ejecutando sp_helptext a l utilizar la base de datos sybsystemprocs . sp_depends El procedimiento del sistema sp_depends muestra todos los procedimientos almacen ados que hacen referencia al objeto especificado por el usuario, o todos los pro cedimientos 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 hac en referencia a la tabla titleauthor : sp_depends titleauthor Cosas incluidas en la base de datos actual que hacen referencia al objeto. object type -------------- ------------------ dbo.titleview view dbo.reptq2 stored procedure dbo.byroyalty stored procedure (retur n status = 0) Debe omitir y volver a crear el procedimiento si el nombre de algunos de los obj

etos a los que hace referencia ha cambiado. Los procedimientos del sistema se explican brevemente en "Procedimientos del sis tema". Para obtener informacin completa sobre los procedimientos del sistema, con sulte el Manual de Referencia de SQL Server . #endregion #endregion #region DISPARADORES: IMPOSICIN DE LA INTEGRIDAD DE REFERENCIA #region Definicin de disparador Un disparador es un tipo especial de procedimiento almacenado que se ejecuta cua ndo se insertan, eliminan o actualizan datos de una tabla especificada. Los disp aradores pueden ayudar a mantener la integridad de referencia de los datos conse rvando la consistencia entre los datos relacionados lgicamente de distintas tabla s. Integridad de referencia significa que los valores de las claves primarias y los valores correspondientes de las claves externas deben coincidir de forma exa cta. La principal ventaja de los disparadores es que son automticos : funcionan cualqu iera sea el origen de la modificacin de los datos, una introduccin de datos por pa rte de un empleado o una accin de una aplicacin. Cada disparador es especfico de un a o ms operaciones de modificacin de datos, update , insert o delete . El disparad or se ejecuta una vez por cada instruccin SQL. Un disparador se "dispara" slo cuando la instruccin de modificacin de datos finaliz a y SQL Server verifica la posible violacin de tipos de datos, reglas o restricci ones de integridad. El disparador y la instruccin que lo "dispara" se consideran una sola transaccin que puede revertirse desde dentro del disparador. Si se detec ta 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 r elacionadas de la base de datos. Por ejemplo, un disparador de eliminacin de la c olumna 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 l ocalizar las filas de titleauthor , sales y roysched . Los disparadores pueden no permitir, o "revertir", los cambios que violen la int egridad de referencia, cancelando la transaccin de modificacin de datos intentada. Este tipo de disparador puede activarse si intenta insertar una clave externa q ue no coincide con su clave primaria correspondiente. Por ejemplo, podra crear un disparador de insercin en titleauthor que revirtiese cualquier insercin si el nue vo 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 dis paradores pueden hacer referencia a columnas u objetos de base de datos. Por eje mplo, un disparador puede revertir actualizaciones que intenten incrementar el p recio 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 modific acin de datos y llevar a cabo acciones basndose en esa comparacin. 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 p

lantillas para otros disparadores. En la seccin final de este captulo se describen las reglas relacionadas con el uso de disparadores y se explican los procedimie ntos del sistema que proporcionan ayuda con los disparadores. Note: Salvo el disparador llamado deltitle , los disparadores tratados en este c aptulo no estn incluidos en la base de datos pubs2 entregada con la copia de SQL S erver. Para trabajar con los ejemplos mostrados en este captulo, cree cada ejempl o de disparador escribiendo la instruccin create trigger. Cada disparador nuevo p ara 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 referen cia en las tablas de la base de datos. Sin embargo, las restricciones de integri dad de referencia se diferencian de los disparadores en que no pueden llevar a c abo 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 d e base de datos Realizar anlisis de hiptesis Adems, las restricciones de integridad de referencia no revierten la transaccin ac tual como resultado de la imposicin de la integridad de datos. Con los disparador es, la transaccin se puede revertir o continuar segn la forma en que se manipule l a 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 s encillo para imponer la integridad de los datos. Tenga presente que SQL Server v erifica las restricciones de integridad de referencia antes que los disparadores , por lo que una instruccin de modificacin de datos que viole la restriccin no disp ara el disparador tambin. Para obtener ms informacin sobre restricciones de integri dad de referencia, consulte el Captulo 7, "Creacin de bases de datos y tablas". #endregion #region Creacin de disparadores Un disparador es un objeto de base de datos. Cuando se crea un disparador, se es pecifica 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 cab o 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 mo dify 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 f or {insert , update} as [if update ( column_name ) [{and | o r} update ( column_name )]...] SQL_statements [if update ( column_name ) [{and | or} update ( column_name )]... S QL_statements ]... La clusula create crea el disparador y le asigna un nombre. El nombre del dispara dor debe cumplir con las reglas para identificadores. La clusula on indica el nombre de la tabla que activa el disparador. Esta tabla s e denomina en ocasiones tabla de disparadores. Los disparadores se crean en la base de datos actual, aunque pueden hacer refere ncia 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 pr opietario de la tabla, puede crear un disparador en una tabla. Si se indica el p ropietario de la tabla con el nombre de tabla en la clusula create trigger o la c lusula on , tambin debe especificarse en la otra clusula. La clusula for especifica los comandos de modificacin de datos de la tabla de disp aradores 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 co ndiciones del disparador especifican criterios adicionales que determinan si el comando insert , delete o update har que se lleven a cabo las acciones del dispar ador. Las acciones de disparador mltiples de una clusula if deben agruparse con be gin y end . Una clusula if update verifica si existe una insercin o actualizacin para una colum na 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 u na 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 us ar ms de una clusula if update en una instruccin create trigger . Puesto que el nom bre de tabla se especifica en la clusula on , no debe usar el nombre de tabla del ante 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 in dex , 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 unmirr or select into #endregion #endregion #region Omisin de disparadores Se puede quitar un disparador omitindolo u omitiendo la tabla de disparadores a l a que est asociado. La sintaxis de drop trigger es: drop trigger [ owner .] trigger_name [, [owner.] trigger_name ]... Cuando se omite una tabla, los disparadores asociados a ella se omiten automticam ente. El permiso drop trigger est asignado de forma predeterminada al propietario de la tabla de disparadores y no es transferible. #endregion #region Uso de disparadores para mantener la integridad de referencia Los disparadores se usan para mantener la integridad de referencia, que garantiz a que los datos vitales de la base de datos, como el identificador nico de unos d atos determinados, sean precisos y puedan usarse conforme cambia la base de dato s. La integridad referencial se coordina mediante el uso de claves primarias y e xternas. 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 t abla con una clave primaria puede combinarse con las claves externas de otras ta blas. La tabla de clave primaria puede considerarse como la maestra en una relac in maestro-discpulo . En una base de datos puede haber numerosos grupos maestro-di scpulo de este tipo. Use el procedimiento del sistema sp_primarykey para marcar la clave primaria. Es to 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 primari a 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 roysc hed . El diagrama del Chapter 1, "The pubs2 Database," del Suplemento de Referen cia 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 frecuen cia 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 clav es 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 algu na 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 tabla s 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 o tros procedimientos que hagan referencia a la tabla syskeys .

Las columnas title_id de titleauthor , salesdetail y roysched son claves externa s; 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 col umna con las claves relacionadas usando tablas de trabajo temporales llamadas ta blas de verificacin de disparadores. Cuando se escriben los disparadores, las com paraciones se basan en los datos almacenados temporalmente en las tablas de veri ficacin de disparadores. Contrastacin de la modificacin de datos respecto a las tablas de verificacin de dis paradores En las instrucciones de los disparadores se usan dos tablas especiales: la tabla deleted (eliminada) y la tabla inserted (insertada). Se trata de tablas tempora les 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 tab las de verificacin de disparadores, pero se pueden usar las tablas en instruccion es select para detectar los efectos de una instruccin insert , update o delete . La tabla deleted almacena copias de las lete y update . Durante la ejecucin de se quitan de la tabla de disparadores y abla deleted y la tabla de disparadores filas afectadas por las instrucciones de una instruccin delete o update , las filas se transfieren a la tabla deleted . La t no suelen tener filas en comn.

La tabla inserted almacena copias de las filas afectadas por las instrucciones i nsert 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 nue vas 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 e rror hacer referencia a eliminated mientras se verifica una instruccin insert ni a inserted mientras se verifica una instruccin delete , estas tablas de verificac in de disparadores no contendrn ninguna fila en estos casos. Note: Cada disparador se activa una sola vez por consulta. Si las acciones de lo s 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 almacen a el "nmero de filas afectadas" por la ltima operacin de modificacin de datos, compr ueba si se ha llevado a cabo una insercin, eliminacin o actualizacin en mltiples fil as. Si otra instruccin select precede a la verificacin de @@ rowcount dentro del d isparador, deber usar variables locales para almacenar el valor a fin de examinar lo ms adelante. Todas las instrucciones Transact-SQL que no devuelven valores vue lven 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 verific ar si existen combinaciones entre la fila o filas insertadas y las filas de la t abla 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 r evierte todos los cambios provocados por la instruccin insert ; en ejemplos poste riores 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 nueva s 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 lo s de la tabla titles . El disparador supone que va a realizar una entrada para l a clave externa y que no va a introducir un valor nulo. Si la combinacin falla, l a transaccin se revierte. create trigger forinsertrig1 on salesdetail for insert as if (select co unt(*) from titles, inserted where titles.title_id = inserted.title_ id) != @@rowcount /* cancelar la insercin e imprimir un mensaje.*/ beg in rollback transaction print "No, a title_id does not exist in title s" end /* En caso contrario, permitirlo. */ else print "Added! Al l 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 verifica cin de si todos los valores title_id aadidos a salesdetail existen en la tabla tit les se lleva a cabo combinando titles e inserted . Si el nmero de filas combinada s, que se determina mediante la consulta select count(*) , es diferente de @@ ro wcount , 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 d e clave externa correspondientes de las tablas dependientes. Esto mantiene la in tegridad de referencia al garantizar la eliminacin de las filas discpulas cuando s e quita la fila maestra. Si esto no se hiciera, podra acabar con una base de dato s 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 ti tles , una o ms filas salen de la tabla titles y se aaden a la eliminida. Un dispa rador puede comprobar las tablas dependientes ( titleauthor , salesdetail y roys ched ) para ver si tienen filas con un valor title_id que coincida con los valor es title_id quitados de titles y almacenados ahora en la tabla deleted. Si el di sparador encuentra alguna fila de este tipo, la quita. create trigger delcascadetrig on titles for delete as delete titleautho from titleauthor, deleted where titleauthor.title_id = deleted.title_id /* Quitar filas de titleauthor que ** coincidan con las filas e liminadas ** (ttulos).*/ delete salesdetail from salesdetail, deleted where salesdetail.title_id = deleted.title_id /* Quitar filas de salesdetail que ** coin cidan con las filas eliminadas ** (ttulos).*/ r

delete roysched from roysched, deleted where roysched.title_id = deleted. title_id /* Quitar filas de roysched que ** coincidan con la s filas eliminadas ** (ttulos).*/ En la prctica, es posible que quiera conservar algunas de las filas discpulas. Est o puede ocurrir por razones de mantenimiento de historiales (para verificar cunta s 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 evit a la eliminacin de una clave primaria si hay filas discpulas correspondientes a la misma en la tabla salesdetail . Este disparador conserva la capacidad de recupe rar filas de salesdetail . create trigger deltitle on titles for delete as if (select count(*) from deleted, salesdetail where salesdetail.title_id = deleted.ti tle_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 combinndola s con la tabla salesdetail . Si se encuentra una combinacin, la transaccin se canc ela. Ejemplos de disparador de actualizacin Dado que una clave primaria es el identificador nico de su fila y de las filas ex ternas de otras tablas, un intento de actualizar una clave primaria debe realiza rse con extremo cuidado. En este caso, desea proteger la integridad de referenci a revirtiendo la actualizacin a no ser que se cumplan las condiciones especificad as. 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 d esea prohibir las actualizaciones slo en determinadas circunstancias, use un disp arador. Este disparador evita las actualizaciones de titles.title_id durante el fin de s emana. La clusula if update de stopupdatetrig permite centrarse en una columna co ncreta, titles.title_id . Las modificaciones de los datos de esa columna hacen q ue el disparador se active. Los cambios de los datos de otras columnas no. Cuand o 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. */ i f update (title_id) and datename(dw, getdate()) in ("Saturday", "Sun day") begin rollback transaction print "We don't allow changes t o" print "primary keys on the weekend!" end Tambin puede especificar acciones de disparador mltiples en ms de una columna media nte if update . El siguiente ejemplo modifica stopupdatetrig a fin de incluir ac ciones de disparador adicionales para las actualizaciones realizadas en titles.p rice 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 antic ipo. Es posible usar el mismo nombre de disparador, ya que el disparador modific ado 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 "prima ry 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 prin t "We don't allow changes to price or" print "advance for a title until i ts 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 probab ilidad un error. Una clave externa no es ms que una copia de la clave primaria; n unca deben ser independientes la una de la otra. Si por alguna razn desea permiti r actualizaciones en una clave externa, es posible que quiera proteger la integr idad 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 po sibles de error: puede ocurrir que title_id no est siquiera en la tabla salesdeta il , o que no est en la tabla titles . Este ejemplo usa instrucciones anidadas if...else . La primera instruccin if se c umple 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 n o contendr ninguna fila y la seleccin devolver un valor nulo. Si esta prueba se sup era, la siguiente instruccin if comprueba si la fila o filas nuevas de la tabla i nserted se combina con alguna title_id de la tabla titles . Si alguna de las fil as 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 (ti tle_id) begin if (select distinct inserted.title_id from ins erted) is null begin rollback transaction print "No! Old title_id must be in salesdetail" end else if (select count(*) from titles, inserted where tit les.title_id = inserted.title_id) != @row begin rollback transaction print "No! New title_id not in titles" end else print "salesdetail table updated" end #endregion #region Consideraciones sobre filas mltiples Las consideraciones sobre filas mltiples son especialmente importantes en los cas os en que la funcin del disparador es recalcular de forma automtica los valores su marios, es decir, llevar a cabo concordancias continuadas. Los disparadores usados para mantener los valores sumarios deben contener clusula s group by, o subconsultas que realicen agrupaciones implcitas, a fin de crear va lores 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 sig nifica que slo se ha visto afectada una fila de la tabla de disparadores. Si @@ r owcount es igual a uno, las acciones del disparador se llevan a efecto sin la clu sula group by . Este disparador de insercin actualiza la columna total_sales de la tabla titles c ada vez que se aade una fila nueva a salesdetail . El disparador se activa cada v ez 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 s u 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 de @@rowcount */ if @@rowcount = 1 for insert as update titles /* verificar valor set total_sale

s = total_sales + qty from inserted where titles.title_id = inse rted.title_id else /* cuando rowcount sea mayor que 1, ** usar una clusula group by */ update titles set total_sales = tota l_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 tota l_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 va lor de @@rowcount */ if @@rowcount = 1 update titles set total_s ales = total_sales - qty from deleted where titles.title_id = de leted.title_id else /* cuando rowcount sea mayor que 1, ** usar un a clusula group by */ update titles set total_sales = tot al_sales - (select sum(qty) from deleted group by deleted.title_i d having titles.title_id = deleted.title_id) Este disparador se activa cada vez que se elimina una fila de la tabla salesdeta il . 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 ta bla titles cada vez que se actualiza el campo qty de una fila de salesdetail . N o olvide que una actualizacin es una insercin seguida de una eliminacin. Este dispa rador hace referencia a las tablas de verificacin de disparadores inserted y dele ted. create trigger updtrig on salesdetail for update as if update (qty) b egin /* verificar valor de @@rowcount */ if @@rowcount = 1 update titles set total_sales = total_sales + inserte d.qty - deleted.qty from inserted, deleted where titles.t itle_id = inserted.title_id and inserted.title_id = deleted.title_id else /* cuando rowcount sea mayor que 1, ** usar una clusula grou p 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 dele ted 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 modificac in de datos como un todo. Si una fila de una insercin de cuatro filas no era acept able, la insercin en su conjunto se consideraba inaceptable y se reverta la transa ccin. Sin embargo, no es necesario revertir todas las modificaciones de datos slo porqu e algunas de ellas no son aceptables. El uso de una subconsulta correlacionada d entro de un disparador puede obligar al disparador a examinar las filas modifica das de una en una. Consulte el Captulo 5, "Subconsultas: uso de consultas dentro de otras consultas", para obtener ms informacin sobre las subconsultas correlacion adas. Entonces el disparador puede llevar a cabo acciones distintas en filas dif erentes. 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) not null, ord_num varchar (20) not null, title_id tid not null, qty smallint not null, discount float not null) Para verificar el disparador condicional, hay que insertar cuatro filas en la ta

bla newsales , . Dos de las filas de newsales tienen columnas title_id que no co inciden con ninguna de las ya existentes en la tabla titles . Estos son los dato s: newsales stor_id ord_num title_id qty discount ------- --------- --------- ------------ 7066 BA27619 PS1372 75 40.0 00000 7066 BA27619 BU7832 100 40.000000 7067 NB-1.242 PSxxxx 50 40.000000 7131 Asoap433 PSyyyy 50 40.00000 0 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 fi las que no tienen una columna title_id en titles . A continuacin se indica cmo hac erlo: create trigger conditionalinsert on salesdetail for insert as if (selec t 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 tit le_ids added." end La prueba de disparador es la misma que la del ejemplo intrig , pero la transacc in 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 orde n en que se lleva a cabo el procesamiento cuando los disparadores se activan. Pr imero se insertan las filas en la tabla y en inserted , y luego se activa el dis parador. #endregion #region 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 desac tivar 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 a ctivar un tercer disparador, y as sucesivamente. Si cualquiera de los disparadore s 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 fil as afectadas por un disparador anterior. Por ejemplo, puede crear un disparador en titleauthor que guarde una copia de se guridad 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 tambin elimina la fila o filas correspondientes de titleauthor . Para guardar los datos, puede crear un disparador delete en titleauthor que guarde lo s datos eliminados en otra tabla, del_save : create trigger savedel on titleauthor for delete as insert del_save s elect * from deleted No conviene usar los disparadores en una secuencia dependiente de criterios de o rdenacin. 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 ni vel 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. To das las modificaciones de datos se revierten. Proporcione sus disparadores con l as instrucciones print o raiserror a fin de determinar dnde se ha producido el fa llo. La ejecucin de rollback transaction en un disparador en cualquier nivel de anidac in 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 mod ificacin 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 d e 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 repetidam ente. Sin embargo, es posible activar la opcin allow self_recursion del comando s et a fin de permitir que los disparadores se llamen a s mismos de forma recurrent e. 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 limita do por el alcance del disparador que la define. Si el disparador que establece s elf_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 act ivar 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 dato s pubs2 : select * from new_budget unit parent_unit budget --------------- --------------- ------one_department one_division 10 one_division company_wide 100 compa ny_wide NULL 1000 (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.budg et + inserted.budget - deleted.budget from inserted, deleted, new_ budget where new_budget.unit = inserted.parent_unit and new_budget .unit = deleted.parent_unit end Si un usuario actualiza new_budget.budget incrementando el presupuesto de la uni dad one_department en 3, SQL Server se comporta como sigue (suponiendo que est ha bilitada la anidacin de disparadores): 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 (e n 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 ) d e 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 disparado r no se activa, finalizando as la recurrencia automtica. Se puede consultar new_bu dget para ver los resultados finales que se muestran a continuacin: select * from new_budget unit parent_unit budget --------------- --------------- ------one_department one_division 13 one_division company_wide 103 compa ny_wide NULL 1003 (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 qu e 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 s e ejecutan exactamente una vez si nested triggers est desactivada. Si esta opcin e st 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 sobrepa se el valor mximo de 16 niveles de anidacin. #endregion #region Reglas asociadas a los disparadores Aparte de prever los efectos de una modificacin de datos en mltiples filas, las re versiones de los disparadores y la anidacin de disparadores, existen otros factor es 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 tabl a tiene los permisos create trigger y drop trigger sobre dicha tabla. Estos perm isos 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, pue sto que el disparador se ejecuta y falla debido a que los permisos no son correc tos. 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 actual ice salesdetail.qty . Sin embargo, Mary es la propietaria de titles y no ha conc edido a Jose el permiso sobre titles . Cuando Jose intenta actualizar salesdetai l , 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 d isparadores por SQL Server: Una tabla puede tener un mximo de tres disparadores: uno de actualizacin, uno de i nsercin y uno de eliminacin. Cada disparador puede aplicarse a una sola tabla. Sin embargo, un mismo disparad or 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 lo s disparadores pueden hacer referencia a las vistas o tablas temporales. Aunque la instruccin truncate table es, en realidad, como una instruccin delete si n la clusula where porque quita todas las filas, no puede "activar" un disparador porque las eliminaciones individuales de fila no se registran. Los disparadores no se permiten en las tablas del sistema. Aunque no aparece nin gn 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 l a columna se le asigna un valor en la lista de seleccin o en la clusula values . L a 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 N ULL 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 disp arador.*/ insert junk (a, b) values (1, 2) /*"if update" es verdadero para ambas columnas. ** Se activa el disp arador.*/ insert junk values (1, 2) /*NULL explcito: **"if update" es verdadero para ambas columnas. ** Se activa el disparador.*/ insert junk values (NULL, 2) /* Si hay un valor predeterminado para la ** columna a, "if update" es verdadero para ** ambas columnas. Se activa el disparador.*/ insert ju nk (b) values (2) /* Si no hay ningn valor predeterminado en la ** columna a, "if updat e" no es verdadero para ** la columna a. El disparador no se acti va.*/ 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, pu ede 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 hace r 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 me moria 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 Es posible utilizar el comando set dentro de un disparador. La opcin set que se e jecuta 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 omit ir el disparador y volver a crearlo de forma que su texto refleje el nombre nuev o del objeto al que hace referencia. Emplee el procedimiento sp_depends para obt ener 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 hag a referencia un disparador. #endregion #region Obtencin de informacin sobre disparadores Como objetos de base de datos que son, los disparadores se enumeran en sysobject s por nombre. La columna type de sysobjects identifica los disparadores con la a breviatura "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 sys comments . Se puede mostrar la definicin de un disparador con el procedimiento de l 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 sob re 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 When_created ----------------------- ---------------- no es aplicable Feb 9 1987 3:56PM (return status = 0) 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(*) fro m deleted, salesdetail where salesdetail.title_id = deleted.title_id) >0 beg in rollback transaction print "You can't delete a title with sales." end sp_depends 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. E ste ejemplo indica cmo utilizar sp_depends para obtener una lista de todos los ob jetos 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 type updated selected ------------------------ ------- -------- dbo.salesdetail user table no no dbo.titles user table no no (return status = 0) Esta instruccin muestra todos los objetos que hacen referencia a la tabla salesde

tail : sp_depends salesdetail Cosas incluidas en la base de datos actual que hacen referencia al objeto. object type --------------------------- --------------dbo.deltitle disparador dbo.history_pr oc procedimiento almacenado dbo.insert_salesdetail_proc procedim iento almacenado dbo.totalsales_trig disparador (return status = 0) #endregion #endregion #region CURSORES: ACCESO A LOS DATOS FILA POR FILA #region Definicin de cursores Un cursor es el nombre simblico asociado a una instruccin select Transact-SQL medi ante una instruccin de declaracin. Se compone de las siguientes partes: 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 elimina r 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 medi ante una operacin llamada recuperacin . Una recuperacin desplaza hacia abajo la pos icin 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 resultad os de la consulta. Sin embargo, los cursores slo admiten el movimiento hacia dela nte (o secuencial) a travs de los resultados de la consulta. Una vez que se han r ecobrado varias filas, no es posible volver hacia atrs en el conjunto de resultad os del cursor para acceder a ellas de nuevo. Este proceso permite examinar los r esultados 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 posib le leer informacin en l. Los cursores se encuentran inicialmente en este estado. E s necesario abrir el cursor de forma explcita para poder utilizarlo. Una vez abie rto, 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 disponibl es para su lectura o actualizacin. Se puede cerrar un cursor y despus volver a abrirse. La reapertura de un cursor v uelve 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 curso r tantas veces como sea necesario. El cursor se puede cerrar en cualquier moment o, 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 curs or implica modificar los datos de la fila o eliminar sta por completo. No es posi

ble utilizar los cursores para insertar filas. Todas las actualizaciones realiza das mediante un cursor afectan a las tablas base correspondientes incluidas en e l 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 si guientes operaciones: Declaracin del cursorSQL Server crea la estructura del cursor y compila la consul ta 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 ge nerada por la consulta y asigna recursos (como memoria) para dar soporte a la es tructura del cursor. Tambin coloca el cursor delante de la primera fila de su con junto 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 recu peraciones hasta alcanzar el final del conjunto de resultados. Actualizacin o eliminacin mediante el cursor SQL Server actualiza o elimina los da tos 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 d espus de una recuperacin. Esta operacin es opcional. Cierre del cursorSQL Server cierra el conjunto de resultados del cursor, quita l as tablas temporales que quedan y libera los recursos del servidor retenidos par a 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 eli mina toda huella de la estructura del cursor. Es preciso volver a declarar el cu rsor antes de utilizarlo. #endregion #region Declaracin de cursores Debe declarar un cursor para poder utilizarlo. La declaracin especifica la consul ta 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. Sintaxis de declare cursor La sintaxis de la instruccin declare cursor es: declare cursor_name cursor for select_statement [for {read only | upd ate [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 Tr ansact-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 semn

tica completas de una instruccin select Transact-SQL, incluida la palabra clave h oldlock . Sin embargo, no puede contener una clusula compute , for browse o into . Por ejemplo, la siguiente instruccin declare cursor define un conjunto de resulta dos 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-SQ L o variables locales. Sin embargo, los nombres slo pueden hacer referencia a parm etros y variables locales definidas en un procedimiento almacenado que contenga la instruccin declare cursor . Si se utiliza el cursor en un disparador, select_s tatement tambin puede hacer referencia a las tablas temporales inserted y deleted utilizadas en los disparadores. Para obtener informacin adicional sobre el uso d e la instruccin select , consulte el Captulo 2, "Consultas: seleccin de datos de un a tabla". Alcance del cursor Un cursor viene definido por su alcance , que determina la regin en que est presen te el cursor. Una vez que el alcance del cursor deja de existir, tambin desaparec e su nombre. El alcance de los cursores viene definido por las siguientes region es: 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 procedimiento s almacenados o disparadores. Procedimiento almacenado: esta regin se inicia cuando un procedimiento almacenado comienza su ejecucin y finaliza cuando la termina. Si un procedimiento almacenad o llama a otro, SQL Server inicia una regin nueva y la trata como subregin del pri mer procedimiento. Disparador: esta regin se inicia cuando un disparador comienza su ejecucin y final iza cuando la completa. Un cursor debe tener un nombre nico dentro de un alcance dado. Puesto que cada al cance es distinto, un nombre de cursor definido en una regin tambin puede definirs e en otra regin o en su propia subregin. No es posible acceder a un cursor definid o en una regin desde otra regin. Sin embargo, SQL Server permite el acceso de un c ursor 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 defini r dos cursores con el mismo nombre si slo se ejecuta uno. Por ejemplo: create procedure proc1 (@flag int) as if (@flag) declare names_crsr curs or 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_crs r en su alcance. Barridos del cursor y el conjunto de resultados del cursor Es posible que las filas del conjunto de resultados del cursor no reflejen los v alores 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 or denar 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, permit iendo 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 es tarn sincronizadas con las filas de la tabla base. Un conjunto de resultados del cursor se genera a medida que las filas son devuel tas mediante un fetch de dicho cursor. Esto significa que una consulta select de l 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 neces idad 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 bas e de datos identity in nonunique index para incluir automticamente una columna ID ENTITY 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 ni cos sean internamente nicos y permite usarlos para procesar cursores actualizable s en lecturas con un nivel de aislamiento 0. Sin embargo, todava puede emplear cursores que hagan referencia a tablas sin ndice s, 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 Serv er permite la declaracin de cursores en tablas sin ndices nicos, pero cualquier act ualizacin o eliminacin que mueva la posicin de las filas en estas tablas cierra tod os 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 actualiz able. Si el cursor es de slo lectura, slo podr leer los datos, pero no actualizarlo s ni eliminarlos. De forma predeterminada, SQL Server intenta determinar si un c ursor es actualizable antes de designarlo como de slo lectura. Se puede especificar si un cursor es actualizable o no explcitamente utilizando l as palabras clave read only o update en la instruccin declare . El siguiente ejem plo define un conjunto de resultados actualizable para el cursor pubs_crsr : declare pubs_crsr cursor for select pub_name, city, state from publishers fo r update of city, state El ejemplo anterior incluye todas las filas de la tabla publishers , pero slo def ine 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 cur sor 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 c omo de slo lectura si se declaran ciertos tipos de cursores que incluyen una clusu la order by como parte de su select_statement . Para obtener ms informacin, consul te la seccin sobre cursores en el Manual de Referencia de SQL Server . Si no especifica una column_name_list con la clusula for update , todas las colum nas especificadas en la consulta son actualizables. Como se ha descrito anterior mente para los barridos de cursor, SQL Server intenta utilizar ndices nicos con lo s 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 especifica das en la lista de columnas de la select_statement del cursor, pero que formen p arte 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, aun que tambin puede utilizar otros ndices o barridos de tabla si no existe ningn ndice n ico para las columnas especificadas. Sin embargo, cuando se especifica for updat e , 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 ba rrido de cursor, lo que ayuda a evitar una actualizacin anmala llamada problema Ha lloween . 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 f ilas de las tablas base. Por ejemplo, si SQL Server accede a una tabla base util izando un ndice y el cliente actualiza la clave del ndice, la fila del ndice actual izada puede moverse dentro de ste y ser leda nuevamente por el cursor. Esto es res ultado de que un cursor actualizable slo crea de forma lgica un conjunto de result ados del cursor. El conjunto de resultados del cursor se compone realmente de la s tablas base de las que se deriva el cursor. #endregion #region Apertura de cursores Despus de declarar el cursor, debe abrir ste para realizar una operacin fetch , upd ate 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 resultado s 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 co n la instruccin declare cursor . Puede volver a abrir un cursor cerrado para rest ablecer su posicin al principio del conjunto de resultados.

#endregion #region Recuperacin de filas de datos mediante cursores Despus de declarar y abrir un cursor, puede recobrar filas de su conjunto de resu ltados 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 parmet ros de Transact-SQL o variables locales con fetch para almacenar valores de colu mna. 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 l a primera fila de su conjunto de resultados de la siguiente manera: fetch authors_crsr au_id au_lname au_fname ----------- ------------------- -------------- 341-22-1782 Smith Meander Cada fetch posterior recupera otra fila del conjunto de resultados del cursor. P or 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. L a posicin del cursor no se altera. No es posible recobrar una fila que ya se ha recuperado, ni volver atrs en un con junto 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 e l principio. La clusula into especifica que SQL Server introduce datos de columna en las varia bles 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 reco brar 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_ta rget_list y las expresiones de la lista de destino especificadas en la select_st atement que define el cursor. Los tipos de datos de las variables o parmetros deb en 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 a l valor mediante la variable global @@sqlstatus . La siguiente tabla enumera val ores de @@sqlstatus posibles y su significado: Tabla 16-1: Valores de @@sqlstatus Valor Significado 0

Indica que la instruccin f etch se ha completado correctamente. 1 Indica que la instruccin f etch ha dado como resultado un error. 2 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 resultad os 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 tie ne efecto sobre esta variable. Verificacin del nmero de filas recobradas SQL Server tambin proporciona la variable global @@rowcount . . @@rowcount permit e 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 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 pued e utilizar la opcin cursor rows del comando set para cambiar el nmero de filas dev ueltas por fetch . Sin embargo, esta opcin no afecta a una recuperacin que conteng a 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 curso r 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 resultad os del cursor: fetch authors_crsr au_id au_lname au_fname ----------- ------------------- -------------- 648-92-1872 Blotchet-Halls Reginald 712-45-1867 del Castillo

Innes 722-51-5424 DeFrance Michel El cursor se coloca en la ltima fila recobrada (el autor Michel DeFrance, en el e jemplo anterior). La recuperacin de varias filas al mismo tiempo es especialmente adecuada para apl icaciones cliente. Si recobra ms de una fila, Open Client o Embedded SQL(TM) colo ca las filas enviadas a la aplicacin cliente en la memoria intermedia automticamen te. El cliente todava ve un acceso fila por fila, pero cada fetch genera menos ll amadas a SQL Server, lo que mejora el rendimiento. #endregion #region Actualizacin y eliminacin de filas utilizando cursores Si el cursor es actualizable, puede utilizar las instrucciones update y delete p ara actualizar o eliminar filas. SQL Server determina si el cursor es actualizab le 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 instruc cin declare cursor . Consulte "Conversin de los cursores en actualizables" para ob tener ms informacin. Eliminacin de filas del conjunto de resultados del cursor Mediante la clusula where current of de la instruccin delete , puede eliminar la f ila de la posicin actual del cursor. Al eliminar una fila del conjunto de resulta dos 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] [[ database .] owner .]{ table_name | view_name } where current of cursor_name 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 q ue define el cursor. Por ejemplo, se puede eliminar la fila a la que apunta actualmente el cursor aut hors_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 se lect 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 t ener acceso a la fila siguiente. Si elimina la ltima fila del conjunto de resulta dos del cursor, SQL Server coloca el cursor despus de la ltima fila del conjunto d e resultados. Por ejemplo, despus de eliminar la fila actual en el ejemplo anterior (el autor M ichel DeFrance), se pueden recobrar los siguientes 3 autores en el conjunto de r esultados del cursor (suponiendo que cursor rows todava est definido como 3): fetch authors_crsr au_id au_lname au_fname ----------- ------------------- -------------- 807-91-6654 Panteley Sylvia 899-46-2035 Ringer Anne 998-72-3567 Ringer Albert Evidentemente, puede eliminar una fila de la tabla base sin hacer referencia a u n cursor. El conjunto de resultados del cursor cambia a medida que se realizan c ambios 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 resu ltados 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 [[[ d atabase .] owner .]{ table_name .| view_name .}] column_name 1 = { expression 1 |NULL|( select_statement )} [, column_n ame 2 = { expressio n2 |NULL|( select_statement )}]... whe re current of cursor_name La clusula set especifica el nombre de columna del conjunto de resultados del cur sor 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 clusu la from de la instruccin select que define el cursor. Si dicha clusula from hace r eferencia 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 si guiente modo: update publishers set city = "Pasadena", state = "CA" where current of p ubs_crsr Despus de la actualizacin, la posicin del cursor permanece igual. Se puede continua r actualizando la fila de esa posicin del cursor siempre que otra instruccin Trans act-SQL no lo desplace. SQL Server permite actualizar columnas que no estn especificadas en la lista de c olumnas de la select_statement , pero forman parte de las tablas indicadas en es ta instruccin. Sin embargo, cuando especifica una column_name_list con update , sl o es posible actualizar las columnas indicadas en ella. #endregion #region 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 S QL Server crear un conjunto de resultados del cursor nuevo utilizando la misma co nsulta que antes. Por ejemplo: close authors_crsr open authors_crsr Despus, puede recobrar desde authors_crsr , empezando por el principio de su conj unto de resultados. Cualquier condicin asociada a dicho cursor (como el nmero de f ilas recobradas, definido por set cursor rows ) permanece en vigor. Por ejemplo: fetch authors_crsr au_id au_lname ---------- 341-22-1782 Smith au_fname ----------- ------------------- ----Meander 527-72-3246 Greene

Morningstar 648-92-1872 Blotchet-Halls Reginald Si quiere desechar el cursor, debe desasignarlo mediante deallocate . La sintaxi s 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 d esasigne. Si desasigna un cursor abierto, SQL Server lo cierra automticamente. La finalizacin de una conexin cliente a un servidor tambin cierra y desasigna cualqui er cursor abierto. #endregion #region 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_lna me Los resultados de la consulta son: author au_id ------------------------- ----------- Abr aham Bennet 409-56-7008 Reginald Blotchet-Halls 648-92-1872 C heryl Carson 238-95-7766 Michel DeFrance 722-51-5454 Ann Dull 427-17-2319 Marjorie Green 213-46-891 5 Morningstar Greene 527-72-3246 Burt Gringlesby 472-27-2 349 Sheryl Hunter 846-92-7186 Livia Karsen 756-30 -7391 Chastity Locksley 486-29-1786 Stearns MacFeather 72480-9391 Heather McBadden 893-72-1158 Michael O'Leary 26 7-41-2394 Sylvia Panteley 807-91-6654 Anne Ringer 899-46-2035 Albert Ringer 998-72-3567 Meander Smith 341-22-1782 Dick Straight 274-80-9391 Dirk Stringer 724-08-9931 Johnson White 172-32-1176 Akiko Yokomoto 672-71-3249 Innes del Castillo 712-45-1867 Los siguientes pasos muestran el modo de utilizar un cursor con la consulta ante rior: 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 Una vez declarado el cursor, puede abrirlo: open newauthors_crsr Ahora puede recobrar filas utilizando el cursor: fetch newauthors_crsr author au_id ------------------------- ----------- Abr aham Bennet 409-56-7008 Se pueden recobrar varias filas al mismo tiempo especificando el nmero de filas c on el comando set : set cursor rows 5 for newauthors_crsr fetch newauthors_crsr author au_id ------------------------inald Blotchet-Halls 648-92-1872 Cheryl Carson ichel DeFrance 722-51-5454 Ann Dull Marjorie Green 213-46-8915 Cada fetch posterior devuelve cinco filas ms: ----------- Reg 238-95-7766 M 427-17-2319

fetch newauthors_crsr author au_id ------------------------ningstar Greene 527-72-3246 Burt Gringlesby heryl Hunter 846-92-7186 Livia Karsen Chastity Locksley 486-29-1786 Una vez que haya terminado con el cursor, puede cerrarlo:

----------- Mor 472-27-2349 S 756-30-7391

close newauthors_crsr El cierre del cursor libera el conjunto de resultados, pero el cursor se mantien e definido. Si lo abre de nuevo, SQL Server vuelve a ejecutar la consulta y colo ca el cursor delante de la primera fila de su conjunto de resultados. El cursor todava est definido para devolver cinco filas con cada fetch . 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.

#endregion #region Uso de cursores en procedimientos almacenados Los cursores son especialmente tiles en procedimientos almacenados. Permiten llev ar 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 c errar un cursor que no est declarado en el procedimiento. El cursor no est definid o fuera del alcance del procedimiento almacenado. Por ejemplo, el siguiente procedimiento almacenado au_sales verifica la tabla sa les 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 con creto */ 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 goo d sales this year." print @msg end fetch author_sales into @title_id, @title, @ytd_sales end /* si se genera un error, llamar al manipulador ** designado */ if (@@sqls tatus = 1) exec error_handle close author_sales deallocate cursor author_sales return Para obtener ms informacin sobre los procedimientos almacenados, consulte el Captul

o 14, "Uso de procedimientos almacenados". #endregion #region Cursores y bloqueo Los mtodos de bloqueo de cursores son similares a los mtodos de bloqueo actuales d e 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 le ctura de datos modificados por una transaccin no consignada. Las instrucciones de actualizacin utilizan bloqueos exclusivos en cada pgina que modifican. Para reduc ir los bloqueos insolubles y mejorar la simultaneidad, SQL Server sita con frecue ncia un bloqueo exclusivo delante de un bloqueo de actualizacin, el cual indica q ue el cliente piensa cambiar datos de la pgina. Con los cursores actualizables, SQL Server utiliza bloqueos de actualizacin de fo rma predeterminada al barrer tablas o vistas referenciadas con la clusula for upd ate de declare cursor . Si se incluye for update , pero la lista est vaca, todas l as referencias a tablas y vistas de la clusula from de la select_statement recibe n bloqueos de actualizacin predeterminadamente. Si no incluye la clusula for updat e , las tablas y vistas referenciadas reciben bloqueos compartidos. Puede indica r a SQL Server que utilice bloqueos compartidos en lugar de bloqueos de actualiz acin aadiendo la palabra clave shared a la clusula from . De forma especfica, aada sh ared 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 Adminis tracin del Sistema . Para obtener ms informacin sobre cursores y bloqueos, consulte el Manual de Referencia de SQL Server . #endregion #region 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 cu rsor 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 comp il 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 d evuelto 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 = 'au thors', Tipo = VARCHAR, Longitud = 20 (actualizable) Para obtener ms informacin sobre sp_cursorinfo , consulte el Manual de Referencia de SQL Server . #endregion #endregion #region TRANSACCIONES: MANTENIMIENTO DE LA CONSISTENCIA Y RECUPERACIN DE DATOS #region Definicin de transaccin Una transaccin es un mecanismo para garantizar que un conjunto de una o ms instruc

ciones SQL se trate como una sola unidad de trabajo. SQL Server maneja automticam ente todos los comandos de modificacin de datos, incluidas las solicitudes de cam bio 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 trans action . begin transaction marca el comienzo de un bloque de transacciones. Toda s las instrucciones posteriores, hasta una rollback transaction o una commit tra nsaction 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 rec uperacin 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 e ste captulo. Transacciones y consistencia En un entorno multiusuario, SQL Server debe evitar que las consultas y solicitud es de modificacin de datos simultneas interfieran entre s. Esto es importante porqu e si los datos procesados por una consulta pudieran ser cambiados por la actuali zacin de otro usuario mientras la consulta est en ejecucin, los resultados de la co nsulta 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 consul ta 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. Di chas transacciones se explican ms adelante en otra seccin. Transacciones y recuperacin Una transaccin es una unidad de trabajo y una unidad de recuperacin. El hecho de q ue SQL Server manipule las solicitudes de cambio de un solo paso como transaccio nes significa que la base de datos puede recuperarse completamente en caso de fa llos. El tiempo de recuperacin de SQL Server se mide en minutos y segundos. Se puede es pecificar 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". #endregion #region Uso de transacciones begin transaction y commit transaction indican a SQL Server que procese cualquie r nmero de comandos individuales como una sola unidad. rollback transaction desha

ce 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 trans action . Las transacciones definidas por el usuario proporcionan control sobre el manejo de la transaccin. Tambin mejoran el rendimiento, dado que la sobrecarga del sistem a se alcanza una vez por transaccin en lugar de una vez para cada comando individ ual. Note: La agrupacin de un gran nmero de comandos Transact-SQL en una transaccin de l arga 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 de be 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 comando s 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 trans acciones 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 com o create table , grant y alter table dentro de transacciones en esa base de dato s. 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 q ue 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 sist ema, 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 temp db dentro de transacciones, porque, de lo contrario, el sistema puede llegar a d etenerse. 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_dbopti on . 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 alter table (se permiten clusulas distintas de partition y unpartition ) create default create index create procedure create rule create schema create table create trigger create view

drop default drop index drop procedure drop rule drop table drop trigger drop view grant revoke

Los procedimientos del sistema que cambian la base de datos master o que crean t ablas temporales no pueden utilizarse dentro de transacciones definidas por el u suario. 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 dump database dump transaction drop database load transaction load database reconfigure select into update statistics truncate table

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 nmer o de instrucciones SQL y procedimientos almacenados. Las sintaxis de ambas instr ucciones 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 reg las para identificadores. Las palabras clave transaction , tran y work (en commit transaction ) son sinnima s: 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 f

inalizados debern deshacerse. Puede cancelar o revertir una transaccin con el comando rollback transaction en c ualquier momento antes de que se introduzca el comando commit transaction . Si u tiliza 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 transac cin para indicar el punto hasta donde es posible realizar la reversin. Los puntos de resguardo se insertan incluyendo un comando save transaction dentr o de la transaccin. La sintaxis es: save {transaction | tran} savepoint_name El nombre del punto de resguardo debe cumplir con las reglas para identificadore s. Si no se proporciona ningn nombre de punto de resguardo ( savepoint_name ) ni nin gn 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 tran saction : begin tran transaction_name statement statement procedure sav e tran savepoint_name statement rollback tran savepoint_name sta tement statement rollback tran El primer comando rollback transaction revierte la transaccin hasta el punto de r esguardo situado dentro de la transaccin. El segundo comando rollback transaction revierte la transaccin hasta su comienzo. Si una transaccin se revierte a un punt o de resguardo, debe continuar hasta su finalizacin o cancelarse por completo. Hasta que se emite commit transaction , SQL Server considera todas las instrucci ones subsiguientes como parte de la transaccin, a menos que se encuentre con otra instruccin begin transaction . En este punto, SQL Server considera todas las ins trucciones subsiguientes como parte de esta nueva transaccin anidada. Las transac ciones anidadas se describen en la prxima seccin. rollback transaction o save transaction no afectan a SQL Server y no devuelven n ingn 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 t ransaccin. 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 ins truccin. @@transtate puede contener los siguientes valores: Tabla 17-3: Valores de @@transtate Valor Significado 0 Transaccin en proceso. Hay una transaccin implcita o explcita en efecto; la instruc cin anterior se ha ejecutado de forma correcta. 1 Transaccin ejecutada de forma correcta. La transaccin ha finalizado y ha consigna

do sus cambios. 2 Instruccin abortada. La instruccin anterior se ha abortado; no ha tenido ningn efe cto sobre la transaccin. 3 Transaccin abortada. La transaccin se ha abortado y ha revertido los cambios efec tuados.

En una transaccin, es posible utilizar @@transtate despus de una instruccin (como i nsert ) 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 ---------1 (1 row affected) El siguiente ejemplo verifica @@transtate despus de una operacin insert no correct a (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 confl icto con una regla vinculada a la columna. El comando ha sido abortado. El confl icto se produjo en la base de 'pubs2', tabla 'publishers', regla 'pub_idrule', c olumna '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 p or 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 segu imiento del nivel de anidacin. SQL Server no consigna la transaccin hasta que se e mite la instruccin commit transaction que coincide con la instruccin begin transac tion ms exterior. SQL Server proporciona una variable global, @@trancount , que mantiene un seguim iento del nivel de anidacin actual de las transacciones. Una instruccin begin tran saction incial implcita o explcita define @@ trancount en 1. Cada begin transactio n subsiguiente aumenta @@trancount y commit transaction la reduce. La activacin d

e un disparador tambin incrementa @@ trancount y la transaccin se inicia con la in struccin que activa el disparador. Las transacciones anidadas no se consignan has ta que @@trancount es igual a 0. Por ejemplo, SQL Server no consigna los siguientes grupos de instrucciones anida dos hasta la instruccin commit transaction final: begin tran select @@trancount /* @@trancount = 1 */ begin tran select @@trancount /* @@trancount = 2 */ begin tran select @@trancount /* @@trancoun t = 3 */ commit tran commit tran commit tran select @@trancount /* @@ trancount = 0 */ Cuando se anida una instruccin rollback transaction sin incluir un nombre de tran saccin o punto de resguardo, siempre revierte a la instruccin begin transaction ms exterior y cancela la transaccin. Ejemplo de una transaccin definida por el usuario Este ejemplo muestra el modo en que se podra especificar una transaccin definida p or 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 inco nsistente ** entre las dos actualizaciones, deben agruparse ** en una transacc in. */ update titleauthor set royaltyper = 65 from titleauthor, titles where roya ltyper = 75 and titleauthor.title_id = titles.title_id and title = "The Gourme t Microwave" update titleauthor set royaltyper = 35 from titleauthor, titles where roya ltyper = 25 and titleauthor.title_id = titles.title_id and title = "The Gourme t Microwave" save transaction percent_changed /* Una vez actualizadas las entradas royaltyper ** de los dos autores, el us uario 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 = titleau thor.title_id and titles.title_id =roysched.title_id rollback transaction percent_changed /* La transaccin se revierte al punto de ** resguardo con el comando rollbac k transaction. ** Sin un punto de resguardo, se revertera al ** principio de la transaccin. */ commit transaction #endregion #region 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 e l nivel de aislamiento de las transacciones, y deberan definirse al comienzo de c ada 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 inst rucciones begin transaction explcitas emparejadas con instrucciones commit transa ction o rollback transaction para completar la transaccin. El modo compatible con las normas SQL, llamado modo encadenado , inicia una tran saccin de forma implcita antes de cualquier instruccin de recuperacin o modificacin d e datos. Estas instrucciones incluyen: delete , insert , open , fetch , select y update . Sin embargo, es necesario finalizar la transaccin explcitamente con comm it transaction o rollback transaction . Puede definir los dos modos mediante la opcin chained del comando set . Sin embar go, no debera mezclar estos modos de transaccin en las aplicaciones. El comportami ento de los procedimientos almacenados y los disparadores puede variar segn el mo do 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 represen ten los datos reales. Este nivel evita que otras transacciones escriban sobre lo s mismos datos antes de que la transaccin se consigne. Los otras transacciones pu eden 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 h asta 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 transacti on isolation level del comando set . Puede imponer el nivel de aislamiento slo pa ra 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 modific acin de datos tengan lugar dentro de una transaccin. Una transaccin se inicia de fo rma 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 chai ned de la instruccin set . Por ejemplo: set chained on Sin embargo, no puede ejecutar el comando set chained dentro de una transaccin. P ara volver al modo no encadenado de las transacciones, defina la opcin chained co mo 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 r ecuperacin o modificacin de datos: delete , insert , open , fetch , select y updat e . Por ejemplo, el siguiente grupo de instrucciones genera diferentes resultado s dependiendo del modo que se utilice:

insert into publishers values ('9999', null, null, null) begin transacti on 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 in strucciones hasta el comienzo de dicha transaccin, incluida la instruccin insert . Aunque el modo encadenado inicia de forma implcita las transacciones con instrucc iones de recuperacin o modificacin de datos, slo puede anidar transacciones mediant e el uso explcito de instrucciones begin transaction . Una vez que comienza la pr imera transaccin implcitamente, las instrucciones de recuperacin o modificacin de da tos posteriores dejan de iniciar transacciones hasta despus de que la primera tra nsaccin se consigne o aborte. Por ejemplo, en la siguiente consulta, la primera i nstruccin commit transaction consigna todos los cambios en modo encadenado; la se gunda instruccin commit no es necesaria: insert into publishers values ('9999', null, null, null) insert into publishers values ('9997', null, null, null) commit transaction c ommit transaction Note: En el modo encadenado, una instruccin de recuperacin o modificacin de datos i nicia una transaccin independientemente de que se ejecute de forma correcta. Incl uso una instruccin select que no acceda a una tabla comienza una transaccin. Puede verificar la variable global @@tranchained para determinar el modo de tran saccin actual de SQL Server. select @@tranchained devuelve 0 para el modo no enca denado 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 cua ndo se ejecutan transacciones concurrentes. Los niveles ms altos incluyen las res tricciones impuestas por los niveles ms bajos: El nivel 0 evita que otras transacciones cambien los datos que ya han sido modif icados (mediante insert , delete , update , etc.) por una transaccin no consignad a. Las otras transacciones se bloquean para que no modifiquen los datos hasta qu e la transaccin se haya consignado. No obstante, las otras transacciones todava pu eden 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 tra nsaccin 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 trans accin 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 lect ura. 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 condici ones 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 transaccione s sea 3 para evitar las lecturas sucias, no repetidas y fantasma. Para imponer e

ste 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 n ivel de aislamiento al principio de cada sesin. Sin embargo, el uso de transactio n 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, es e nivel de aislamiento permanece en efecto para cualquier instruccin de recuperac in o modificacin de datos que inicie una transaccin de forma implcita. En ambos caso s, esto puede originar problemas de concurrencia para algunas aplicaciones, ya q ue 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 aplica ciones no afectadas por las lecturas sucias pueden presenciar una concurrencia m enos problemtica y un nivel de bloqueo insoluble reducido cuando acceden a los mi smos datos. Un ejemplo es una aplicacin que halla el saldo promedio momentneo de t odas las cuentas de ahorro almacenadas en un tabla. Dado que slo necesita una cap tacin instantnea del saldo promedio actual, que probablemente cambia con frecuenci a en una tabla activa, la aplicacin debera consultar la tabla con un nivel de aisl amiento 0. Las aplicaciones que precisen una consistencia de datos, como los ing resos 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 tr ansacciones 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 c erciorndose de que se han ledo los datos correctos antes de modificarlos. La variable global @@isolation contiene el nivel de aislamiento actual de la ses in 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 isolat ion con las instrucciones select o readtext . Las opciones read uncommitted , re ad committed y serializable de at isolation representan cada nivel de aislamient o al igual que se indica a continuacin: Opcin de at isolation Nivel de aislamiento read uncommited 0 read committed

1 serializable 3

Por ejemplo, las dos instrucciones siguientes consultan la misma tabla con los n iveles 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 a t 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 opci ones para at isolation (y set transaction isolation level ). Una extensin Transac t-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 est e manual no usan esta extensin. Tambin puede imponer el nivel de aislamiento 3 usando la palabra clave holdlock d e la instruccin select . Sin embargo, no es posible especificar holdlock , nohold lock 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 aislami ento 0) y esta clusula tiene prioridad sobre el nivel de sesin definido por set tr ansaction isolation level . Cursores y niveles de aislamiento Puede utilizar la clusula at isolation de la instruccin select para cambiar el niv el de aislamiento de un cursor. Por ejemplo: declare commit_crsr cursor for select * from titles at isolation read commit ted Esta instruccin hace que el cursor funcione con el nivel de aislamiento 1, sea cu al sea el nivel de la transaccin o sesin. Si declara un cursor con el nivel de ais lamiento 0 ( read uncommitted ), SQL Server tambin define el cursor como de slo le ctura. No es posible especificar la clusula for update con at isolation read unco mmitted en una instruccin declare cursor . SQL Server establece el nivel de aislamiento de un cursor al abrirlo, no al decl ararlo. 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 r

eemplaza 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 a islamiento 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 sob re esta restriccin y los distintos tipos de cursores, consulte el Manual de Refer encia de SQL Server. Procedimientos almacenados y niveles de aislamiento Los procedimientos almacenados del sistema de Sybase siempre funcionan con el ni vel de aislamiento 1, sea cual sea el nivel de la transaccin o sesin. Los procedim ientos 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 procedi miento 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 aislamien to del disparador en 1 antes de ejecutar su primera instruccin. #endregion #region Uso de transacciones en procedimientos almacenados y disparadores Es posible utilizar transacciones en procedimientos almacenados y disparadores d el 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 encade nado) inicia la transaccin del lote, procedimiento almacenado o disparador. Cada begin transaction subsiguiente aumenta el nivel de anidacin. Cada commit transact ion subsiguiente reduce el nivel de anidacin hasta que alcanza el 0. A continuacin , SQL Server consigna la transaccin completa. rollback transaction aborta la tran saccin 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 . Es to tambin se aplica a los procedimientos almacenados que utilizan el modo encaden ado. 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 instruccione s de transaccin dentro de procedimiento almacenados: Figure 17-5: Anidacin de instrucciones de transaccin Las instrucciones rollback transaction incluidas en procedimientos almacenados n o afectan a las instrucciones subsiguientes del procedimiento o lote que llam ori ginalmente al procedimiento. SQL Server ejecuta las instrucciones subsiguientes

del procedimiento almacenado o lote. Sin embargo, las instrucciones rollback tra nsaction en disparadores abortan el lote a fin de que las instrucciones subsigui entes no se ejecuten. Por ejemplo, el siguiente lote llama al procedimiento almacenado myproc que incl uye una instruccin rollback transaction : begin tran update titles set ... insert into titles ... execute myproc te titles where ... Las instrucciones update e insert se revierten y la transaccin se aborta. ver contina el lote y ejecuta la instruccin delete . Sin embargo, si hay ador insert en una tabla que incluye rollback transaction , se aborta todo te y delete no se ejecuta. Por ejemplo: dele SQL Ser un dispar el lo

begin tran update authors set ... insert into authors ... delete authors whe re ... El uso de diferentes modos o niveles de aislamiento de transaccin para procedimie ntos almacenados tiene determinados requisitos, que se describen en la siguiente seccin. Los disparadores no se ven afectados por el modo de transaccin actual, pu esto 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 l as 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 t oda 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 ll amar a procedimientos almacenados escritos para usar el mismo modo. Las excepcio nes a dicha regla son los procedimientos almacenados del sistema SYBASE (que no incluyen a sp_procxmode descrito ms adelante), que pueden ser llamados por sesion es que utilizan cualquier modo de transaccin. Si no hay ninguna transaccin activa al ejecutar un procedimiento almacenado del sistema, SQL Server desactiva el mod o 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 ("encadena do" o "no encadenado") de la sesin en la que se crean. Esto ayuda a evitar proble mas asociados con transacciones que utilizan un modo que invocan otras transacci ones 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 ca da 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 p roporciona una tercera etiqueta, "anymode" ("cualquier etiqueta"), que puede uti lizar con sp_procxmode para sealar los procedimientos del sistema que pueden ejec utarse 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 t odos los procedimientos almacenados de la base de datos actual: sp_procxmode procedure name transaction mode ------------------------------------------- byroyalty Unchained discount_proc Unchained insert_sales_proc Unchained insert_salesdetail_pr oc Unchained storeid_proc Unchained storename_proc Unchained title_proc Unchained titleid_proc 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 admin istrador del sistema, el propietario de la base de datos o el propietario del pr ocedimiento. #endregion #region 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 consignac in o reversin de esa transaccin cierra automticamente todos los cursores abiertos as ociados a ella. Para imponer este comportamiento compatible con las normas SQL, SQL Server propo rciona la opcin close on endtran del comando set . Adems, si se activa el modo enc adenado, SQL Server inicia una transaccin cuando se abre un cursor y cierra el cu rsor cuando la transaccin se consigna o revierte. Por ejemplo, la siguiente secuencia de instrucciones genera de forma predetermin ada 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 ha sta 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 bloqu eo de pgina actual permanece en efecto. Asimismo, el cursor podra continuar adquir iendo bloqueos conforme recobrara filas adicionales. #endregion #region 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 instrucc iones SQL, se registran de forma automtica en la tabla del sistema syslogs . A es ta tabla se le llama diario de transacciones . Algunos comandos que cambian la base de datos no se registran, como truncate tab le , 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 c ada pocos segundos. Cuando comienza una transaccin, se registra un evento begin t ransaction en el diario. Las instrucciones de modificacin de datos se registran e n el diario conforme se reciben. El cambio siempre se registra en el diario antes de que se realice ningn cambio e n la base de datos en s. Este tipo de diario, llamado registro de escritura antic ipada, 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, proble mas del software de sistema, problemas del software de aplicacin, cancelaciones d e transacciones dirigidas por el programa o decisiones de usuario de cancelar un a transaccin. En caso de generarse alguno de estos fallos, el diario de transacciones puede re producirse frente a una copia de la base de datos restaurada a partir de una cop ia de seguridad realizada con los comandos dump . Para recuperarse de un fallo, las transacciones que estaban en in consignar, en el momento del fallo deben deshacerse, puesto parcial no es un cambio exacto. Las transacciones finalizadas i no hay garanta de que se hayan escrito en el dispositivo de proceso, pero an s que una transaccin deben rehacerse s bases de datos.

Si hay transacciones activas de larga duracin todava sin consignar en el momento e n que SQL Server falla, el proceso para deshacer los cambios puede necesitar tan to tiempo como el invertido en ejecutar la transaccin. Estos casos incluyen trans acciones que no contienen commit transaction ni rollback transaction para que co incidan 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 tran sacciones con los comandos dump , aunque el permiso para ejecutarlos puede trans ferirse a otros usuarios. Sin embargo, el permiso para utilizar los comandos loa d 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 as pectos 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 necesar io con el comando checkpoint . Para obtener ms informacin, consulte el Manual de Referencia de SQL Server y la Gua

de Administracin del Sistema . #endregion #endregion

Das könnte Ihnen auch gefallen