Удалить строку из источника курсора SQL Server

У меня есть курсор SQL Server 2005, работающий с табличной переменной с именем @workingSet.

Иногда строки могут быть связаны, и в этом случае я одновременно обрабатываю полученную строку и связанные строки. Затем я удаляю связанные записи из @workingset, так как мне не нужно обрабатывать их в цикле.

В @workingSet с 7 строками первые две связаны, поэтому, когда я обрабатываю 1, я также обрабатываю 2. Я удаляю строку 2 из источника курсора (@workingSet), а затем извлекаю следующую. Проблема в том, что он возвращает вторую строку в @workingset (тот, который я удалил на предыдущей итерации).

У меня сложилось впечатление, что это можно сделать, т.е. удалить элемент из источника, с которым работает курсор, и он будет учитывать удаление при последующих выборках.


person Simon Rigby    schedule 05.10.2011    source источник
comment
Можете ли вы показать нам, что вы делаете ?? лучшим вариантом было бы полное удаление курсора, что возможно как минимум в 90% всех случаев...   -  person marc_s    schedule 05.10.2011
comment
Спасибо, и да, вы правы ... и я все еще не уверен, что курсор нужен, но меня больше интересовало, что это возможно.   -  person Simon Rigby    schedule 06.10.2011


Ответы (2)


Похоже, что ответ заключается в том, что табличная переменная, используемая в качестве источника курсора, должна иметь первичный ключ. Я добавил это, и все работает правильно.

person Simon Rigby    schedule 06.10.2011
comment
Таблица в моем ответе не имеет ПК и правильно отражает результаты DELETE. - person Martin Smith; 06.10.2011
comment
Привет .. да, я смог провести проверку концепции без ПК, и это сработало правильно. Я не знаю, почему в другом случае это требуется. - person Simon Rigby; 06.10.2011
comment
У вас были установлены другие параметры курсора? - person Martin Smith; 06.10.2011
comment
Привет Мартин .. нет .. без параметров курсора .. по умолчанию все пути. Я не уверен, что это ответ, поэтому я не отметил его. - person Simon Rigby; 26.10.2011
comment
Кажется, я нашел объяснение. Вам нужен динамический курсор, чтобы изменения в исходной таблице отражались в выборке курсора. Вы получали неявное преобразование в курсор keyset или static. Возможно, поскольку вы упорядочивали по неиндексированному столбцу. Есть ли в вашем запросе ORDER BY в столбце PK? Я получаю такое же поведение в запросе в своем ответе, если добавляю ORDER BY C к SELECT - person Martin Smith; 30.10.2011

Не очень хорошо знаком с курсорами, но из быстрого теста в этом конце вам нужно избегать объявления курсора с параметрами STATIC или KEYSET, тогда изменения в базовой таблице отражаются в курсоре.

SET NOCOUNT ON;

DECLARE @WorkingTable TABLE(C int)

INSERT INTO @WorkingTable VALUES (1),(2),(3)

DECLARE @C int

DECLARE wt_cursor CURSOR 
DYNAMIC /*Or left blank but not STATIC or KEYSET*/
FOR 
SELECT C
FROM @WorkingTable

OPEN wt_cursor;

FETCH NEXT FROM wt_cursor 
INTO @C

DELETE FROM @WorkingTable

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @C;


    FETCH NEXT FROM wt_cursor 
    INTO @C;
END
CLOSE wt_cursor;
DEALLOCATE wt_cursor;
person Martin Smith    schedule 05.10.2011
comment
Спасибо .. да, курсор не был объявлен с помощью STATIC или KEYSET. - person Simon Rigby; 06.10.2011
comment
@Simon - Что вы получаете, когда запускаете код в моем ответе, но удаляете опцию DYNAMIC? Для меня он просто возвращает 1, а не 1,2,3 - person Martin Smith; 06.10.2011