Курсоры
Разрешение обновления
Возможны случаи, когда необходимо обновить либо удалить строки таблицы, выбираемые с помощью курсора. В других случаях требуется гарантированно исключить такое обновление или удаление. SQL предоставляет возможность осуществлять контроль с помощью предложения разрешения обновления в операторе DECLARE CURSOR. Чтобы запретить обновление и удаление в области действия курсора, используйте оператор:
FOR READ ONLY
Для разрешения обновления избранных столбцов, при том, что остальные столбцы должны быть защищены, используйте:
FOR UPDATE OF имя_столбца [, имя_столбца]…
Помни:
Естественно, столбцы, внесенные в приведенный список, должны присутствовать в выражении запроса оператора DECLARE CURSOR. Если предложение разрешения (или запрета) обновления отсутствует, по умолчанию данные всех столбцов, указанных в выражении запроса, могут быть обновлены. В этом случае оператор UPDATE может обновить все столбцы строки области действия курсора, а оператор DELETE может удалить такую строку.
Чувствительность
Выражение запроса в операторе DECLARE CURSOR определяет строки, которые находятся в области действия курсора. Возникает вопрос: что если программный код, расположенный между операторами OPEN и CLOSE, изменяет содержимое некоторых строк так, что они перестают удовлетворять условиям запроса? А если некоторые строки вообще удалены? Продолжает ли команда курсора обрабатывать все строки, которые изначально соответствовали условиям запроса, или же изменяет свое поведение в зависимости от изменений, а может, вообще игнорирует измененные или удаленные строки?
Помни:
До окончания построчной обработки в результате запроса DECLARE CURSOR данные могут находиться в полном беспорядке. Такие данные недостоверны и противоречивы. Потому рекомендуется сделать курсор нечувствительным к любым изменениям. Для этого в оператор DECLARE CURSOR нужно добавить ключевое слово INSENSITIVE. В течение времени, когда курсор остается открытым, он нечувствителен к изменениям таблицы, так что область действия курсора распространяется на строки, соответствующие исходным условиям выражения запроса. Курсор не может быть нечувствительным и обновляемым в одно и то же время. Нечувствительный курсор должен быть открыт только для чтения.
Обычные операторы SQL, такие как UPDATE, INSERT или DELETE, работают с набором строк таблицы базы данных, а возможно, со всеми строками таблицы. Во время работы механизм транзакций SQL защищает ее от вмешательства других команд, работающих одновременно с теми же данными. При использовании же курсора данные более уязвимы. В течение всего времени, пока курсор открыт, данные могут быть изменены другими командами. Если открывается один курсор и начинается обработка таблицы, затем открывается другой курсор, а первый курсор остается активным, действия, производимые вторым курсором, могут повлиять на данные, используемые командой первого курсора. Предположим, составлены следующие запросы:
DECLARE Cl CURSOR FOR SELECT * FROM EMPLOYEE ORDER BY Salary; DECLARE C2 CURSOR FOR SELECT * FROM EMPLOYEE FOR UPDATE OF Salary;
Теперь предположим, что оба курсора открыты и командой курсора С1 последовательно выбрано несколько строк, а в это время данные по зарплате обновлены с помощью С2. При этом может так получиться, что строка, уже выбранная С1, может опять появиться при последующей выборке.
Проблемы:
Проблемы, возникающие в результате взаимодействий нескольких одновременно открытых курсоров или обыкновенных команд SQL и открытых курсоров, можно избежать только путем локализации транзакций. В противном случае можно нарваться на крупные неприятности. Хорошенько запомните: нельзя работать со множеством открытых курсоров.
По умолчанию чувствительность курсора находится в состоянии ASENSITIVE. Значение ASENSITIVE зависит от реализации SQL. В одной реализации оно может быть эквивалентно SENSITIVE, а в другой – INSENSITIVE. Для того чтобы выбрать, какое значение использовать в вашей реализации, прочитайте техническую документацию к вашей системе.