使用 SQL 游标而不是自连接来查找非连续数字

Using SQL cursors instead of self-join to find non - consecutive numbers

在 SQL 服务器中,我想使用 SQL 游标函数检查特定列中的数字是否按升序排列。基本上每一行的值都必须大于前一行。我使用 self-join 编写了代码,如下所示:

首先,我给每行一个定义为整数的行号,以便使用 select row_number() over(ORDER BY (SELECT NULL) ) AS Row# 将每一行与前一行进行比较。然后使用上面创建的行号将 table 与自身进行比较,并使用下面的代码找到不连续的行。

  SELECT *
  FROM Sequence AS prev_row
  JOIN Sequence AS next_row 
  ON prev_row.Row#+1 = next_row.Row#
  AND (prev_row.Number > next_row.Number)

尽管我上面的代码工作正常,但我想使用 SQL 游标执行相同的操作,以便更好地理解游标的用法,并在 SQL 方法上开发不同的方法。所以我写了下面的代码,但它不起作用:

DECLARE db_cursor CURSOR 
FOR
SELECT Row#, Number
FROM Sequence;

DECLARE @Row# int;
DECLARE @Numbers int;

OPEN db_cursor
FETCH NEXT FROM db_cursor

WHILE @@FETCH_STATUS = 0
BEGIN
    SELECT @Row# , @Numbers
    FETCH NEXT FROM db_cursor
    SELECT @Row#, @Numbers --this part is for printing results
    where @Row#>@Row#+1 --condition
END
CLOSE db_cursor;
DEALLOCATE db_cursor; 

谁能解释一下我哪里出错了?帮助将不胜感激。

create table seq(id int, val int);
insert into seq values
(1,  10),
(2,  11),
(3,  15),
(4,  20),
(5,  19),
(6,  24),
(7,  30),
(8,  31),
(9,  29),
(10, 35);
GO
10 rows affected
select id, val,
       iif(coalesce(lag(val) over (order by id), val) <= val, 'OK', 'ERROR') [check]
from seq
GO
id | val | check
-: | --: | :----
 1 |  10 | OK   
 2 |  11 | OK   
 3 |  15 | OK   
 4 |  20 | OK   
 5 |  19 | ERROR
 6 |  24 | OK   
 7 |  30 | OK   
 8 |  31 | OK   
 9 |  29 | ERROR
10 |  35 | OK   
declare cur cursor for
    select id, val from seq order by id;

declare @id int = 0,
        @val int = 0,
        @last_val int = null;

declare @res table (id int, val int, [check] varchar(10));

open cur;

fetch next from cur into @id, @val

while @@fetch_status = 0
begin
    insert into @res
    select @id, @val, iif (@last_val is null or @last_val < @val, 'OK', 'ERROR');

    set @last_val = @val;    

    fetch next from cur into @id, @val;
end

close cur;
deallocate cur;

select * from @res;
GO
id | val | check
-: | --: | :----
 1 |  10 | OK   
 2 |  11 | OK   
 3 |  15 | OK   
 4 |  20 | OK   
 5 |  19 | ERROR
 6 |  24 | OK   
 7 |  30 | OK   
 8 |  31 | OK   
 9 |  29 | ERROR
10 |  35 | OK   

dbfiddle here