DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

Использование оператора COMMIT при считывании строк

Обратите внимание, что в предыдущем примере оператор COMMIT вы­полняется после окончания цикла выборки. Дело в том, что этот опера­тор снимает все блокировки, удерживаемые сеансом. Конструкция FOR UPDATE устанавливает блокировки, а оператор COMMIT их снимает.
Когда это происходит, действие курсора прекращается и любая последу­ющая попытка считать строки приводит к ошибке Oracle:
Таким образом, если оператор COMMIT расположен внутри цикла вы­борки SELECT...FOR UPDATE, считывание строк после COMMIT будет завершаться ошибкой. Поэтому не рекомендуется размещать COMMIT внутри цикла. Если курсор не определен как SELECT...FOR UPDATE, ни­каких проблем не возникает.
Совет
Даже если не используется SELECT...FOR UPDATE, применение оператора COMMIT внутри цикла выборки нежелательно. Например, если запрос воздействует на большое число строк, то можно получить ошибку "ORA-1555snapshot too old" (мгновенный снимок слишком старый).
Как поступить, если требуется обновить строку, только что считанную из курсора, и при этом применить оператор COMMIT внутри цикла? Кон­струкцией WHERE CURRENT OF воспользоваться нельзя, так как курсор не может быть определен как FOR UPDATE. В этом случае можно исполь­зовать первичный ключ таблицы в условии WHERE оператора UPDATE,
как показано в следующем примере:

В этом примере, по существу, имитируется конструкция WHERE CURRENT OF, однако строки активного набора не блокируются. Как следствие, этот блок может выполняться не так, как требуется, если дру­гие сеансы будут параллельно обращаться к данным.
Совет
Если используемая в запросе таблица не имеет первичного ключа, вместо него можно применить псевдостолбец ROWID. Можно извлечь ROWID каждого столбца в переменную PL/SQL (типа ROWID или UROWID) и использовать его в предложении WHERE в виде WHERE rowid =  v_RowID.
 









jAntivirus