SQL Server 的静态游标始终是只读的,因为结果集将存储在 tempdb 中。您可以使用此游标向前和向后移动。
SQL Server 游标场景:通常,关系数据库上的所有操作都作用于一组行。例如,编写 Select 语句会返回满足查询条件的所有记录(结果集)。但是,在某些情况下,我们需要处理单行或少量行块。在这种情况下,我们可以使用游标。
在此游标演示中,我们使用下表,该表包含 14 条记录。

SQL Server 中的游标类型
服务器支持四种类型的游标。
- 静态:它显示打开时存在的记录。它不会显示打开后更新、删除或插入的记录。
- 仅前进:顾名思义,它只能向前移动,不能向后滚动。这些只读游标按顺序从头到尾获取行。
- 键集:这些由键或唯一标识符控制。
- 动态:这些与静态相反,并显示打开后由更新、删除或插入所做的更改。
- Fast_Forward.
SQL Server 静态游标示例
在此示例中,我们将向您展示如何声明和打开游标。在这里,我们使用的是语法。
DECLARE empCR CURSOR STATIC
FOR SELECT * FROM [EmployeeTab]
OPEN empCR
FETCH NEXT FROM empCR;
分析
在此示例中,以下语句将为 Employee 表中的所有记录声明游标语句。
DECLARE empCR CURSOR STATIC FOR SELECT * FROM [EmployeeTab]
它将打开声明的 empCR。
OPEN empCR
下一条语句将从中获取一行或返回下一条记录。
FETCH NEXT FROM empCR;
尽管 Employee 表有 14 条记录,但它只检索了一条记录。这是因为 FETCH NEXT 只会从此 SQL Server 游标中获取一行,如果您想要全部获取,请使用循环。

看,它只检索了第二条记录。如果您仔细观察,我们只选择 FETCH 语句,因为我们的 empCR 仍然在使用中,因为我们还没有关闭或取消分配它。

让我使用 FETCH LAST 选项。它返回我们表中存在的最后一条记录,即 ID 号 14。

接下来,我们使用了 FETCH PRIOR 选项。它返回最后一条记录之前的行,即 ID 号 13(14 之前)。

最后,我们使用了 FETCH FIRST 选项。返回我们表中存在的第一个记录,即 ID 号 1。

SQL Server 游标示例 2
在前面的示例中,我们展示了它如何一次获取(或处理)一行。在此示例中,我们将使用 WHILE LOOP 循环遍历游标元素并将其作为输出打印。
SET NOCOUNT ON
-- Declaring the Variables
DECLARE @EmpID INT,
@EmpName VARCHAR(50),
@EmpEducation VARCHAR(50),
@EmpOccupation VARCHAR(50),
@EmpYearlyIncome DECIMAL (10, 2),
@EmpSales DECIMAL (10, 2);
DECLARE empCR CURSOR
STATIC FOR
SELECT [ID]
,[Name]
,[Education]
,[Occupation]
,[YearlyIncome]
,[Sales]
FROM EmployeeTab
OPEN empCR
IF @@CURSOR_ROWS > 0
BEGIN
FETCH NEXT FROM empCR
INTO @EmpID, @EmpName, @EmpEducation,
@EmpOccupation, @EmpYearlyIncome, @EmpSales
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'ID = '+ CONVERT(VARCHAR(10), @EmpID)+', Full Name = '+ @EmpName
+', Education = '+ @EmpEducation +', Occupation = '+ @EmpOccupation
+ ', Yearly Income = ' + CONVERT(VARCHAR(10),@EmpYearlyIncome)
+ ', Sales Amount = ' + CONVERT(VARCHAR(10),@EmpSales)
FETCH NEXT FROM empCR
INTO @EmpID, @EmpName, @EmpEducation,
@EmpOccupation, @EmpYearlyIncome, @EmpSales
END
END
CLOSE empCR
DEALLOCATE empCR
SET NOCOUNT OFF
在此示例中,首先,我们使用 SET NOCOUNT ON 来停止 SQL Server 查询中的受影响行数消息。接下来,我们声明了一些变量来保存从中获取的数据。
然后,我们声明并打开了 Employee 表中所有记录的 SQL 游标。
接下来,我们在 IF 语句中使用 @@ 来检查其中是否有任何行。以下语句会将下一条记录获取到已声明的变量中。
FETCH NEXT FROM empCR
INTO @EmpID, @EmpName, @EmpEducation,
@EmpOccupation, @EmpYearlyIncome, @EmpSales
接下来,我们使用 WHILE LOOP 来循环遍历元素。在循环中,FETCH_STATUS 用于检查 FETCH 语句的状态。在循环中,我们使用 Print 语句逐行打印记录。
PRINT 'ID = '+ CONVERT(VARCHAR(10), @EmpID)+', Full Name = '+ @EmpName +', Education = '+ @EmpEducation +', Occupation = '+ @EmpOccupation + ', Yearly Income = ' + CONVERT(VARCHAR(10),@EmpYearlyIncome) + ', Sales Amount = ' + CONVERT(VARCHAR(10),@EmpSales)
然后,我们使用 FETCH NEXT 从中获取下一条记录。
FETCH NEXT FROM empCR
INTO @EmpID, @EmpName, @EmpEducation,
@EmpOccupation, @EmpYearlyIncome, @EmpSales
最后,我们使用 CLOSE 和 DEALLOCATE 语句来关闭和取消分配游标。
CLOSE empCR DEALLOCATE empCR

