Типы данных UROWID и ROWID в PL/SQL

Doc

Doc

АйТишник со стажем... Профиль автора.

UROWID и ROWID в PL/SQL OracleТипы данных UROWID и ROWID предназначены для работы с идентификаторами строк базы данных. ROWID — идентификатор строки (ROW IDentifier), а точнее, двоичное значение, однозначно идентифицирующее строку данных в таблице Oracle, даже если таблица не имеет уникального ключа. Две записи, даже если они содержат одинаковые значения столбцов, обладают разными идентификаторами ROWID или UROWID.

Учтите, что значения ROWID в таблицах могут изменяться. В ранних версиях Oracle (Oracle8 и ранее) значения ROWIDs оставались неизменными на протяжении жизненного цикла строки. Но в версии Oracle8i были добавлены новые возможности, нарушающие это старое правило. Если для обычной или индексной таблицы разрешено перемещение строк, обновление может привести к изменению ROWID или UROWID строки. Кроме того, если с таблицей будет выполнена операция, из-за которой строка перейдет из одного физического блока данных в другой блок, значение ROWID строки изменится.

Впрочем, даже с учетом этого предупреждения значения ROWID приносят практическую пользу. Включение значений ROWID в командах SELECT, UPDATE, MERGE и DELETE в некоторых случаях повышает скорость обработки, поскольку обращение к строке по ее идентификатору выполняется быстрее, чем по первичному ключу. На рис. 1 использование ROWID в команде UPDATE сравнивается с использованием значений столбцов (например, первичного ключа).

Идентификатор ROWID ссылается непосредственно на строку таблицы

Рис. 1. Идентификатор ROWID ссылается непосредственно на строку таблицы

Исторически тип ROWID появился раньше типа UROWID. По мере добавления новых функциональных возможностей, таких как использование индекс-таблиц и шлюзов к другим базам данных, компания Oracle, естественно, разрабатывала и новые типы идентификаторов строк, и новые типы данных для их хранения. Так появился тип данных UROWID, используемый для хранения идентификаторов строк таблиц любого типа. Буква U в его названии означает «Universal» (универсальный), а переменная UROWID может содержать любое значение ROWID из любого типа таблиц.

Тип данных UROWID рекомендуется использовать во всех новых программах, работающих с идентификаторами строк. Тип ROWID обеспечивает обратную совместимость, но он не поддерживает все типы идентификаторов строк, использующихся в современных базах данных Oracle. Тип UROWID надежнее — он поддерживает все типы ROWID, сохраняя все преимущества ускоренного доступа.

 

Получение идентификаторов строк

Чтобы получить ROWID для строки таблицы, добавьте ключевое слово в список выборки.

Пример:

DECLARE
   employee_rowid UROWID;
   employee_salary NUMBER;
BEGIN
   -- Выборка информации, которую мы собираемся модифицировать
   SELECT rowid, salary INTO employee_rowid, employee_salary
   FROM employees
   WHERE last_name='Grubbs' AND first_name='John';
END; 

В терминологии Oracle ROWID называется «псевдостолбцом», потому что на самом деле столбца с именем ROWID в таблице не существует. Значение ROWID ближе к указателю — оно содержит физический адрес строки в таблице.

Использование идентификаторов строк

Преимущества использования ROWID проявляются при повторном обращении к строке, если оно производится часто или сопряжено со значительными затратами ресурсов. Вспомните пример из предыдущего раздела, когда мы извлекали из базы данных информацию об окладе работника. Допустим, нам потребовалось изменить величину оклада и ввести в базу данных новое значение. Конечно, для этого можно написать команду UPDATE с тем же условием WHERE, которое использовалось в команде SELECT:

DECLARE
   employee_rowid UROWID;
   employee_salary NUMBER;
BEGIN
   -- Выборка информации, которую мы собираемся модифицировать
   SELECT rowid, salary INTO employee_rowid, employee_salary
   FROM employees
   WHERE last_name='Grubbs' AND first_name='John';
   /* Вычисление нового оклада */
   UPDATE employees
   SET salary = employee_salary
   WHERE last_name='Grubbs' AND first_name='John';
END;

Конечно, этот код работает, но у него есть недостаток: необходимость повторения для UPDATE пути доступа, который уже использовался для SELECT. Скорее всего, поиск нужной записи потребовал обращения к одному-двум индексам. Но ведь программа уже обращалась к этим индексам для команды SELECT, так зачем выполнять всю работу дважды? Обращение к индексу производилось для получения ROWID с целью прямого обращения к записи. Включая значение ROWID в команду SELECT, я могу просто передать его команде UPDATE и обойтись без лишнего поиска по индексу:

DECLARE
   employee_rowid UROWID;
   employee_salary NUMBER;
BEGIN
   -- Выборка информации, которую мы собираемся модифицировать
   SELECT rowid, salary INTO employee_rowid, employee_salary
   FROM employees
   WHERE last_name='Grubbs' AND first_name='John';
   /* Вычисление нового оклада */
   UPDATE employees
   SET salary = employee_salary
   WHERE rowid = employee_rowid;
END;

Вспомните предупреждение о возможном изменении ROWID. Если в многопользовательской системе ROWID строки изменятся между командами SELECT и UPDATE, то код не будет работать так, как задумано. Почему? Потому что при разрешенном перемещении строк в стандартной таблице ROWID этой строки таблицы может измениться. А перемещение строк может быть разрешено потому, что администратор базы данных желает провести оперативную реорганизацию таблицы, или таблица может быть разбита на блоки, и перемещение строки позволит записи переместиться из одного блока в другой в процессе обновления.

Иногда для достижения аналогичного результата проще всего воспользоваться для выборки данных явным курсором, с последующей модификацией или удалением с применением конструкции WHERE CURRENT OF CURSOR.

Конечно, использование ROWID ускоряет работу программ PL/SQL, потому что вы по сути опускаетесь на физический уровень управления базой данных. Однако хорошие приложения обычно не зависят от физической структуры данных. Они поручают управление физической структурой базе данных и административным программам, а сами ограничиваются логическим управлением данными. По этой причине использовать ROWID в приложениях обычно не рекомендуется.

Вас заинтересует / Intresting for you:

Управление приложениями PL/SQL...
Управление приложениями PL/SQL... 4634 просмотров Stas Belkov Thu, 16 Jul 2020, 06:20:48
Встроенные методы коллекций PL...
Встроенные методы коллекций PL... 14739 просмотров sepia Tue, 29 Oct 2019, 09:54:01
Тип данных RAW в PL/SQL
Тип данных RAW в PL/SQL 12239 просмотров Doctor Thu, 12 Jul 2018, 08:41:33
Символьные функции и аргументы...
Символьные функции и аргументы... 18546 просмотров Анатолий Wed, 23 May 2018, 18:54:01
Войдите чтобы комментировать