Sunday 6 April 2014

SQL Server 2005 Features

Index Enhancements


1. Rebuilding of Clustered index
            In SQL Server 2000, rebuilding a clustered index, was forcing all of the related non-clustered indexes also to be rebuild. In SQL Server 2005  rebuilding clustered index no longer force non-clustered indexes to be rebuilt.

Execute the following code in SQL Server 2000.

create table empl(eno int , ename varchar(20))
insert into empl values(1,'aa')
insert into empl values(2,'bb')
insert into empl values(3,'cc')
create clustered index empl_index on empl(eno)
create index empl_nc_index on empl(ename)

dbcc dbreindex('empl','empl_index')
Run the profiler trace , that shows the rebuild of all the related  non clustered indexes also.

Execute the above code in SQL Server 2005

Run the profiler trace. Only the clustered index would have got rebuilt. All the other non clustered indexes are not automatically rebuilt.

2. Adding Non-Key Columns to an Index
SQL Server 2005 also allows adding a Non-Key column to an index.
As previous Versions of SQL Server and almost all databases allow only key columns to be a part of index and so there is limited query support, which can take advantage of indexes. This new feature allows more queries to get executed by taking full advantage of indexes.



The heap or clustered index for a table (often called the “base table”) contains (or covers) all columns in the table.  Non-clustered indexes, on the other hand, contain (or cover) only a subset of the columns in the table. SQL Server 2005 allows the inclusion of non key columns into a non clustered index. When more columns are covered it improves queries performance

Note :- If a table contains a clustered index as well as a non clustered index , the non-clustered indexes will include the indexed column as well as the “cluster key”. 

Consider the following Example,
create table T_clu (a int, b int, c int, d int, e int)
create unique clustered index T_clu_a on T_clu (a)
create index T_clu_b on T_clu (b)
create index T_clu_ac on T_clu (a, c)
create index T_clu_d on T_clu (d) include (e)

Index
Covered Columns
T_Clu_a
A,b,c,d,e
T_Clu_b
A, b
T_Clu_ac
A,c
T_Clu_d
A,d,e

The non clustered index ‘T_Clu_d’ has more number of columns than other non clustered indexes. Included columns are more efficient than key columns; they save disk space and make searching and updating the index more efficient.

3. Enable and Disable indexes
Another new feature of SQL Server 2005 is ability to disable an index. Disabling an index stops that index to be being maintained and used by SQL Server engine. When an index is disabled, SQL Server 2005 database engine de-allocates the storage space used by an index but maintains the meta-data of that index. Alter Index statement is used to rebuild an index and only after that, disabled index can be enabled again.
Index can be disabled as follows

alter index emp_index on employee disable

To enable the index again, use the following command
Alter index emp_index on employee rebuild
      Rebuilding an index will enable the disabled index

4. Online index rebuild
      Previous versions of SQL Server didn't allow any access to an index while that index was rebuilt. Developers needed to wait until the rebuilt process completed and so database objects can get updated. SQL Server 2005 also allows online index operations, which enables applications to access the index and perform database operations like insert, update and delete on a table while the index is rebuilding.




SQL Enhancements

Using the OUTPUT Keyword


SQL Server triggers use the tables “inserted” and “deleted” to get information about the records that were manipulated by the current transaction. SQL Server 2005 introduces the OUTPUT keyword to provide this same functionality in a simple INSERT, UPDATE, and DELETE statement. You can use the OUTPUT keyword to return information about the results of a Transact-SQL statement into a table-valued variable.

Using the OUTPUT keyword

You can include an OUTPUT clause in any DML statement with the following exceptions:

INSERT statements targeting views
DML operations with remote tables or views
DML operations on local or distributed partitioned views





Examples of using the OUTPUT keyword

The following example shows how to use the OUTPUT keyword with an INSERT statement.
The example assumes a table called Stock.ProductList with an IDENTITY ProductID column, a ProductName column, and a Price column already exists.


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

The following example shows how to use the OUTPUT keyword with an UPDATE statement when updating the same sample table as in the previous example.

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

The following example shows how to use the OUPUT keyword with a DELETE statement

DECLARE @DeleteDetails TABLE
(
ProductID int,
DeletedBy sysname
)

