【问题标题】:Can I reset cursor's position to the beginning?我可以将光标的位置重置到开头吗?
【发布时间】:2013-06-26 10:34:36
【问题描述】:

如主题。我可以简单地将光标的位置重置为 Transact-SQL 中的开头,以便它可以在表上再次运行吗?我想在以下情况下重置它:

DECLARE @userID INT
DECLARE user_cursor CURSOR FOR SELECT userID FROM users

WHILE /* some condition */
BEGIN
...

    FETCH NEXT FROM user_cursor INTO @userID

    IF @@FETCH_STATUS = 0
    BEGIN
        /*... here goes the reset of the cursor ...*/
    END

...
END

【问题讨论】:

标签: sql-server tsql database-cursor


【解决方案1】:

你需要将你的光标声明为滚动,像这样

declare c scroll cursor for (select statement); 

然后在任何时候定位到第一个只需使用以下

fetch first from c;

【讨论】:

  • 为了防止更改(更新/删除),您将在滚动后声明游标 READ_ONLY
  • 还需要将光标声明为DECLARE @CursorX SCROLL CURSOR SELECT ...SET @CursorX = CURSOR SCROLL FOR SELECT ....
【解决方案2】:

另一个不会强迫你改变光标类型的选项是close光标然后重新open它:

CLOSE user_cursor
OPEN user_cursor

但是scroll option 在资源使用方面会更便宜,如果这是您可以接受的更改。

【讨论】:

  • 你知道哪种方法更快吗?
  • @OskarSzura - 正如我所说,卷轴应该更便宜(在您发出fetch first 时)。另一方面,在最初的open 期间可能会更贵。但真正了解的唯一方法是尝试使用 your 数据、your 索引、your 硬件等。
【解决方案3】:

游标检索到的数据不会改变。

静态

定义一个游标,该游标制作数据的临时副本以供游标使用。对游标的所有请求都是从 tempdb 中的这个临时表中回答的;因此,对基表所做的修改不会反映在对该游标进行的提取返回的数据中,并且该游标不允许修改。

【讨论】:

    【解决方案4】:

    使用游标循环并为您处理...

    cursor c_something IS
       select * from somewhere
    
    BEGIN
    
        for some_row in c_something LOOP
            -- do stuff with some_row.COLUMN;
        END LOOP; -- this closes the cursor for you when it has gone all the way through
    
        -- do other stuff
    
        for some_row in c_something LOOP -- opens the cursor again from the top
            -- do stuff with some_row.COLUMN;
        END LOOP;
    
    END;
    

    【讨论】:

    • 问题是 SQL Server/Sybase TSQL 不是 Oracle,对吧?
    猜你喜欢
    • 2022-11-20
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 2011-12-04
    相关资源
    最近更新 更多