|
Программирование >> Программирование баз данных
SET IDENTITY INSERT CursorTable ON -- Объявление курсора DECLARE CursorTest CURSOR GLOBAL -- Параметр, позволяющий манипулировать курсором из -- кода, находящегося за пределами данного пакета SCROLL -- Параметр, позволяющий выполнять прокрутку назад и -- проверять результаты внесения изменений DYNAMIC -- Параметр, проверяемый на этот раз SELECT SalesOrderlD, CustomerlD FROM CursorTable -- Объявления двух вспомогательных переменных DECLARE ©SalesOrderlD int DECLARE ©CustomerlD varchar(5) -- Открытие курсора и получение первой строки OPEN CursorTest FETCH NEXT FROM CursorTest INTO ©SalesOrderlD, ©CustomerlD -- Обработка данных в цикле WHILE ©©FETCH STATUS = О BEGIN PRINT CAST(©SalesOrderlD AS varchar) + + ©CustomerlD FETCH NEXT FROM CursorTest INTO ©SalesOrderlD, ©CustomerlD -- Внесение изменения. Будет показано, что на этот раз изменение повлияет на -- работу курсора UPDATE CursorTable SET CustomerlD = -111 WHERE SalesOrderlD = 43663 -- Удаление строки для ознакомления с тем, как осуществляется эта операция DELETE CursorTable WHERE SalesOrderlD = 43664 -- Вставка строки. Далее будет показано, что эта строка не обнаруживается в -- курсоре INSERT INTO CursorTable (SalesOrderlD, CustomerlD) VALUES (-99999, -99999) -- Проверка таблицы для определения того, что в ней действительно отражены -- внесенные изменения SELECT SalesOrderlD, CustomerlD FROM CursorTable -- Переход в начало набора данных. Это возможно, поскольку курсор является -- прокручиваемым FETCH FIRST FROM CursorTest INTO ©SalesOrderlD, ©CustomerlD /* Повторная обработка в цикле. На этот раз следует учитывать, что проверяемые ** данные изменились. Не исключена возможность того, что некоторые строки ** отсутствуют (удалены), поэтому не будут обнаружены при обработке данных в ** курсоре; таким образом, должна быть предусмотрена немного более сложная ** проверка состояния курсора */ WHILE ©©FETCH STATUS != -1 BEGIN IF ©©FETCH STATUS = -2 BEGIN PRINT MISSING! It probably was deleted. ELSE BEGIN PRINT CAST (©SalesOrderlD AS varchar) + + CAST (©CustomerlD AS varchar) FETCH NEXT FROM CursorTest INTO ©SalesOrderlD, ©CustomerlD -- Удаление ненужных объектов CLOSE CursorTest DEALLOCATE CursorTest DROP TABLE CursorTable При выполнении этого сценария формируются следующие результаты: (5 row(s) affected) 43661 442 43662 227 43663 510 43664 397 43665 146 (1 row(s) affected) (1 row(s) affected) (1 row(s) affected) SalesOrderlD CustomerlD -99999 -99999 43661 442 43662 227 43663 -111 43665 146 (5 row(s) affected) -99999 * 43661 442 43662 227 43663 -111 43665 146 Первые два набора записей выглядят точно так же, как и в прошлый раз. Изменения обнаруживаются после перехода к анализу третьего (и последнего) результирующего набора, как описано ниже. Отсутствуют какие-либо указания на то, что выборка окончилась неудачей, несмотря на то, что удалена одна строка (не формируется то же извещение, что и перед этим). В обновленной строке показаны результаты обновления (так же, как и при использовании ключевого курсора). В наборе данных курсора теперь обнаруживается вставленная строка. Динамические курсоры наиболее чувствительны к изменениям в данных по сравнению со всеми прочими курсорами. Наборы данных динамических курсоров затрагиваются всеми изменениями, внесенными в основополагающие данные. Недостатки динамических курсоров заключаются в том, что при их использовании могут обнаруживаться некоторые дополнительные проблемы распараллеливания работы, к тому же эти курсоры создают значительную нагрузку на систему при работе с крупными наборами данных. С формальной точки зрения динамические курсоры, в отличие от ключевых курсоров, могут применяться для работы с неуникальным индексом. Но такой организации работы следует избегать в любом случае (по мнению автора, этому должна препятствовать сама СУБД SQL Server и при попытке создания динамического курсора на таблице с неуникальным индексом активизировать ошибку). При определенных обстоятельствах применение неуникального индекса вполне может привести к созданию бесконечного цикла, поскольку при этом динамический курсор утрачивает способность следить за тем, где находится текущая строка в наборе данных курсора. Единственный безотказный способ предотвращения такой ситуации состоит в том, что следует избегать использования динамических курсоров или применять их для работы только с таблицами, имеющими действительно уникальный индекс. Курсоры FASTFORWARD Курсоры FAST FORWARD по определению представляют собой быстродействующие однонаправленные курсоры (в данном случае оценка быстродействия выполняется по отношению к курсорам других типов, поскольку, вообще говоря, производительность курсоров является крайне низкой по сравнению с обычными запросами). Кроме того, для обозначения курсоров FAST FORWARD часто применяют термин firehose-курсоры, которым условно именуются все однонаправленные курсоры. Автор часто приводит аналогию, позволяющую пояснить, почему такие курсоры называют однонаправленными. Дело в том, что после получения с их помощью данньгх отсутствует возможность вернуть откорректированные данные в таблицу с помощью таких же курсоров. Иначе говоря, курсор передает данные только в одном направлении. Особенность курсоров FAST FORWARD состоит в том, что после открытия курсора не допускается выполнение никаких действий, кроме получения данных, продвижения вперед и освобождения курсора (отметим, что в перечень допустимых действий не входит закрьггие курсора). Итак, на основе приведенного описания можно смело утверждать, что курсоры FAST FORWARD не совсем подходят под определение понятия курсора. В частности, курсоры этого типа в нескольких различных обстоятельствах автоматически преобразуются в курсоры других типов, но, по мнению автора, их скорее можно сравнить с ключевыми курсорами в том смысле, что относящийся к ним набор данных не изменяется; после того как содержимое курсора определяется при его создании, не происходит добавление каких-либо новых строк. Строки, удаленные после открытия курсора, обнаруживаются как недостающие (при попытке выборки таких строк системная переменная @@FETCH STATUS принимает значение -2). Но следует учитывать, что если курсор FAST FORWARD преобразуется в курсор какого-то другого типа (в результате автоматического преобразования), то он начинает функционировать полностью как курсор этого нового типа. С таким автоматическим преобразованием связана возможность возникновения ошибок, поскольку СУБД SQL Server не сообщает о том, что произошло преобразование, если в объявлении курсора не предусмотрена опция TYPE WARNING.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |