Cursors
Cursors have terrible performance and should never be used. They are expensive in terms of processing and also lock the entire dataset when in use.
Furthermore, using a temporary table in a cursor is extremely bad because no other process is able to create or drop temporary tables for the duration of the cursor as it prevents them from acquiring the necessary exclusive locks on the tempdb database. The processes are forced to wait and result in poor server performance. Also, referencing a temporary table in a cursor forces the stored procedure to recompile every time.
Most cursors are just used for looping through a dataset and performing other actions. A simple loop can easily be accomplished using the automatic increment functionality (for example, IDENTITY) of a temp table or table variable instead.
For example, instead of using the following cursor:
DECLARE CURSOR MyCursor FOR
SELECT Field1
FROM DataTable
ORDER BY Field1 ASC
OPEN MyCursor
FETCH NEXT FROM MyCursor INTO @Field1
WHILE @@FETCH_STATUS = 0
BEGIN
-- process your data
FETCH NEXT FROM MyCursor INTO @Field1
END
Use a table variable instead in the following manner:
DECLARE @MyTable TABLE ( RowId int IDENTITY,
Field1 int)
DECLARE @Rows int,
@Row int
-- Insert data here in the order desired
INSERT INTO @MyTable (Field1)
SELECT Field1
FROM DataTable
ORDER BY Field1 ASC
-- Get the total number of rows
SELECT @Rows = @@ROWCOUNT,
@Row = 0
-- Loop through the rows in the table
WHILE @Row < @Rows
BEGIN
SELECT @Row = @Row + 1
SELECT @Field1 = Field1
FROM @MyTable
WHERE RowId = @Row
-- Process your data
END