Published on

January 15, 2020

Understanding SQL Cursors and the @@FETCH_STATUS Function

SQL cursors are a commonly used database object that allows you to retrieve data from a result set one row at a time. While they may not be recommended for performance reasons, they are still widely used, especially when dealing with small amounts of data. In this article, we will provide an overview of SQL cursors and explain the @@FETCH_STATUS function, which is used to check the status of the last FETCH statement issued against any opened cursor.

SQL Cursor Overview

A cursor is a database object used to fetch rows from a result set. The cursor lifecycle consists of several phases:

  • Declaring the cursor: This involves creating a cursor object and specifying the source SQL query.
  • Opening the cursor: After declaring the cursor, you need to retrieve the result set using the OPEN command.
  • Fetching rows: Once the cursor is opened, you can fetch rows from the result set and either visualize them or store them in variables.
  • Closing and deallocating the cursor: After consuming the rows, you should close the cursor to release the result set and free any cursor locks. The DEALLOCATE command is used to release the cursor object reference from memory.

The @@FETCH_STATUS Function

The @@FETCH_STATUS function is a system function that returns the status of the last FETCH statement issued against any opened cursor. It returns an integer value that indicates the success or failure of the fetch operation. The possible values and their descriptions are:

ValueDescription
0The FETCH statement was successful.
-1The FETCH statement failed, or the row was beyond the result set.
-2The row fetched is missing.
-9The cursor is not performing a fetch operation.

One common use case for the @@FETCH_STATUS function is to implement it within a while loop to continue fetching rows as long as the fetch statement is successful. This eliminates the need for multiple FETCH statements for each cursor. Here’s an example:

DECLARE @Schema NVARCHAR(50)
DECLARE @Name NVARCHAR(50)

DECLARE csr CURSOR FOR
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES

OPEN csr

FETCH NEXT FROM csr INTO @Schema, @Name

WHILE @@FETCH_STATUS = 0
BEGIN
    FETCH NEXT FROM csr INTO @Schema, @Name
END

CLOSE csr
DEALLOCATE csr

In the above example, we create a cursor to fetch the names and schemas of tables created within a database. We use a while loop with the @@FETCH_STATUS function to continue fetching rows as long as the fetch statement is successful. Once the fetch statement returns -1 (indicating no more rows), the loop is exited.

Understanding @@FETCH_STATUS Values

In addition to the commonly encountered values of 0 and -1, the @@FETCH_STATUS function can also return -2 and -9. Here’s a brief explanation of these values:

-2: The row fetched is missing

This value is returned when a row that should be returned in the FETCH statement is deleted. This can occur when the KEYSET option is used while declaring the cursor, which specifies that the membership and order of the rows in the cursor are fixed when the cursor is opened. This scenario can happen when multiple users are working with the same data and one user deletes rows while another is trying to manipulate them using a SQL cursor.

-9: The cursor is not performing a fetch operation

This value is not returned by the @@FETCH_STATUS function itself, but it is a value stored within SQL Server internals. It is shown in the System Dynamic Management Views when the SELECT statement is defined. Declaring a SQL cursor with no columns will result in this value, regardless of whether the cursor is open or not.

By understanding these values, you can handle different scenarios that may arise when working with SQL cursors.

Conclusion

In this article, we provided an overview of SQL cursors and explained the @@FETCH_STATUS function. We discussed the different phases in a cursor’s lifecycle and how to use the @@FETCH_STATUS function to check the status of a fetch operation. By understanding these concepts, you can effectively work with SQL cursors and handle various scenarios that may arise.

Click to rate this post!
[Total: 0 Average: 0]

Let's work together

Send us a message or book free introductory meeting with us using button below.