Cursors are generally not recommended and are slower compared to other methods of reading data. But there are situations where you must use cursors. I have found them to be useful when I am trying to run a SELECT on a table in Query Analyzer and performance is not a concern.
For example, consider a Stores table that has one to many relationship with another table called StoreHours. The store closes at different time depending on weekday. Also stores close at different times in different regions. You need to run a query to determine the latest closing time for each store. You can easily achieve this by running a cursor.
As I mentioned earlier, cursors are rather slow, but you can increase their performance using FAST_FORWARD and READ_ONLY hints. Also remember to always deallocate and close cursor when done.
Let's use the cursor to select latest closing time for each store, insert them into a temporary table and then select the records from the temp table.
DECLARE @tmpStoreClosing(StoreID INT, ClosingTime DateTime)
DECLARE @StoreID INT
DECLARE curStore CURSOR FAST_FORWARD READ_ONLY FOR
SELECT StoreID FROM Stores
OPEN curStore
FETCH NEXT FROM curStore INTO @StoreID
WHILE @@FETCH_STATUS=0
BEGIN
INSERT INTO @tmpStoreClosing(StoreID,ClosingTime)
SELECT TOP 1 @StoreID,ClosingTime FROM StoreHours
WHERE StoreID=@StoreID ORDER BY ClosingTime DESC
FETCH NEXT FROM curStore INTO @StoreID
END
CLOSE curStore
DEALLOCATE curStore
SELECT StoreID,ClosingTime FROM @tmpStoreClosing
You can also improve the performance using INSENSITIVE or STATIC keyword. When this keyword is used, cursor copies the data into tempDB and runs the select from there. The drawback of this approach is that any changes made to the data are not reflected.
FAST_FORWARD is same as FORWARD_ONLY and READ_ONLY combined. Data can only be read and in forward only manner. When using this flag, you can only use FETCH NEXT.
Cursors should be avoided and if used they should be used primarily for reading the data in forward only manner.
Thank you.
No comments:
Post a Comment
As always, your comments are welcome and appreciated!