Transact SQL 2005
zahedls31 de Mayo de 2012
2.980 Palabras (12 Páginas)535 Visitas
Transact SQL 2005
________________________________________
Este documento describe las nuevas caracteristicas de T-SQL para SQL Server 2005.
________________________________________
Introduccion
Microsoft Sql Server 2005 (YUKON) es un producto con muchas novedades comparándolo con su antecesor SQL 2000. Sin duda que uno de sus mayores cambios ha sido la inclusión del CLR dentro del motor de base de datos.
En este artículo nos concentraremos en algunas de las tantas novedades que nos trae Microsoft SQL 2005 en lo que respecta a Transact-SQL, las cuales serán de mucha utilidad para los desarrolladores de aplicaciones como así también para los DBA.
Transact SQL (TSQL) es el lenguaje que usamos para escribir : Store Procedures – Triggers – Querys – Etc.
Sin dudas que TSQL no dispone de las mismas habilidades y potencia que puede tener un lenguaje como C# o VB.NET. En Sql2005 veremos un cambio significativo en TSQL el cual nos ayudara en nuestro trabajo diario.
Antes de empezar les recomiendo que descarguen la versión Beta de Sql-Server June 2005 del siguiente link:
http://www.microsoft.com/downloads/details.aspx?FamilyId=B414B00F-E2CC-4CAB-A147-EACA26740F19&displaylang=en
Recomiendo que dicha instalación se realice en un ambiente de testing como podría ser una maquina Virtual.
Numerando Registros (RowId):
En muchas ocasiones es necesario poder obtener una columna con el número de registro o también poder generar un ranking. Hasta SQL2000 este tipo de operaciones no eran tan simples de realizar y no disponíamos de instrucciones directas. En TSQL 2005 disponemos de una serie de instrucciones las cuales nos hacen el trabajo mucho mas simple y eficiente. Veamos de qué se trata ello.
Row_Number: Esta nueva función de TSQL nos permitirá numerar los resultados de una query.
El siguiente ejemplo muestra el uso de esta función:
Use AdventureWorks
Go
Select row_number() over(order by name) as rowid,
name,productNumber,productId from Production.product where productnumber like 'be%'
order by name
El resultado obtenido de esta query es el siguiente:
rowid name productNumber productId
-------- -------------------------------------------------- ------------------------- ---------
1 BB Ball Bearing BE-2349 3
2 Headset Ball Bearings BE-2908 4
A las funciones de numeración como Row_number() le podemos agregar la cláusula Partition la cual nos permitirá numerar pero haciendo un corte y reiniciando el numerador a partir de ese corte. En el siguiente ejemplo hacemos uso de ello:
Use AdventureWorks
Go
Select row_number() over(partition by color order by name) as rowid,
name,productNumber,productId,color from Production.product
where color in ('Blue','Silver')
order by color,name
Este ejemplo nos retornara un listado de productos donde el color sea Blue o Silver y los numerara con rowid pero al cambiar el color el numerador volverá a comenzar.
rowid name productNumber productId color
------- --------------------------------------------- ------------------------- ----------- ---------------
…
25 Touring-3000 Blue, 58 BK-T18U-58 959 Blue
26 Touring-3000 Blue, 62 BK-T18U-62 960 Blue
1 Chain CH-0234 952 Silver
2 Chainring Bolts CB-2903 320 Silver
3 Chainring Nut CN-6137 321 Silver
4 Freewheel FH-2981 332 Silver
…
Conclusiones: La instrucción Row_number() nos da la habilidad de poder numerar los resultados de nuestras querys, este tipo de tareas eran muy solicitadas por los usuarios en la versión 2000 y no existía una solución directa como la que podemos tener ahora con Sql2005. De todas maneras vale aclarar un concepto: Los motores de base de datos están pensados para trabajar en conjunto de registros y no registró a registro, por lo cual les recomiendo que el uso de numeradores lo utilicen con criterio y que no se lo utilice para recorrer registró a registro (cursores).
TOP @n:
Tsql2005 incorpora una nueva funcionalidad a la instrucción TOP, hasta la versión 2000 no se le podía pasar un parámetro variable a la misma, en la versión 2005 esta funcionalidad se ha agregado. El siguiente ejemplo nos muestra como se implementa:
USE ADVENTUREWORKS
GO
DECLARE @NUM INT
SET @NUM = 3
SELECT TOP(@NUM) * FROM PRODUCTION.PRODUCT
En el siguiente ejercicio veremos como podemos utilizar TOP @n para eliminar registros de a grupos:
Use AdventureWorks
Go
IF OBJECT_ID('GRANDE') IS NOT NULL
DROP TABLE GRANDE
GO
CREATE TABLE GRANDE (ID INT IDENTITY,NOMBRE VARCHAR(100), DIRECCION VARCHAR(100))
GO
DECLARE @N INT
SET @N = 1
WHILE @N <= 50000
BEGIN
INSERT INTO GRANDE (NOMBRE,DIRECCION) VALUES ('SQL' + CONVERT(VARCHAR(10),@N),'DIR' + CONVERT(VARCHAR(10),@N))
SET @N = @N+1
END
GO
/* BORRAMOS POR PARTES (DE A 500) USANDO ROWCOUNT Y TOP */
SET ROWCOUNT 500
DELETE TOP(500) FROM GRANDE
WHILE @@ROWCOUNT > 0
DELETE TOP(500) FROM GRANDE
SET ROWCOUNT 0
Conclusiones: Sin lugar a dudas que muchos de los desarrolladores y DBA que venimos trabajando con Sql2000 estábamos reclamando esta funcionalidad del TOP, con la misma como se podrá observar se pueden lograr muchas funcionalidades que antes se debían resolver quizás con SQL-Dinámico.
Control de errores:
Tsql 2005 incorpora al control de errores los bloques TRY..CATH. La administración de errores de esta manera es conocida por los desarrolladores de la actualidad ya que .NET administra de la misma manera. En esta sección les mostrare varios ejemplos de su utilización. Para poder realizar estos ejercicios he creado una tabla de prueba
USE ADVENTUREWORKS
GO
IF OBJECT_ID('EMPLEADOS') IS NOT NULL
DROP TABLE EMPLEADOS
GO
CREATE TABLE EMPLEADOS (ID INT PRIMARY KEY, NOMBRE VARCHAR(30) NOT NULL)
GO
En nuestro primer ejemplo veremos como poder capturar un error al intentar realizar una operación de insert sobre nuestra tabla donde el campo Nombre no admite valores nulos.
BEGIN TRY
INSERT INTO EMPLEADOS VALUES (1,NULL)
PRINT 'PASO EL INSERT'
END TRY
BEGIN CATCH
PRINT 'TENEMOS EL ERROR NUMERO:' + CONVERT(VARCHAR(10),ERROR_NUMBER())
END CATCH
Como podemos observar al suceder un error SQL sale a la sección CATCH donde capturamos el mismo y podemos informar al usuario con algún mensaje. En este ejemplo se hace uso de la función ERROR_NUMBER() las cual nos retorna el número de error, pero también podríamos hacer uso de las siguientes funciones:
ERROR_LINE() : Retorna el número de línea donde se genero el error. El resultado es NULL cuando el error se genero fuera del bloque Try.
ERROR_MESSAGE(): Retorna el texto del error.
ERROR_PROCEDURE(): Retorna el nombre del Procedimiento Almacenado o el Trigger desde donde se ha generado el error en el bloque Try Catch
ERROR_SEVERITY(): Retorna la severidad del error
El siguiente ejemplo genera un error en el primer insert y automáticamente se pasa a la sección Catch sin ejecutar la segunda instrucción, además en el modulo Catch evaluamos el número de error y personificamos el mensaje emitido al usuario.
BEGIN TRY
INSERT INTO EMPLEADOS VALUES ('1',NULL)
INSERT INTO EMPLEADOS VALUES ('1','MAXI')
PRINT 'PASO EL INSERT'
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 515
BEGIN
PRINT ' HAY ALGUNAS COLUMNAS QUE NO ADMITEN NULOS: ' + ERROR_MESSAGE()
END
ELSE IF ERROR_NUMBER() = 8152
BEGIN
PRINT '
...