Mejoras en T-SQL para SQL Server 2005

33,016
-1

Published on

Esta presentación nos muestra las características incluidas en el lenguaje T-SQL en SQL Server 2005 y que no estaban en versiones anteriores

Published in: Technology
1 Comment
20 Likes
Statistics
Notes
  • ngomong opo,,,,,iku!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
33,016
On Slideshare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
0
Comments
1
Likes
20
Embeds 0
No embeds

No notes for slide

Mejoras en T-SQL para SQL Server 2005

  1. 1. Pablo Espada Bueno www.programadorautonomo.net www.esbupa.com
  2. 2. <ul><li>Habitualmente me dedico a impartir formación y a labores de desarrollo y consultoría en .NET </li></ul><ul><li>Si desea que colabore con usted impartiéndoles una formación o desarrollando algún proyecto, puede contactarme: </li></ul><ul><ul><li>Web </li></ul></ul><ul><ul><ul><li>www.programadorautonomo.net </li></ul></ul></ul><ul><ul><ul><li>www.esbupa.com </li></ul></ul></ul><ul><ul><li>Email </li></ul></ul><ul><ul><ul><li>[email_address] </li></ul></ul></ul><ul><ul><ul><li>[email_address] </li></ul></ul></ul><ul><li>Espero que les guste la presentación </li></ul>
  3. 3. <ul><li>Nuevos Tipos de Datos </li></ul><ul><li>Nuevas Características en Indices </li></ul><ul><li>La palabra reservada OUTPUT </li></ul><ul><li>Common Table Expressions </li></ul><ul><li>Operaciones PIVOT y UNPIVOT </li></ul><ul><li>El operador APPLY </li></ul><ul><li>Clausula OVER </li></ul><ul><li>Función RANK </li></ul><ul><li>Función DENSE_RANK </li></ul><ul><li>Función ROW_NUMBER </li></ul><ul><li>Función NTILE </li></ul><ul><li>Gestión Estructurada de Excepciones </li></ul>
  4. 4. <ul><li>Creacíon de campos varchar,nvarchar o varbinary con tamaño máximo de hasta 2^31 Bytes </li></ul><ul><li>El nuevo tipo “xml” permite almacenar documentos de hasta 2 GB </li></ul>CREATE TABLE mySchema.LargeTable (varcharCol varchar(max)) CREATE TABLE mySchema.XMLTable (idCol int, xmlCol xml)
  5. 5. <ul><li>La sentencia ALTER INDEX nos permitirá realizar un conjunto de operaciones básicas sobre índices </li></ul><ul><ul><li>Deshabilitar un índice. Para rehabilitarlo habrá que recompilarlo o eliminarlo </li></ul></ul><ul><ul><li>Recompilar un índice </li></ul></ul><ul><ul><li>Recompilar todos los índices de una tabla </li></ul></ul>ALTER INDEX IX_CustDOB ON Sales.Customer DISABLE ALTER INDEX PK_CustId ON Sales.Customer REBUILD ALTER INDEX ALL ON Sales.Customer REBUILD
  6. 6. <ul><ul><li>Reorganizar (defragmentar) un índice </li></ul></ul><ul><ul><li>Cambiar cualquier valor establecido en la sentencia CREATE INDEX </li></ul></ul><ul><li>SQL Server 2005 permite crear índices no agrupados que incluyan campos que no sean clave </li></ul>ALTER INDEX PK_CustId ON Sales.Customer REORGANIZE CREATE NONCLUSTERED INDEX IX_CustomerPostalCode ON Sales.Customer (PostalCode) INCLUDE (AddressLine1, AddressLine2, City)
  7. 7. <ul><li>OUTPUT permite volcar los resultados de la ejecución de cualquier sentencia SQL en una variable de tipo “tabla” </li></ul><ul><li>Esta palabra clave podrá utilizarse en cualquier sentencia DML excepto: </li></ul><ul><ul><li>INSERT que vayan a insertar datos en vistas </li></ul></ul><ul><ul><li>Operaciones con tablas/vistas remotas </li></ul></ul><ul><ul><li>Operaciones en vistas particionadas </li></ul></ul>
  8. 8. <ul><li>Suponiendo una tabla Stock.ProductList con campos </li></ul><ul><ul><li>ProductID IDENTITY int </li></ul></ul><ul><ul><li>ProductName nvarchar(100) </li></ul></ul><ul><ul><li>Price money </li></ul></ul><ul><li>Veamos algunos ejemplos del uso de OUTPUT con sentencias INSERT, UPDATE y DELETE </li></ul>
  9. 9. DECLARE @InsertDetails TABLE ( ProductID int, InsertedBy sysname ) INSERT INTO Stock.ProductList OUTPUT INSERTED.ProductID, suser_name() INTO @InsertDetails VALUES ('Racing Bike', 412.99) SELECT * FROM @InsertDetails DECLARE @PriceChangeDetails TABLE ( ProductID int, OldPrice money, NewPrice money, UpdatedBy sysname ) UPDATE Stock.ProductList SET Price = 3.99 OUTPUT INSERTED.ProductID, DELETED.Price, INSERTED.Price, suser_name() INTO @PriceChangeDetails WHERE ProductID = 1 SELECT * FROM @PriceChangeDetails DECLARE @DeleteDetails TABLE ( ProductID int, DeletedBy sysname ) DELETE Stock.ProductList OUTPUT DELETED.ProductID, suser_name() INTO @DeleteDetails WHERE ProductID = 2 SELECT * FROM @DeleteDetails
  10. 10. <ul><li>Las CTE’s permiten crear consultas que trabajan con datos recursivos </li></ul><ul><ul><li>Consultas más entendibles </li></ul></ul><ul><ul><li>Implementación de algoritmos recursivos </li></ul></ul>WITH TopSales (SalesPersonID, NumSales) AS ( SELECT SalesPersonID, Count(*) FROM Sales.SalesOrderHeader GROUP BY SalesPersonId ) --Select simple SELECT * FROM TopSales WHERE SalesPersonID IS NOT NULL ORDER BY NumSales DESC --Ejemplo de Join SELECT ts.SalesPersonID, sp.SalesYTD, ts.NumSales FROM Sales.SalesPerson sp INNER JOIN TopSales ts ON ts.SalesPersonID = sp.SalesPersonID ORDER BY NumSales DESC
  11. 11. <ul><li>Las operaciones PIVOT y UNPIVOT están indicadas para la creación de consultas cuyo resultado debe ser una matriz </li></ul><ul><ul><li>Por cada línea de los resultados, tendremos un conjunto variable de columnas que nos mostrarán valores calculados con una función de agregado </li></ul></ul><ul><li>La operación PIVOT nos permite convertir los resultados de una consulta en columnas, mientras que UNPIVOT nos convierte las columnas en resultados </li></ul>
  12. 12. <ul><li>Ejemplo de PIVOT </li></ul><ul><ul><li>Creamos una tabla de Pedidos </li></ul></ul><ul><ul><li>Añadimos los siguientes valores </li></ul></ul>CREATE TABLE Sales.[Order] ( Customer varchar(8), Product varchar(5), Quantity int ) Customer Product Quantity Mike Bike 3 Mike Chain 2 Mike Bike 5 Lisa Bike 3 Lisa Chain 3 Lisa Chain 4
  13. 13. <ul><ul><li>Vamos a realizar una operación de PIVOT sobre la tabla </li></ul></ul><ul><ul><li>El resultado sería </li></ul></ul>SELECT * FROM Sales.[Order] PIVOT (SUM(Quantity) FOR Product IN ([Bike],[Chain])) AS PVT Customer Bike Chain Lisa 3 7 Mike 8 2 Lisa 3 7 Mike 8 2 Lisa 3 7 Mike 8 2
  14. 14. <ul><ul><li>Si realizamos una operación UNPIVOT sobre la tabla Sales.PivotedOrder </li></ul></ul><ul><ul><li>El resultado sería </li></ul></ul>SELECT Customer, Product, Quantity FROM Sales.PivotedOrder UNPIVOT (Quantity FOR Product IN ([Bike],[Chain])) AS UnPVT Customer Product Quantity Mike Bike 8 Mike Chain 2 Lisa Bike 3 Lisa Chain 7
  15. 15. <ul><li>Este operador permite aplicar una función que devuelva una tabla por cada fila de una tabla obtenida por JOIN </li></ul><ul><li>Tenemos 2 tipos de operadores APPLY </li></ul><ul><ul><li>CROSS APPLY </li></ul></ul><ul><ul><ul><li>Sólo se incluirán filas del JOIN que produzcan un resultado en la llamada a la función que devuelve una tabla </li></ul></ul></ul><ul><ul><li>OUTER APPLY </li></ul></ul><ul><ul><ul><li>Se incluirán todas las filas del JOIN </li></ul></ul></ul><ul><li>Normalmente lo que haremos será aplicar una función que tome como parámetros valores de la fila y nos devuelva una nueva tabla </li></ul>
  16. 16. <ul><li>Veamos un ejemplo de uso </li></ul><ul><ul><li>Crearemos una función que nos devuelva los 3 últimos pedidos de un cliente </li></ul></ul><ul><ul><li>Utilizando CROSS APPLY obtendremos el nombre del cliente (y los detalles de los pedidos) sólo de los clientes que hayan realizado algún pedido </li></ul></ul>CREATE FUNCTION Sales.MostRecentOrders(@CustID int) RETURNS TABLE AS RETURN SELECT TOP (3) SalesOrderID, OrderDate FROM Sales.SalesOrderHeader WHERE CustomerID = @CustID ORDER BY OrderDate DESC SELECT Name Customer, MR.* FROM Sales.Store CROSS APPLY Sales.MostRecentOrders(CustomerID) AS MR
  17. 17. <ul><ul><li>Utilizando OUTER APPLY obtendremos el nombre del cliente (y los detalles de los pedidos) de todos los clientes </li></ul></ul>SELECT Name AS Customer, MR.* FROM Sales.Store OUTER APPLY Sales.MostRecentOrders(CustomerID) AS MR
  18. 18. <ul><li>SQL Server 2005 nos proporciona 4 nuevas funciones de ordenación/ranking: RANK, DENSE_RANK,NTILE y ROW_NUMBER </li></ul><ul><li>Para todas ellas podremos aplicar la cláusula OVER para particionar y ordenar las filas de resultados </li></ul><ul><ul><ul><li>La cláusula PARTITION BY determina el criterio de agrupación mientras que ORDER BY determina el criterio de ordenación </li></ul></ul></ul>OVER ( [ PARTITION BY < value_expression > , ... [ n ] ] ORDER BY <column> [ ASC | DESC ] [, ...[ n ] ] )
  19. 19. <ul><li>La función RANK nos permite obtener el número de orden de cada fila, dentro de una determinada partición </li></ul>SELECT P.Name Product, P.ListPrice, PSC.Name Category, RANK() OVER(PARTITION BY PSC.Name ORDER BY P.ListPrice DESC) AS PriceRank FROM Production.Product P JOIN Production.ProductSubCategory PSC ON P.ProductSubCategoryID = PSC.ProductSubCategoryID
  20. 20. <ul><li>La función DENSE_RANK es similar a la de RANK, pero no deja “huecos” a la hora de elaborar el ranking </li></ul>SELECT P.Name Product, P.ListPrice, PSC.Name Category, DENSE_RANK() OVER(PARTITION BY PSC.Name ORDER BY P.ListPrice DESC) AS PriceRank FROM Production.Product P JOIN Production.ProductSubCategory PSC ON P.ProductSubCategoryID = PSC.ProductSubCategoryID
  21. 21. <ul><li>Esta función permite obtener el número de cada fila dentro de un conjunto de resultados </li></ul>SELECT ROW_NUMBER() OVER(PARTITION BY PC.Name ORDER BY ListPrice) AS Row, PC.Name Category, P.Name Product, P.ListPrice FROM Production.Product P JOIN Production.ProductSubCategory PSC ON P.ProductSubCategoryID = PSC.ProductSubCategoryID JOIN Production.ProductCategory PC ON PSC.ProductCategoryID = PC.ProductCategoryID
  22. 22. <ul><li>Esta función permite crear grupos de resultados numerados, a partir de las filas del conjunto de resultados </li></ul>SELECT NTILE(3) OVER(PARTITION BY PC.Name ORDER BY ListPrice) AS PriceBand, PC.Name Category, P.Name Product, P.ListPrice FROM Production.Product P JOIN Production.ProductSubCategory PSC ON P.ProductSubCategoryID = PSC.ProductSubCategoryID JOIN Production.ProductCategory PC ON PSC.ProductCategoryID = PC.ProductCategoryID
  23. 23. <ul><li>SQL Server 2005 incluye la posibilidad de realizar una gestión de excepciones de forma estructurada </li></ul><ul><li>Esto simplifica muchísimo el desarrollo del código </li></ul><ul><li>La gestión de las excepciones se realizará en bloques TRY-CATCH </li></ul><ul><ul><li>Dentro del bloque TRY incluiremos el código que potencialmente puede generar errores </li></ul></ul><ul><ul><li>Dentro del bloque CATCH realizaremos la captura de los posibles errores y su tratamiento adecuado </li></ul></ul>
  24. 24. <ul><li>Sintaxis: </li></ul><ul><li>Elimina la necesidad de utilizar la variable global @@error </li></ul><ul><li>Si vamos a utilizar esta gestión de excepciones, será necesario activar una opción que indica que los errores producidos en el TRY, automáticamente aborten la transacción actual: SET XACT_ABORT ON </li></ul>BEGIN TRY { sql_statement | statement_block } END TRY BEGIN CATCH TRAN_ABORT { sql_statement | statement_block } END CATCH
  25. 25. <ul><li>Para asegurarnos de que transacciones que hayan podido quedar en estado “fantasma” se cierren adecuadamente, debemos incluir en el bloque CATCH, una sentencia ROLLBACK TRANSACTION </li></ul><ul><li>Si queremos consultar la variable @@error, debemos hacerlo en la primera línea del CATCH </li></ul><ul><li>Si necesitamos levantar una excepción “de aplicación” lo haremos usando RAISERROR:WITH TRAN_ABORT </li></ul>
  26. 26. CREATE TABLE dbo.DataTable (ColA int PRIMARY KEY, ColB int) CREATE TABLE dbo.ErrorLog (ColA int, ColB int, error int, date datetime) GO CREATE PROCEDURE dbo.AddData @a int, @b int AS SET XACT_ABORT ON BEGIN TRY BEGIN TRAN INSERT INTO dbo.DataTable VALUES (@a, @b) COMMIT TRAN END TRY BEGIN CATCH TRAN_ABORT DECLARE @err int SET @err = @@error --trap the error number ROLLBACK TRAN INSERT INTO dbo.ErrorLog VALUES (@a, @b, @err, GETDATE()) END CATCH GO EXEC dbo.AddData 1, 1 EXEC dbo.AddData 2, 2 EXEC dbo.AddData 1, 3 --violates the primary key

×