Manual Transact SQL
Manual Transact SQL
A
TRANSACT SQL
Dto Programacin
Merlos-Infor, SL
2009
Luis M Caballero
Pgina 2
2009
Las desventajas de SQL son pocas comparadas a las ventajas, y van ms por el lado
comercial y por lo complejo que puede ser el acceso a los comandos desde la consola.
Versin
1.0 (OS/2)
4.21 (NT)
6.0
6.5
7.0
8.0
8.0
9.0
10.0
Ao
1989
1993
1995
1996
1998
1999
2000
2003
2005
2008
Code Name
SQL95
Hydra
Sphinx
Platn
Shiloh
Liberty
Yukon
Katmai
Luis M Caballero
Pgina 3
2009
Luis M Caballero
Pgina 4
2009
*/
declare @nombrevar varchar(50)
set @nombre = 'valordelavariable'
print @Nombre
La intercalacin puede definirse a diferentes niveles segn nos interese en cada caso.
Puede definirse a nivel de servidor de BD, a nivel de la BD, a nivel de tabla, a nivel del
Luis M Caballero
Pgina 5
2009
campo de texto dentro de la tabla o nivel de la consulta. Al margen del primer caso que
es para tener una poltica general para todas ellas, las otras se aplicaran una u otra
segn nuestras necesidades:
Luis M Caballero
Pgina 6
2009
de forma de no dejar activa ninguna opcin de intercalacin. Esto nos servir para que
en el caso de que creemos una base de datos tipo TEST, se crear con la misma
intercalacin que las bases de datos que monta Eurowin. Esto nos evitar problemas
en el caso de UPDATES combinados entre tablas con diferentes Intercalaciones.
Luis M Caballero
Pgina 7
2009
Como avanzadilla sobre los que nos vendr, en SQL SERVER 2008, aparece el
tipo DATE, que a diferencia de DATETIME que ocupa 4 bits, el DATE ocupar 3, y
slo guardar la fecha.
En Eurowin, sobre la versin 2008, los campos de tipo fecha son traducidos al tipo
DATE. Con esto se consiguen las siguientes ventajas:
- Rango totalmente ampliado (1/1/0001 31/12/9999). Evitamos el problema del
2005 por fuera de rango
Luis M Caballero
Pgina 8
2009
Los campos de tipo DATE ocupan menos bytes que los campos de tipo
SMALLDATETIME, por tanto ocupa menos espacio en la base de datos y por
tanto se traduce en una optimizacin a nivel de base de datos
Eurowin no tiene que hacer un proceso adicional de conversin entre fechas de
tipo Datetime a Date y por tanto aumentamos velocidad.
Binary. Se utiliza para almacenar datos binarios de longitud fija, con una
longitud mxima de 8000 bytes.
Varbinary. Se utiliza para almacenar datos binarios de longitud variable, con
una longitud mxima de 8000 bytes..Es muy similar a binary, salvo que
varbinary utiliza menos espacio en disco.
Varbinary(max).Igual que varbinary, pero puede almacenar 231-1 bytes
Luis M Caballero
Pgina 9
2009
SELECT @nombre=nombre ,
@direccion=direccion,
@poblacion=poblacion
FROM CLIENTES
WHERE codigo = 430000125
PRINT @nombre
PRINT @direccion
PRINT @poblacion
Pgina 10
2009
Operadores
=
Operadores aritmticos
+ (suma)
- (resta)
* (multiplicacin)
/ (divisin)
** (exponente)
% (modulo)
Operador
concatenacin
Otros
AND (y lgico)
NOT (negacion)
OR (o lgico)
& (AND a nivel de bit)
| (OR a nivel de bit)
^ (OR exclusivo a nivel de bit)
de +
ALL (Devuelve TRUE si el conjunto completo de
comparaciones es TRUE)
ANY(Devuelve TRUE si cualquier elemento del conjunto
de comparaciones es TRUE)
BETWEEN (Devuelve TRUE si el operando est dentro
del intervalo)
EXISTS (TRUE si una subconsulta contiene filas)
IN (TRUE si el operando est en la lista)
LIKE (TRUE si el operando coincide con un patron)
NOT (Invierte el valor de cualquier operador booleano)
SOME(Devuelve TRUE si alguna de las comparaciones
de un conjunto es TRUE)
Luis M Caballero
Pgina 11
2009
BEGIN
...
END
ELSE IF (<expresion>)
BEGIN
...
END
ELSE
BEGIN
...
END
@diminutivo = 'EW'
BEGIN
PRINT 'www.eurowin.com'
END
ELSE
BEGIN
PRINT 'Otro software '
END
Luis M Caballero
Pgina 12
2009
END
Ejemplo de CASE.
DECLARE @Soft varchar(100),
@diminutivo varchar(2)
SET @diminutivo = 'EW'
SET @Soft = (CASE @diminutivo
WHEN 'EW' THEN 'www.eurowin.com'
WHEN 'TW' THEN 'www.eurowintuweb.com'
ELSE 'www.millorsoft.es'
END)
PRINT @Soft
Bucle WHILE
El bucle WHILE se repite mientras expresion se evalue como verdadero.
Es el nico tipo de bucle del que dispone Transact SQL.
WHILE <expresion>
BEGIN
...
END
Luis M Caballero
Pgina 13
2009
IF (@contador % 2 = 0)
CONTINUE
PRINT 'Iteracion del bucle ' + cast(@contador AS varchar)
END
El bucle se dejar de repetir con la instruccin BREAK.
DECLARE @contador int
SET @contador = 0
WHILE (1 = 1)
BEGIN
SET @contador = @contador + 1
IF (@contador % 50 = 0)
BREAK
PRINT 'Iteracion del bucle ' + cast(@contador AS varchar)
END
Estructura GOTO
La sentencia GOTO nos permite desviar el flujo de ejecucin hacia una etiqueta.
DECLARE @divisor int,
@dividendo int,
@resultado int
SET @dividendo = 100
SET @divisor = 0
SET @resultado = @dividendo/@divisor
IF @@ERROR > 0
GOTO error
PRINT 'No hay error'
RETURN
error:
PRINT 'Se ha producido una division por cero'
Luis M Caballero
Pgina 14
2009
La sentencia SELECT nos permite consultar los datos almacenados en una tabla de la
base de datos.
El formato de la sentencia select es:
SELECT [ALL | DISTINCT ][ TOP expression [ PERCENT ] [ WITH TIES ] ]
<nombre_campos>
FROM <nombre_tabla>
[ INNER | LEFT [OUTER]| RIGHT [OUTER] | CROSS]
[JOIN ] <nombre_tabla> ON <condicion_join>[ AND|OR <condicion>]
[WHERE <condicion> [ AND|OR <condicion>]]
[GROUP BY <nombre_campos>]
[HAVING <condicion>[ AND|OR <condicion>]]
[ORDER BY <nombre_campo> [ASC | DESC]
El siguiente ejemplo muestra una consulta sencilla que obtiene el cdigo y el nomnbre
de la "familia" de una tabla llamada familias (representara familias de productos por
ejemplo).
SELECT CODIGO, NOMBRE
FROM [2008V8].[dbo].FAMILIAS
El uso del asterisco indica que queremos que la consulta devuelva todos los campos
que existen en la tabla.
SELECT * FROM [2008V8].[dbo].FAMILIAS
Ahora vamos a realizar una consulta obteniendo adems de los datos de familias, las
subfamilias asociadas a las familias y los productos.
SELECT *
FROM [2008V8].[dbo].FAMILIAS
INNER JOIN [2008V8].[dbo].SUBFAM
ON SUBFAM.FAMILIA = FAMILIA.CODIGO
INNER JOIN [2008V8].[dbo].ARTICULO
ON ARTICULO.FAMILIA = FAMILIA.CODIGO
Los registros que no tengan datos relacionados en una consulta LEFT JOIN
devolvern en valor NULL en los campos que correspondan a las tablas en las que no
tienen dato.
Tambin podemos forzar un producto cartesiano (todos con todos) a travs de CROSS
JOIN o FULL JOIN (a partir de SQL 2000)
Luis M Caballero
Pgina 15
2009
SELECT *
FROM [2008V8].[dbo].FAMILIAS
CROSS JOIN [2008V8].[dbo].SUBFAM
SELECT *
FROM [2008V8].[dbo].FAMILIAS
FULL JOIN [2008V8].[dbo].SUBFAM
La clusula WHERE
La clusula WHERE es la instruccin que nos permite filtrar el resultado de una
sentencia SELECT.
SELECT CODIGO, NOMBRE
FROM [2008V8].[dbo].FAMILIAS
WHERE CODIGO='001'
La clausula WHERE se puede utilizar conjuntamente con INNER JOIN, LEFT JOIN ...
SELECT FAMILIAS.CODIGO, FAMILIAS.NOMBRE
FROM [2008V8].[dbo].FAMILIAS
INNER JOIN [2008V8].[dbo].SUBFAM
ON SUBFAM.FAMILIA = FAMILIA.CODIGO
WHERE FAMILIAS.CODIGO IN ('001','002','099')
Luis M Caballero
Pgina 16
2009
_ representa un caracter.
SELECT CODIGO, NOMBRE
FROM [2008V8].[dbo].FAMILIAS
WHERE NOMBRE LIKE 'REFRESCO_'
La clausula TOP se puede combinar con WITH TIES en consultas agregadas. Este
punto lo veremos propiamente en las consultas agregadas.
La clusula ORDER BY
Luis M Caballero
Pgina 17
2009
La clusula GROUP BY
La clausula GROUP BY combina los registros devueltos por una consulta SELECT
obteniendo uno o varios valores agregados(suma, valor mnimo y mximo ...).
Para cada registro se puede crear un valor agregado si se incluye una funcin SQL
agregada, como por ejemplo Sum o Count, en la instruccin SELECT. Su sintaxis es:
SELECT [ALL | DISTINCT ] [TOP <n> [WITH TIES]]
<nombre_campo> [{,<nombre_campo>}]
[{,<funcion_agregado>}]
FROM <nombre_tabla>|<nombre_vista>
[{,<nombre_tabla>|<nombre_vista>}]
[WHERE <condicion> [{ AND|OR <condicion>}]]
[GROUP BY <nombre_campo> [{,<nombre_campo >}]]
[HAVING <condicion>[{ AND|OR <condicion>}]]
[ORDER BY <nombre_campo>|<indice_campo> [ASC | DESC]
[{,<nombre_campo>|<indice_campo> [ASC | DESC ]}]]
En este otro se muestra la suma del IMPORTE de cada uno de los productos que
componen un pedido, para calcular el total del pedido agrupado por el numero de
pedido.
SELECT EMPRESA, LETRA, NUMERO, SUM(IMPORTE)AS IMPORTE
FROM D_PEDIVE
GROUP BY EMPRESA, LETRA, NUMERO
Sql Server nos obliga a que en la agrupacin aparezcan todos los campos no
agrupados que hay en la consulta.
En el siguiente ejemplo veremos cmo aadir un campo ms a la consulta sin la
necesidad de que se agrupe.
SELECT EMPRESA, CUENTA, DATEPART(QQ,FECHA) AS TRIMESTRE, MAX(NUMERO)
AS CAMPO2,
SUM(DEBE)AS TOT_DEBE, SUM(HABER) AS TOT_HABER
Luis M Caballero
Pgina 18
2009
Siempre que incluyamos una clausula WHERE en una consulta agregada esta se
aplica antes de calcular el valor agregado. Es decir, si sumamos el valor de las ventas
por producto, la suma se calcula despus de haber aplicado el filtro impuesto por la
clausula WHERE.
SELECT EMPRESA, LETRA, NUMERO, SUM(IMPORTE)AS IMPORTE
FROM D_PEDIVE
WHERE EMPRESA='01'
GROUP BY EMPRESA, LETRA, NUMERO
La clusula HAVING
Es posible que necesitemos calcular un agregado, pero que no necesitemos obtener
todos los datos, solo los que cumplan una condicin del agregado. Por ejemplo,
podemos calcular el valor de las ventas por producto, pero que solo queramos ver los
datos de los pedidos que el importe sea mayor de 150. En estos casos se debe usar la
clausula HAVING.
Una vez que GROUP BY ha combinado los registros, HAVING muestra cualquier
registro agrupado por la clusula GROUP BY que satisfaga las condiciones de la
clusula HAVING. Se utiliza la clusula WHERE para excluir aquellas filas que no
desea agrupar, y la clusula HAVING para filtrar los registros una vez agrupados.
SELECT EMPRESA, LETRA, NUMERO, SUM(IMPORTE)AS IMPORTE2
FROM D_PEDIVE
WHERE EMPRESA='01'
GROUP BY EMPRESA, LETRA, NUMERO
HAVING SUM(IMPORTE) >150
Funciones agregadas.
Transact SQL pone a nuestra disposicin mltiples funciones agregadas, las ms
comunes usaremos son:
Count
Calcula el nmero de registros devueltos por una consulta. Su sintaxis es la siguiente:
COUNT(<expr>)
En donde expr contiene el nombre del campo que desea contar. Los operandos de
expr pueden incluir el nombre de un campo de una tabla, una constante o una funcin
(la cual puede ser intrnseca o definida por el usuario pero no otras de las funciones
agregadas de SQL). Puede contar cualquier tipo de datos incluso texto.
Count simplemente cuenta el nmero de registros sin tener en cuenta qu valores se
almacenan en los registros. La funcin Count no cuenta los registros que tienen
campos null a menos que expr sea el carcter comodn asterisco (*).
SELECT COUNT(*) FROM D_PEDIVE
Luis M Caballero
Pgina 19
2009
Max, Min
Devuelven el mnimo o el mximo de un conjunto de valores contenidos en un campo
especifico de una consulta. Su sintaxis es:
MIN(<expr>)
MAX(<expr>)
Sum
Devuelve la suma del conjunto de valores contenido en un campo especifico de una
consulta. Su sintaxis es:
SUM(<expr>)
En donde expr respresenta el nombre del campo que contiene los datos que desean
sumarse o una expresin que realiza un clculo utilizando los datos de dichos campos.
SELECT EMPRESA, LETRA, NUMERO, SUM(IMPORTE)AS IMPORTE
FROM D_PEDIVE
GROUP BY EMPRESA, LETRA, NUMERO
Luis M Caballero
Pgina 20
2009
Las consultas a unir deben tener el mismo nmero campos, y adems los
campos deben ser del mismo tipo.
UNION
UNION devuelve la suma de dos o ms conjuntos de resultados. El conjunto obtenido
como resultado de UNION tiene la misma estructura que los conjuntos originales
El siguiente ejemplo muestra el uso de UNION
SELECT CODIGO, NOMBRE, DIRECCION
FROM CLIENTES
UNION
SELECT CODIGO, NOMBRE, DIRECCION
FROM PROVEED
El siguente ejemplo, en el campo direccin del resultado nos rellenar el campo CIF
en los resultados correspondientes a PROVEED
SELECT CODIGO, NOMBRE, DIRECCION
FROM CLIENTES
UNION
SELECT CODIGO, NOMBRE, CIF
FROM PROVEED
El siguente ejemplo, devolver un error, dado que als consultas con UNION el numero
de campos a consultar en cada tabla debe de ser el mismo.
SELECT CODIGO, NOMBRE, DIRECCION
FROM CLIENTEs
UNION
SELECT CODIGO, NOMBRE, DIRECCION, CIF
FROM PROVEED
Cuando realizamos una consulta con UNION internamente se realiza una operacion
DISTINCT sobre el conjunto de resultados final. Si queremos obtener todos los valores
debemos utiliza UNION ALL.
SELECT CODIGO, NOMBRE, DIRECCION
FROM CLIENTES
UNION ALL
SELECT CODIGO, NOMBRE, DIRECCION
FROM PROVEED
EXCEPT
EXCEPT devuelve la diferencia (resta) de dos o ms conjuntos de resultados. El
conjunto obtenido como resultado de EXCEPT tiene la misma estructura que los
conjuntos originales.
Luis M Caballero
Pgina 21
2009
Este ejemplo devolver la consulta de la tabla de CUENTAS sin las cuentas que se
encuentren en la tabla CLIENTES
El uso de EXCEPT, como norma general, es mucho ms rpido que utilizar
condiciones NOT IN o EXISTS en la clausula WHERE.
INTERSECT
Devuelve la interseccin entre dos o ms conjuntos de resultados en uno. El conjunto
obtenido como resultado de INTERSECT tiene la misma estructura que los conjuntos
originales.
El siguiente ejemplo muestra el uso de INTERSECT
SELECT CODIGO, NOMBRE
FROM CUENTAS
INTERSECT
SELECT CODIGO, NOMBRE
FROM CLIENTES
las
Luis M Caballero
Pgina 22
2009
En SQL Sever podemos marcar un campo de una tabla como autonumrico (identity),
cuando insertamos un registro en dicha tabla el valor del campo se genera
automticamente. Para recuperar el valor generado disponemos de varios mtodos:
Luis M Caballero
Pgina 23
2009
Luis M Caballero
Pgina 24
2009
Un aspecto a tener en cuenta, es que SQL graba los cambios inmediatamente sin
necesidad de hacer COMMIT. Por supuesto podemos gestionar nosotros las
transacciones pero es algo que hay que hacer de forma explcita con la instruccin
BEGIN TRAN y que se ver en un curso ms avanzado de T-SQL.
Update INNER JOIN
Luis M Caballero
Pgina 25
2009
En ocasiones queremos actaualizar los datos de una tabla con los datos de otra.
Habitualmente, usamos subconsultas para este proposito, pero Transact SQL permite
la utilizacin de la sentencia UPDATE INNER JOIN.
UPDATE D_ALBVEN
SET
FAMILIA=ARTICULO.FAMILIA
FROM D_ALBVEN
INNER JOIN ARTICULO
ON ARTICULO.CODIGO=D_ALBVEN.ARTICULO
Clausula OUTPUT
El uso de sta clausula es idntico al que hemos visto en el apartado anterior.
Guardar los datos antes de actualizar o borrar.
DECLARE @FILAS_ACTUALIZADAS TABLE
( codigo char(2), nombre char(30), vista bit)
UPDATE ACTIVI
SET
NOMBRE='INSTALADOR DE GAS'
OUTPUT DELETED. * INTO @FILAS_ACTUALIZADAS
WHERE CODIGO='56'
SELECT * FROM @FILAS_ACTUALIZADAS
GO
Donde:
Luis M Caballero
Pgina 26
2009
style, parametro opcional que especifica el formato que tiene expresion. Por
ejemplo, si queremos convertir un varchar a datetime, aqui debemos especificar el
formato de la fecha (el tipo varchar).
Veamos unos ejemplos:
DECLARE @fecha varchar(20)
-- Convertimos un valor varchar a datetime
-- El 103 indica el formato en el que esta escrita la fecha
-- 103 => dd/mm/aaaa
SET @fecha = CONVERT(datetime, '19/03/2008',103)
SELECT @fecha
Donde:
Luis M Caballero
Pgina 27
2009
http://technet.microsoft.com/es-es/library/ms187928.aspx
Isnull
Evalua una expresion y si esta es NULL, reemplaza NULL con el valor de reemplazo
especificado. El valor de reemplazo debe ser del mismo tipo de datos que la expresion
a evaluar.
ISNULL ( expresin , valor_de_reemplazo )
Veamos un ejemplo.
update articulo set ult_fecha =
isnull(ult_fecha, convert(datetime,'31/05/09'))
GetDate y GetUTCDate
GetDate devuelve la fecha y hora actuales del sistema en el formato interno estndar
de SQL Server 2005 para los valores datetime.
GetUTCDate devuelve el valor datetime que representa la hora UTC (hora universal
coordinada u hora del meridiano de Greenwich) actual.
Veamos un elemplo
DECLARE @fechaLocal datetime,
@fechaUTC datetime
SET @fechaLocal = getdate()
SET @fechaUTC = GETUTCDATE()
SELECT @fechaLocal, @fechaUTC
Nos devuelve:
2009-10-05 12:53:14.263
2009-10-05 10:53:14.263
Datepart
Datepart devuelve un entero referido a la parte de una fecha o de una hora.
DATEPART ( argumento , fecha )
Sinedo :
Veamos un ejemplo:
DECLARE @Trimestre int,
@Diadelao int, @semana int
set @Trimestre = DATEPART( qq, getdate() )
Luis M Caballero
Pgina 28
2009
Nos devolver:
Trimestre
dia_del_ao semana
4
278
41
EXECUTE o EXEC:
Ejecuta una cadena de comandos o una cadena de caracteres que contienen un
proceso por lotes de Transact-SQL
La sintaxis es la siguiente
-- Ejecuta un string o cadena de caracteres:
{ EXEC | EXECUTE }
( { @string_variable | [ N ]'tsql_string' } [ + ...n ] )
[ AS { LOGIN | USER } = ' name ' ]
[;]
[N] 'tsql_string'
Es una cadena de constante. tsql_string puede ser del tipo de datos nvarchar o
varchar. Si se incluye N, la cadena se interpreta como del tipo de datos nvarchar.
Ejemplo:
EXEC(
Luis M Caballero
Pgina 29
2009
ROLLUP:
El operador ROLLUP es til para generar informes con subtotales y totales de forma
automtica. Nos presenta los totales agrupados por los campos del group by.
select cliente,articulo ,sum(unidades) as unidades, sum(importe) as
importe
from d_albven
group by cliente, articulo
with rollup
CUBE:
El operador CUBE es til para generar un conjunto de resultados que es un cubo
multidimensional.
select cliente,articulo ,sum(unidades) as unidades, sum(importe) as
importe
from d_albven
group by cliente, articulo
with cube
Ahora podemos ejecutar las dos consultas juntas, de forma que analizaremos los
resultados:
Luis M Caballero
Pgina 30
2009
Cierra el cursor
CLOSE <nombre_cursor>
Luis M Caballero
Pgina 31
2009
use [master]
go
declare @nombreBBDD nvarchar(128), @sentenciaSQL nvarchar(max)
DECLARE cursorBBDD CURSOR read_only fast_forward forward_only
FOR (SELECT name FROM sys.databases where database_id>4)
OPEN cursorBBDD
FETCH NEXT FROM cursorBBDD
INTO @nombreBBDD
WHILE @@FETCH_STATUS = 0
BEGIN
set @sentenciaSQL = 'DBCC SHRINKDATABASE(N'''+ @nombreBBDD +''')
;'
exec(@sentenciaSQL)
FETCH NEXT FROM cursorBBDD
into @nombreBBDD
END
CLOSE cursorBBDD
DEALLOCATE cursorBBDD
Descripcin
La instruccin FETCH se ejecut correctamente.
La instruccin FETCH no se ejecut correctamente o la fila
estaba ms all del conjunto de resultados.
Falta la fila recuperada.
Luis M Caballero
Pgina 32
2009
Luis M Caballero
Pgina 33
2009
Luis M Caballero
Pgina 34
2009
Anexos:
TRUCOS Y CURIOSIDADES:
Dar formato a un numero:
De una tabla con cdigos de cliente numrico, convertirlos a cdigos de cliente de
Eurowin.
DECLARE @num int, @nivel3 varchar(3),
@formato varchar(5),@expresion varchar(8)
SET @nivel3 = '430'
SET @formato = '00000'
SET @num = 2002
SET @expresion = @nivel3 + RIGHT( @formato + cast(@num AS varchar), 5)
SELECT @expresion
Esto puede ser muy til si hemos de borra un archivo del disco duro desde la consola
del MSSMS, o ejecutar un comando de consola de DOS, como por ejemplo el BCP.
Uso de trazas y anlisis de trazas
Podemos ejecutar trazas (profiles) en el servidor de SQL Server para visualizar todas
las llamadas que se ejecutan sobre la Base de Datos.
Luis M Caballero
Pgina 35
2009
Otro dellate para estudiar son las lecturas y escrituras. Las trazas permiten
visualizar los accesos que tenemos en disco fsico (lecturas u escrituras). Si
tenemos altas lecturas u escrituras podemos optimizar las consultas o aadir
ndices en las tablas donde participa.
Y por finalizar, dira que gracias a las trazas nos permiten realizar un pequeo
debug. Si estamos programando aplicaciones que trabajan con storeds
puede sernos til lanzar una traza, recoger la llamada del stored con todos sus
parmetros y ejecutar la consulta en el Query analyzer.
Luis M Caballero
Pgina 36
2009
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%NOMBRE2%'
GO
COALESCE
Luis M Caballero
Pgina 37