DELETE Stock.ProductList
OUTPUT DELETED.ProductID, suser_name() INTO @DeleteDetails
WHERE ProductID = 2

SELECT * FROM @DeleteDetails

Common Table Expressions (CTE)

Introduction

Common table expressions (CTEs) are defined in the SQL_99 standard, and let you create queries that work with recursive data. CTE-based recursive queries are generally more readable than those created using traditional Transact-SQL syntax.

Definition

A CTE is a named temporary result set based on a regular SELECT query. You then use the result set in any SELECT, INSERT, UPDATE, or DELETE query defined within the same scope as the CTE.

Advantages of CTEs

Using CTEs provides you with two main advantages:
  • Queries with derived tables become simpler and therefore more readable.
Traditional Transact-SQL constructs used to work with derived tables usually require a separate definition for the derived data (such as a temporary table or table valued function). Using a CTE to define t he derived table makes it easier to see the definition of the derived table with the code that uses it.
  • You can traverse recursive hierarchies.
CTEs reduce the amount of code required for a query that traverses recursive hierarchies (such as when rows in the same table can be linked with a self-join).

 

Example of a simple CTE


The following example shows the creation of a CTE named TopSales that displays the number of sales for each salesperson based on information provided by the SalesOrderHeader table.

WITH TopSales (SalesPersonID, NumSales) AS
( 
SELECT SalesPersonID, Count(*)
FROM Sales.SalesOrderHeader GROUP BY SalesPersonId 
)

SELECT * FROM TopSales
WHERE SalesPersonID IS NOT NULL
ORDER BY NumSales DESC
The query then restricts the TopSales CTE based on the SalesPersonID and sorts the rows based on the NumSales column.

Example of using a CTE and a join


The following example shows the same CTE named TopSales joined with the SalesPerson table to retrieve the salesperson's year-to-date sales figure and number of sales.
--assumes WITH TopSales from previous example

SELECT ts.SalesPersonID, sp.SalesYTD, ts.NumSales
FROM Sales.SalesPerson sp INNER JOIN TopSales ts
ON ts.SalesPersonID = sp.SalesPersonID
ORDER BY NumSales DESC

PIVOT and UNPIVOT Operators

Introduction

SQL Server 2005 introduces the PIVOT and UNPIVOT relational operators. These operators allow you to create powerful crosstab queries that form the basis of crosstab reports in a data warehouse scenario.

PIVOT definition

PIVOT lets you generate crosstab queries in which values are converted (or pivoted) to columns. A crosstab query calculates a sum, average, or other aggregation and then groups the result by row headings down the left side of a grid and by column headings across the top of a grid. The SQL Server 2005 PIVOT operator is similar to the Microsoft Access TRANSFORM statement.

 

UNPIVOT definition

UNPIVOT converts columns to values; the opposite of PIVOT. UNPIVOT has the same syntax as PIVOT except that you specify the UNPIVOT operator instead of PIVOT. The input table is narrowed from the columns in column_list into the single column in pivot_column.

 

Example of a simple PIVOT

In a sales environment, you might want to know the number of orders a customer places for individual products. Using the PIVOT operator
+achieves this aim.
The following example shows the structure of a simple Order table:
CREATE TABLE Sales.[Order]
(
Customer varchar(8), Product varchar(5), Quantity int
)
The table has the following values:
Customer
Product
Quantity
Mike
Bike
3
Mike
Chain
2
Mike
Bike
5
Lisa
Bike
3
Lisa
Chain
3
Lisa
Chain
4
The following example shows a PIVOT operation on the Order table:
SELECT * FROM Sales.[Order]
PIVOT (SUM(Quantity) FOR Product IN ([Bike],[Chain])) AS PVT
The expected output from this query is:
Customer
Bike
Chain
Lisa
3
7
Mike
8
2

Example of a simple UNPIVOT

The following example shows how to unpivot the PivotedOrder table to view the totals for each product:
SELECT Customer, Product, Quantity FROM Sales.PivotedOrder
UNPIVOT (Quantity FOR Product IN ([Bike],[Chain])) AS UnPVT
This produces the following results:
Customer
Product
Quantity
Lisa
Bike
3
Lisa
Chain
7
Mike
Bike
8
Mike
Chain
2

The APPLY Operator

Introduction

