2013-06-26 2 views
12

Как в теме. Могу ли я просто сбросить позицию курсора в начало в 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 
+1

См ссылки ниже: http://stackoverflow.com/questions/2909357/start-position-for-a-reused-t -sql-cursor – bgs

ответ

21

вам нужно объявить курсор как свиток, как этот

declare c scroll cursor for (select statement); 

затем в любое время для определения местоположения на первый раз с помощью следующей

fetch first from c; 
+0

для предотвращения изменений (обновление/удаление) вы бы указали курсор READ_ONLY сразу после прокрутки –

+0

Также вам нужно объявить свой курсор как 'DECLARE @CursorX SCROLL CURSOR SELECT ...' или 'SET @CursorX = CURSOR SCROLL FOR SELECT .... ' –

1

Данные, полученные курсором, не будут изменены.

STATIC

Определяет курсор, который делает временную копию данных, которые будут использоваться курсором. Все запросы к курсору отвечают из этой временной таблицы в tempdb; поэтому изменения, внесенные в базовые таблицы, не отражаются в данных, возвращаемых выборками, сделанными для этого курсора, и этот курсор не допускает модификаций.

9

Другой вариант, который может быть использован, не заставит вас изменить тип курсора просто close курсор и повторно open это:

CLOSE user_cursor 
OPEN user_cursor 

Но scroll option будет дешевле с точки зрения использование ресурсов, если это изменение, которое вы можете принять.

+0

Знаете ли вы, какой метод быстрее? –

+1

@OskarSzura - как я уже сказал, свиток должен быть дешевле (в тот момент, когда вы выдаете 'fetch first'). С другой стороны, это может быть дороже во время первоначального 'open'. Но единственный способ узнать, как это сделать, - это попробовать: * ваши * данные, * ваши * индексы, * ваше * оборудование и т. Д. –

+0

хорошо, спасибо за подсказку. –

-2

Используйте петлю курсора и его позаботились за вас ...

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; 
+0

Это не работает, вы можете объяснить? –

+0

Он работает для меня с Oracle 11g – WebWeasel

+0

Вопрос SQL Server/Sybase TSQL, а не Oracle, не так ли? –

Смежные вопросы