在SQL Server上迭代游标时如何知道最后一行?

时间:2016-08-23 07:21:28

标签: sql-server tsql cursor

在SQL Server上迭代游标时如何知道最后一行?

我尝试使用计数器和@@CURSOR_ROWS以及@@FETCH_STATUS,但它不能很好地工作,或者我没有以正确的方式使用它们。

编辑:

嗯,是的,在每个循环结束时用逗号... ,组成字符串。当然,在返回之前我可以切断最后一个字符,,但我想知道这是唯一的方法吗?

但是,有很多情况,知道如何识别最后一行可能会很好。

2 个答案:

答案 0 :(得分:4)

正如评论中所建议的那样,通过为第一行行而不是最后一行做一些特别的事情,可以更容易地实现元素之间的逗号。 1,2 < / p>

而不是

WHILE @@FETCH_STATUS=0
BEGIN
    SET @value = @value + @newelement + ','

    ...
END

试图弄清楚如何特别对待最后一行,这样做容易得多:

SET @first = 1
WHILE @@FETCH_STATUS=0
BEGIN
    IF @first = 1
        SET @first = 0
    ELSE
        SET @value = @value + ','

    SET @value = @value + @newelement

    ...
END

另一种转换,如果确实确实需要为最后一行做某事,那就是使用中间变量和非标准游标循环:

declare boris cursor for select top 10 name from sys.objects order by name

declare @name sysname
declare @nametemp sysname

open boris
fetch next from boris into @nametemp
while @@FETCH_STATUS=0
BEGIN
    set @name = @nametemp --Use SELECT if multiple variables to be assigned

    fetch next from boris into @nametemp

    if @@FETCH_STATUS!=0
    begin
        print 'and finally'
    end

    print @name
END

close boris
deallocate boris

哪些打印(对我来说,几乎是空的DB):

EventNotificationErrorsQueue
filestream_tombstone_2073058421
filetable_updates_2105058535
IsIt
QueryNotificationErrorsQueue
queue_messages_1977058079
queue_messages_2009058193
queue_messages_2041058307
ServiceBrokerQueue
and finally
sysallocunits

但我强烈推荐第一种转型。

1 这不仅仅是一个T-SQL的东西。在大多数编程语言中,如果您可以将问题从“以不同方式处理最后一次迭代”转换为“以不同方式处理第一次迭代”,那么通常会容易得多。

2 当然,插入通常的警告,关于游标是SQL中的最后手段,使用基于集合的方法,除非或直到它们被证明是不合适的。

答案 1 :(得分:0)

您还可以在FETCH之后使用条件:

DECLARE @sqlStatement nvarchar(max) = '(';
DECLARE @column_name nvarchar(255);
DECLARE colums CURSOR FOR 
SELECT TOP 10 name FROM sys.all_columns 
OPEN colums
FETCH NEXT FROM colums INTO @column_name
WHILE @@FETCH_STATUS = 0
BEGIN 
    SET @sqlStatement = @sqlStatement 
                      + QUOTENAME(@column_name)                   
    FETCH NEXT FROM colums INTO @column_name
    SET @sqlStatement = @sqlStatement + CASE WHEN @@FETCH_STATUS != -1 THEN ',' ELSE ')' END 
                      + char(13)
END
CLOSE colums
DEALLOCATE colums
print @sqlStatement