SQL Server 2005 introduces the APPLY relational operator, which allows you to apply a table-valued function to each row of a JOIN table. This technique is extremely flexible because you can use a user-defined function, allowing endless possibilities.
Definition ====
The APPLY operator invokes a function that returns a table for each row in a JOIN table. You can choose between the following APPLY operator types:
  • CROSS APPLY. Only rows in the JOIN table are included if the row produces results in the table returned by the function.
  • OUTER APPLY. All rows in the JOIN table are included regardless of whether the row produces results in the table returned by the function.
You can use the APPLY operator in any situation in which you use a FROM clause. The APPLY operator has the following syntax:
FROM left_table_source
{OUTER | CROSS} APPLY right_table_source
The main benefit of this operator comes when you use a table-valued function as right_table_source. This function normally accepts one or more columns from left_table_source as function parameters. The function uses these parameters to produce the table-valued result set.

Example of the APPLY operator


In this example, a report displaying customer order information relating to only the most recent three purchases is required. The MostRecentOrders function retrieves the required rows from the SalesOrderHeader table for a particular customer ID. The results are applied to the Store table that contains the customer information.

The following sample code shows the MostRecentOrders function:
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
In the following example, only the names of customers who have placed orders will appear in the output because of the use of a CROSS APPLY operator.
SELECT Name Customer, MR.*
FROM Sales.Store
CROSS APPLY Sales.MostRecentOrders(CustomerID) AS MR
In the following sample code, the names of all customers will appear in the output because of the use of an OUTER APPLY operator, even if they have not placed any orders.

SELECT Name AS Customer, MR.* FROM Sales.Store
OUTER APPLY Sales.MostRecentOrders(CustomerID) AS MR




Structured Exception handling

      Structured exception handling is a common way to handle exceptions in many popular programming languages, such as Microsoft Visual Basic .NET and Microsoft Visual C# .NET. SQL Server 2005 includes enhancements to Transact-SQL that allow you to use structured exception handling in any transactional situation, such as a stored procedure. This enhancement makes your code more readable and more maintainable.


Definition
Use TRY:CATCH blocks to implement structured exception handling. The TRY block contains the transactional code that could potentially fail. The CATCH block contains the code that executes if an error occurs in the TRY block.

TRY:CATCH has the following syntax:

BEGIN TRY
{ sql_statement | statement_block }
END TRY
BEGIN CATCH TRAN_ABORT
{ sql_statement | statement_block }
END CATCH
The sql_statement or statement_block part of the syntax is any Transact-SQL statement or group of statements.
 
 
 

Eliminates the need for "IF @@error"

In previous versions of SQL Server, you would handle exceptions by checking the @@error global variable. You would often check this variable immediately after an INSERT, UPDATE, or DELETE statement took place and then perform corrective action if @@error did not equal zero. The new structured exception handling approach reduces the amount of code you must create because you do not need to keep checking @@error.

Requires XACT_ABORT ON

One requirement for structured exception handling in SQL Server 2005 is that you must enable the automatic rolling back of transactions with SET XACT_ABORT ON. This setting raises all errors within a TRY block to the level of transactional abort errors. The CATCH block then handles the errors.

Transaction doomed state requires manual rollback

When the transaction fails, it enters a state known as the doomed state. The transaction remains open, but it cannot be committed. You must manually roll back the transaction that failed in the CATCH block by using the ROLLBACK TRANSACTION statement. This should be one of the first statements in the CATCH block to release the transaction resources as soon as possible.

Using @@error

If you need to use @@error, you must retrieve the value in the first statement of the CATCH block. If you intend to log this information in to an error log table, store @@error as a local variable and perform the log after the ROLLBACK statement. If you log the error before the ROLLBACK statement, you will also roll back the insertion into the error log.

Using RAISERROR

If you need to create your own exception in a TRY block, use the RAISERROR:WITH TRAN_ABORT statement. The WITH TRAN_ABORT option raises the error to the level of a transactional abort error, thereby invoking the CATCH block.

Example of a TRY:CATCH

In this example, a stored procedure named AddData attempts to insert two values into a table called TestData. The first column of the TestData table is an integer primary key, and the second column is an integer data type. A TRY:CATCH block within the AddData stored procedure protects the TestData INSERT statement and logs any errors in the ErrorLog table as part of the CATCH block logic.
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