Saturday, May 31, 2014

Local and Global Cursors in SQL Server

Based on the scope, Cursors can be classified into two types in SQL Server, namely Local Cursors and Global Cursors. They behave just like Local and Global Temporary Tables with some differences. In this post, I'll write about how they work.

Just like temporary tables, the scope of a cursor can be Local or Global. Global Cursors can be accessed anywhere in the program once they are declared whereas Local Cursors can be accessed only in the respective batch. There is an option to set whether the default cursor in a particular database is Global or Local. By default it is set to Global. To know that, run the following code,

SELECT is_local_cursor_default FROM sys.databases WHERE name = DB_NAME()

If this query returns 0 then the default cursor is Global. If it is 1 then it means the default cursor of the database is Local. The scope of the default cursor can be changed to LOCAL with the following ALTER statement,

ALTER DATABASE AdventureWorks2012 SET CURSOR_DEFAULT LOCAL

If Global Cursor is declared inside a stored procedure or a trigger, it can be accessed from another Stored Procedure or a Trigger whereas Local Cursor cannot be accessed like this. Global Cursors should be manually closed and de-allocated or it will be de-allocated on closing the connection whereas Local Cursors are automatically closed and de-allocated as soon as the query analyzer crosses its batch.

Global Cursor and Local Cursor have different namespaces, so both can be declared with the same name. Let's see how this works,

Assuming the default scope of cursor is set to GLOBAL, let's create one as follows,

USE AdventureWorks2012
GO
DECLARE MYCURSOR CURSOR
FOR
SELECT * FROM Production.Product

Now cursor is declared for table Product. Now it can be opened in an independent SQL Statement,

OPEN MYCURSOR

If any row is to be fetched then it can also be done with an independent statement,

FETCH NEXT FROM MYCURSOR
WHILE @@FETCH_STATUS = 0
BEGIN
   FETCH NEXT FROM MYCURSOR
END

This cursor can be closed and de-allocated independently too,

CLOSE MYCURSOR
DEALLOCATE MYCURSOR

The above case is not with Local Cursor. If a local cursor has to be created on the same table then it goes as follows,

DECLARE MYCURSOR CURSOR LOCAL
FOR
SELECT * FROM Production.Document
OPEN MYCURSOR
FETCH NEXT FROM MYCURSOR
WHILE @@FETCH_STATUS = 0
BEGIN
    FETCH NEXT FROM MYCURSOR
END
CLOSE MYCURSOR
DEALLOCATE MYCURSOR

The above SQL code should be executed in a single batch because of the keyword LOCAL which means the cursor is a local scoped one. If the default scope of cursor is set to LOCAL then a keyword GLOBAL should be used while declaring a global cursor. The above two cursors can be declared in a single connection.

There is a scenario where a Global Cursor can be declared inside a Stored Procedure or a Trigger and can be accessed from outside the procedure or trigger. To know that functionality, let's create a Stored Procedure as follows,


CREATE PROCEDURE GLOBAL_CURSOR_TEST
AS
BEGIN
DECLARE MYCURSOR CURSOR
FOR
SELECT * FROM Production.Product
END

Now execute the Stored Procedure which declares the cursor,

EXEC GLOBAL_CURSOR_TEST

Now this cursor can be accessed from either outside this procedure independently or inside another Stored Procedure. For now let's try independently,

OPEN MYCURSOR

FETCH NEXT FROM MYCURSOR
WHILE @@FETCH_STATUS = 0
BEGIN
    FETCH NEXT FROM MYCURSOR
END
CLOSE MYCURSOR
DEALLOCATE MYCURSOR

Now you can observe that this fetches the result from the table Production.Product with a cursor MYCURSOR. This cannot be done when a Local Stored Procedure is created within the Stored Procedure.

Here is the link for the official documentation about scope of cursors, by Microsoft,

Saturday, May 24, 2014

Numbered Stored Procedures in SQL Server

I've come across an unseen feature (for me) in SQL Server, named Numbered Stored Procedures. They are like normal Stored Procedures but there lies some difference. The normal Stored Procedures are unique in their names whereas Numbered Stored Procedures are quite opposite to them in this aspect. 

Numbered Stored Procedures are the ones which exist with the same names and can be with different functionality inside them. To differentiate, each Stored Procedure should be given a number. It is just like Method Overloading which we find in Object Oriented Programming Languages where a number of methods are created with the same name and different parameters. Let's see how this works in SQL Server,

Create a Stored Procedure as follows:

USE AdventureWorks2012
GO
CREATE PROCEDURE Numbered_Procedure;1
AS
BEGIN
    SELECT * FROM Person.Person
END

In the above snippet, note that a number "1" is specified after the name of the Procedure. This means this is the first procedure of the numbered procedures. If you want to create another Stored Procedure with the same name and a different functionality then it goes as follows:

CREATE PROCEDURE Numbered_Procedure;2
AS
BEGIN
    SELECT * FROM Production.Product
END

