T-SQL 游标缺少第一个值并分批执行

T-SQL Cursor missing first value and executing in multiple batches

假设我想遍历 table xval 中的值,它被定义为:

CREATE TABLE xval (x INT NULL); 
INSERT INTO xval(x) 
VALUES (13),(1),(42),(9),(-2),(14); 
GO

现在我有以下内容:

DECLARE @x INT 
DECLARE pointer CURSOR FOR (SELECT x FROM xval)
OPEN pointer
FETCH NEXT FROM pointer INTO @x
WHILE @@FETCH_STATUS = 0
BEGIN 
    PRINT @x
    FETCH NEXT FROM pointer
END 
CLOSE pointer
DEALLOCATE pointer

当我 运行 这样做时,SSMS 在结果 window 中给我多个批次,并且在每个批次中它从 xval table 中选择一个值。但是这些批次只包含值 1,42,9,-2,14 和末尾的一个空批次 。 然而,在消息 window 中,我得到以下内容:

13

(1 row affected)
13

(1 row affected)
13

(1 row affected)
13

(1 row affected)
13

(1 row affected)
13

(0 rows affected)

Completion time: 2020-08-30T21:54:14.7480477+01:00

我想知道这是怎么回事: 1. 为什么我第一批没有拿到13? 2、为什么多批次排在第一位? 3. 为什么我收到的信息只有13条...

我意识到我需要始终获取我声明的变量。

WHILE @@FETCH_STATUS = 0
BEGIN 
    PRINT @x
    FETCH NEXT FROM pointer **INTO @x**
END 

由于我没有在循环中将值取入@x,它一直打印出最初设置为13 的@x(第4 行的FETCH NEXT FROM pointer INTO @x)。所以每次我们循环它都会打印 13。它还会从 xval 获取下一个值,因此结果 window 显示它正在获取的内容。因为它已经将 13 取出到 x 中,所以指针移动到下一个值。所以你在结果中看不到 13 window.

末尾的空集是因为它在 while 循环检查开始之前继续从游标中获取下一个值 (@@FETCH_STATUS = 0),即使列表已用完。这就是为什么它是空的,因为它试图寻找下一个值,但那里没有任何值。