游标示例 3
在我们之前的 SQL Server 静态游标示例中,我们展示了如何使用 WHILE LOOP 循环遍历元素并将其作为输出打印。在此示例中,我们将在 while 循环内添加一个 select 语句来显示结果集中的项。
SET NOCOUNT ON
DECLARE @EmpID INT,
@EmpName VARCHAR(50),
@EmpEducation VARCHAR(50),
@EmpOccupation VARCHAR(50),
@EmpYearlyIncome DECIMAL (10, 2),
@EmpSales DECIMAL (10, 2);
DECLARE empCR CURSOR
STATIC FOR
SELECT [ID]
,[Name]
,[Education]
,[Occupation]
,[YearlyIncome]
,[Sales]
FROM EmployeeTab
OPEN empCR
IF @@CURSOR_ROWS > 0
BEGIN
FETCH NEXT FROM empCR
INTO @EmpID, @EmpName, @EmpEducation,
@EmpOccupation, @EmpYearlyIncome, @EmpSales
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'ID = '+ CONVERT(VARCHAR(10), @EmpID)+', Full Name = '+ @EmpName
+', Education = '+ @EmpEducation +', Occupation = '+ @EmpOccupation
+ ', Yearly Income = ' + CONVERT(VARCHAR(10),@EmpYearlyIncome)
+ ', Sales Amount = ' + CONVERT(VARCHAR(10),@EmpSales)
-- Display the result set
SELECT @EmpID AS ID, @EmpName AS Name, @EmpEducation AS Education,
@EmpOccupation AS Occupation, @EmpYearlyIncome + 25000 AS YearlyIncome,
@EmpSales + 1000 AS Sales
FETCH NEXT FROM empCR
INTO @EmpID, @EmpName, @EmpEducation,
@EmpOccupation, @EmpYearlyIncome, @EmpSales
END
END
CLOSE empCR
DEALLOCATE empCR
SET NOCOUNT OFF
它将每个记录显示为一个单独的结果集。此外,它还反映了我们在 SELECT Statement 中所做的更改(年收入 + 25000,销售额 + 1000)。

让我们查看 Message 选项卡,检查游标的 Print 语句结果。如您所见,它显示了 Employee 表中的年收入和销售额值。这是因为我们在 Print 语句中没有更改任何值。