The above Stored Procedure is the second Stored Procedure with the same name. You cannot create the second procedure without creating the first procedure. If you try to do so then SQL Server raises the following error

Msg 2730, Level 11, State 1, Procedure Numbered_Procedure, Line 1
Cannot create procedure 'Numbered_Procedure' with a group number of 2 because a procedure with the same name and a group number of 1 does not currently exist in the database. Must execute CREATE PROCEDURE 'Numbered_Procedure';1 first.

This means you need to create a procedure with number 1 before going to create the one with number 2. There is even no rule that you should create the procedure with number 2 after creating 1. Creating procedure with number 1 is mandatory. Later number 3 or anything can be created. 

If you take the help of the System Stored Procedure sp_helptext then it shows the definition of all starting from the Procedure with number 1.

EXEC sp_helptext Numbered_Procedure


To get the definition of the other procedures created individually, use the following System View,

SELECT * FROM sys.numbered_procedures


In the above screenshot, you can observe that all the Stored Procedures created have the same "object_id". To execute a particular numbered procedures, you can execute as follows:

EXEC Numbered_Procedure;2


If you don't specify any number in the EXEC statement then the procedure created with number 1 is executed. Each procedure can be modified separately but all the Numbered Procedures created can be dropped with a single DROP statement as,

DROP PROCEDURE Numbered_Procedure

There is no option of dropping a Stored Procedure with a particular number. Microsoft has been mentioning in the product documentation since SQL Server 2005 that this feature will be removed in the next release, but this feature is even present in the recent release SQL Server 2014. To be on safe side, don't use this feature in your production environment.


There is a limitation for these Numbered Procedures. They cannot be used in Contained Databases.

Every feature can be tested with a sample database AdventureWorks available for different versions of SQL Server for download in the following link:

http://msftdbprodsamples.codeplex.com/releases/view/93587

Saturday, May 10, 2014

SQL Server Configuration Manager in 64 bit MSSQL Server

SQL Server Configuration Manager is a tool that comes along when the product is installed. It lets the administrators configure different options like starting or stopping a service, enable or disable network protocols etc. As Microsoft concentrates more on User Interface in its products, it did the same even in the case of configuration manager by providing a well designed API. 

SQL Server Configuration Manager can be opened by searching in Start Menu. It offers the configuration for the following options:
  1. Managing of Services.
  2. Configuration of Network Protocols.
  3. Managing Aliases for Server.
The configuration manager is different for 32 bit and 64 bit versions of SQL Server. I had a doubt regarding this while checking it once. In 64 bit SQL Server's Configuration Manager, in the left pane, I observed five options like
  1. SQL Server Services.
  2. SQL Server Network Configuration (32 bit).
  3. SQL Native Client Configuration (32 bit)
  4. SQL Server Network Configuration.
  5. SQL Native Client Configuration.





In 32 bit SQL Server's Configuration Manager I've observed the above options except 2nd and 3rd options. After a long research, I've found the reason for having the options like this. 


When you install a 64 bit Microsoft Windows operating system, you can find two folders in your C:\ drive as Program Files and Program Files (x86). The latter specifies the Program Files for the 32 bit software. Microsoft has included this feature because, firstly 32 bit was introduced and after a long time 64 bit OS was introduced. Meanwhile so many software vendors designed their software which suits the 32 bit OS architecture. After introducing 64 bit, if Microsoft had restricted the installation of 32 bit software then it would've been a burden on so many software vendors who couldn't migrate their software to suit 64 bit OS architecture. Keeping this in account, Microsoft kept no restriction on installing 32 bit software on a 64 bit machine and introduced another folder in C:\ drive with name Program Files (x86). In a 64 bit machine, if any 64 bit software is installed, it gets installed in Program Files folder while any 32 bit software gets installed in Program Files (x86) folder.

When a 64 bit SQL Server is installed on a 64 bit machine, it gets installed as both 32 bit and 63 bit version, thus taking a place in the both the above specified folders. This is the reason for the appearance of two more options with (32 bit) at the end as shown above. There exists a .dll file with name sqlmgmprovider.dll which is responsible for the Network and Native Client configurations in the following paths,

C:\Program Files\Microsoft SQL Server\110\Shared\    --> For 64 bit SQL Server 2012

C:\Program Files (x86)\Microsoft SQL Server\110\Shared\  --> For 32 bit SQL Server 2012

If the .dll is corrupt or missing in any of the above locations then you cannot see the Network Configuration and Native Client Configuration options in your SQL Server Configuration Manager. Suppose you install a 64 bit instance and a 32 bit instance on a 64 bit machine, the configuration manager appears like this:




The protocols and aliases for 32 bit instance can be configured from SQL Server Network Configuration (32 bit) section while the remaining below sections are for 64 bit instance. 

Suppose you can't see any of these options of 32 bit and 64 bit, it means the file sqlmgmprovider.dll is either corrupted or missing. If so, you can just copy it from another machine which is working correctly.

Above knowledge has been gained from different blogs, the following msdn blog helped a lot in understanding,