|
Sybase
|
|
|
|
|
Продукты
|
|
|
|
|
Сообщества
|
|
|
|
|
Меню
|
|
|
|
|
Вход
|
|
|
|
|
Рассылка
|
|
|
|
|
Статистика
|
|
|
|
|
Как правильно работать с курсорами на TSQL
|
Как правильно работать с курсорами на TSQLШаблон кода для работы с курсором
declare <cursor name> cursor for
select
from ...
for read only/for update
open <cursor name>
declare @error int
select @error = 0
declare ... -- переменные для строки курсора
while 1=1
begin
fetch <cursor name> into ...
if @@sqlstatus = 2 break
if @@sqlstatus = 1
begin
select @error = 1
raiserror 20000 'Ошибка при работе с курсором <cursor name>'
break
end
-- обработка строки
-- пример обработки ошибки
if @@error <> 0 or @@rowcount <> 1
begin
select @error = 1
raiserror 20000 'Ошибка ...'
break
end
end
close <cursor name>
deallocate cursor <cursor name>
if @error <> 0
-- обработка ошибки
Кроме этого, надо помнить о особенностях курсоров в ASE
- Курсоры в ASE работают "только вперед".
- declare только определяет структуру курсора, но не выбирает данные.
- declare должен быт отдельным батчем (batch) если код не находится внутри процедуры или триггера (после оператора declare должен стоять GO)
- open начинает реально выбирать данные. Открывать курсор можно
много раз, предварительно естественно закрыв его с помощью close.
- Значения переменных, находящихся внутри запроса, "используются" в тот момент, когда выполняется команда open.
- Курсоры всегда чувствительны к изменениям данных во время их работы. Т.е. если курсор открыт, и кто-то другой меняет данные, которые должны выбираться курсором, эти изменения будут "видны" для этого курсора.
Эти изменения данных могут приводить к тому, что курсор будет закрыт, и надо быть к этому готовым.
Так, например, типичная ситуация - удаление текущей записи курсора приводит к ошибке курсора. Но все же есть способы обходить это (см. ниже).
Как модифицировать или удалять текущую запись.
- Cделать курсор for update. При этом надо добиться того, чтобы запрос удовлетворял
определенным требованиям (см. описание команды declare cursor), а это можно сделать не всегда.
- Сделать курсор нечувствительным.
- Держать два набора переменных для записи курсора - текущую и предыдущую и модифицировать предыдущую запись. Это требует добавления кода модификации последней записи после закрытия цикла обработки курсора.
Как сделать курсор нечувствительным к изменениям.
Принцип - заставить ASE сделать временную таблицу для набора данных, обрабатываемого курсором. Надо помнить, что гарантированно этого сделать нельзя практически никогда, и поэтому важно тщательно тестировать код, особенно при изменениях конфиругации сервера и схемы данных.
Способы:
- фиктивный DISTINCT
- фиктивный GROUP BY
- ORDER BY, не покрываемый индексом (довольно труднопроверяемый способ).
Также можно прочитать раздел документации, описывающий случаи, когда курсоры не являются updateable, т.е. являются "только для чтения". Если вы напишите курсор так, что он не будет updateable, то почти наверняка он будет и нечувствительным.
Побочные эффекты - практически всегда курсор будет неизменяемым (read only).
|
Дата публикации: Wednesday 29 March 2006 12:49:36 Материал прочитан: 12711 раз(а) [ Назад ] |
|
|
|
|
|
|
Copyright©2005 . Все права защищены.
|