Monday, December 15, 2014

Cursor


Source:Refer  the Source for details.


Relational Database Management Systems, including Sql Server are very good at handling data in SETS. For example, the following "UPDATE" query, Updates a set of rows that matches the condition in the "WHERE" clause at the same time.

Update tblProductSales Set  UnitPrice = 50 where ProductId = 101

tblProducts:

Id         Name                                Description
1          Product - 1                         Product - 1 Description
2          Product - 2                         Product - 2 Description
3          Product - 3                         Product - 3 Description
4          Product - 4                         Product - 4 Description     
5          Product - 5                         Product - 5 Description      

tblProductsSales:

Id        ProductId                 UnitPrice        QuantitySold
1          5                               5                     3
2          4                               23                   4 
3          3                               31                   2 
4          4                               93                   9
5          5                               72                   5

However, if there is ever a need to process the rows , on a row-by-row basis, then cursors are your
choice.Cursors are very bad for performance and should be avoided always.Most of the time, cursors can be very easily replaced using joins.

Cursors in Sql Server:

There are different types of cursors in sql server as listed below. We will talk about the differences
between these cursor types in a later video session.

1.Forward only
2.Static
3.Keyset
4.Dynamic

DEMO

The cursor will loop through each row in tblProductSales table.As there are 600,000 rows, to be processed on a row-by-row basis, it takes around 40 to 45 seconds on my machine.We can achieve
this very easily using a join, and this will significantly increase the performance.We will discuss about this in our next video session.

Note:
Cursor is nothing but a pointer to a row.

Select top 10 * from tblProducts
Select top 10 * from tblProductsSales

Select count(*) from tblProducts
Select count(*) from tblProductssales

Select Name, UnitPrice FROM tblProducts join tblProductSales on tblProducts.Id=tblProductSales.ProductId
Where ( Name = 'Product - 55'   or  Name = 'Product - 65' or Name like 'Product - 100%)

---
Declare @ProductId  int
Declare @Name nVarchar(30)

Declare ProductCursor CURSOR FOR

Select Id,Name from tblProducts where Id<=1000

Open ProductCursor

Fetch Next from ProductCursor into  @ProductId , @Name

While (@@ FETCH_STATUS = 0)

Begin

Print 'Id=' + Cast(@ ProductId as NVarchar(10) ) + 'Name' + @Name

End

CLOSE  ProductCursor

DEALLOCATE ProductCursor

--
Declare @ProductName  nVarchar(50)

Select @ProductName = Name from  tblProducts where  Id= @ProductId

if (@ProductName = 'Product - 55')

Begin

Update  tblProductSales Set UnitPrice=55 Where ProductId = @ProductId

End 

else if  ( @ProductName = 'Product - 65')

Begin

Update tblProductSales Set UnitPrice = 65 Where ProductId = @ProductId

End

else if (@ProductName like 'Product - 100%')

Begin

Update tblProductSales Set UnitPrice=1000 Where ProductId=@ProductId

End 

--
Declare @ProductId int
Declare @ProductName nVarchar(30)

Declare ProductCursor CURSOR FOR

Select ProductId From  tblProductSales 

Open ProductCursor

Fetch  Next  FROM  ProductCursor into @ProductId

While (@@FETCH_STATUS = 0 )
Begin

Select @ProductName=Name from tblProducts Where Id=@ProductId

if (@ProductName = 'Product - 55')

Begin

Update  tblProductSales Set UnitPrice=55 Where ProductId = @ProductId

End 

else if  ( @ProductName = 'Product - 65')

Begin

Update tblProductSales Set UnitPrice = 65 Where ProductId = @ProductId

End

else if (@ProductName like 'Product - 100%')

Begin

Update tblProductSales Set UnitPrice=1000 Where ProductId=@ProductId

End 

 Fetch Next from ProductCursor into  @ProductId 

End

CLOSE  ProductCursor

DEALLOCATE ProductCursor

 -------------------------------------------------------------------------------------------------------------------------------

Source:Replacing cursors using joins in sql server Part 64


In Part 63, We have discussed about cursors. The example, in Part 63, took around 45 seconds in my machine. Please watch Part 63, before proceeding with this video. In this video will re-write the
example, using a join.
Update tblProductSales
Set UnitPrice = 
  Case
    When Name='Product - 55' Then 55
    When Name='Product - 65' Then 65
    When Name='Product - 100%' Then 1000
Else
    UnitPrice
End Case
From tblProductSales
join    tblProducts
On tblProducts.Id=tblProductSales.ProductId Where ( Name='Product - 55' or Name='Product - 65' or Name like 'Product - 100%' 
When i executed this query, on my machine it took less than a second, where as the same thing
using cursor took 45 seconds.
Just  imagine the amount of impact cursors have on performance.Cursors should be used as your last option.
Most of  the time Cursors can be very easily replaced using joins.
 -------------------------------------------------------------------------------------------------------------------------------
   



 

 


 

No comments:

Post a Comment